import QtQuick import QtQuick.Controls import QtQuick.Layouts import ISC // ===== Home Workspace Shell ===== Rectangle { id: root anchors.fill: parent color: Theme.pageBackground clip: true border.color: Theme.outerFrameBorder border.width: Theme.borderStrong // ===== Navigation Model ===== // Primary navigation shown in the left rail. property var sideActions: ["DETECT WAFER", "READ MEMORY", "OPEN CSV IN EXCEL", "ERASE MEMORY", "IMPORT DATA", "STORED DATA"] // ===== Footer Tab Model ===== // Footer tabs drive the active workspace section. property var bottomTabs: ["Status", "Graph", "Data", "Wafer Map", "Compare", "Split", "Settings", "About"] // ===== View State ===== property int selectedTabIndex: 0 property int selectedSideActionIndex: -1 // nothing active on startup // ===== Main Two-Column Layout ===== RowLayout { anchors.fill: parent spacing: 0 // ===== Left Action Rail ===== // Left control rail. Rectangle { id: sideRail Layout.preferredWidth: Theme.sideRailWidth Layout.fillHeight: true color: Theme.sideRailBackground border.color: Theme.workspaceBorder border.width: Theme.borderThin readonly property int actionCount: root.sideActions.length readonly property real computedButtonHeight: Math.min(Theme.sideButtonHeight, (height - (Theme.panelPadding * 2) - (Theme.sideRailSpacing * Math.max(0, actionCount - 1))) / Math.max(1, actionCount)) ColumnLayout { anchors.fill: parent anchors.margins: Theme.panelPadding spacing: Theme.sideRailSpacing Repeater { model: root.sideActions Button { id: control text: modelData property bool isActive: index === root.selectedSideActionIndex Layout.fillWidth: true Layout.preferredHeight: Math.max(Theme.sideButtonMinHeight, sideRail.computedButtonHeight) hoverEnabled: true onClicked: { root.selectedSideActionIndex = index root.selectedTabIndex = 0 // always jump to Status tab if (index === 0) deviceController.detectWafer() else if (index === 1) deviceController.readMemoryAsync() else if (index === 2) deviceController.openCsvFile() } background: Rectangle { color: { if (control.down) { return Theme.buttonPressed; } if (control.isActive) { return Theme.sideActiveBackground; } return "transparent"; } border.color: control.isActive ? Theme.cardBorder : "transparent" border.width: 1 radius: Theme.radiusSm Rectangle { anchors.left: parent.left anchors.top: parent.top anchors.bottom: parent.bottom width: 3 visible: control.isActive color: Theme.primaryAccent radius: Theme.radiusXs } } contentItem: Text { text: control.text color: control.isActive ? Theme.headingColor : Theme.bodyColor font.bold: control.isActive font.pixelSize: 18 wrapMode: Text.WordWrap horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } } } } // Main workspace and footer navigation. Rectangle { Layout.fillWidth: true Layout.fillHeight: true color: Theme.workspaceBackground border.color: Theme.workspaceBorder border.width: Theme.borderThin ColumnLayout { anchors.fill: parent anchors.margins: Theme.mainAreaPadding spacing: Theme.rightPaneGap // ===== Active Tab Content Area ===== Rectangle { Layout.fillWidth: true Layout.fillHeight: true Layout.minimumHeight: 220 color: Theme.responseBackground border.color: Theme.responseBorder border.width: 1 radius: Theme.radiusMd StackLayout { anchors.fill: parent currentIndex: root.selectedTabIndex // ===== Tab Content Routing ===== Repeater { model: root.bottomTabs Item { property string tabName: modelData Loader { anchors.fill: parent active: parent.tabName === "Settings" source: parent.tabName === "Settings" ? "Tabs/SettingsTab.qml" : "" } Loader { anchors.fill: parent active: parent.tabName === "Status" source: parent.tabName === "Status" ? "Tabs/StatusTab.qml" : "" } Loader { anchors.fill: parent active: parent.tabName === "Data" source: parent.tabName === "Data" ? "Tabs/DataTab.qml" : "" } Label { anchors.centerIn: parent visible: parent.tabName !== "Settings" && parent.tabName !== "Status" && parent.tabName !== "Data" text: parent.tabName + " content" color: Theme.bodyColor font.pixelSize: 20 } } } } } // Keep the tab strip evenly distributed across the footer. // ===== Footer Tab Strip ===== Rectangle { Layout.fillWidth: true Layout.preferredHeight: Theme.tabBarHeight + (Theme.tabBarPadding * 2) color: Theme.tabBarBackground border.color: Theme.workspaceBorder border.width: Theme.borderThin RowLayout { anchors.fill: parent anchors.margins: Theme.tabBarPadding spacing: Theme.tabSpacing Repeater { model: root.bottomTabs Button { id: botTabBtn property bool isActive: index === root.selectedTabIndex text: modelData Layout.fillWidth: true Layout.preferredHeight: Theme.tabBarHeight Layout.minimumWidth: Theme.tabButtonMinWidth onClicked: root.selectedTabIndex = index hoverEnabled: true background: Rectangle { color: botTabBtn.isActive ? Theme.tabActiveBackground : (botTabBtn.hovered ? Theme.tabHoverBackground : Theme.tabBackground) border.color: Theme.tabBorder border.width: 1 radius: Theme.tabRadius } contentItem: Text { text: botTabBtn.text color: botTabBtn.isActive ? Theme.tabActiveText : Theme.tabText font.pixelSize: Theme.tabFontSize font.bold: botTabBtn.isActive horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } } } } } } } } }