| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- import QtQuick 2.15
- import QtQuick.Controls 2.15
- import QtQuick.Layouts 1.15
- import QtQuick.Dialogs
- import QtQuick.VirtualKeyboard 2.15
- import DuneWeaver 1.0
- import "components"
- import "components" as Components
- ApplicationWindow {
- id: window
- visible: true
- width: 800
- height: 480
- title: "Dune Weaver Touch"
- // Solid background color for ApplicationWindow
- color: Components.ThemeManager.backgroundColor
- property int currentPageIndex: 0
- property alias stackView: stackView
- property alias backend: backend
- property bool shouldNavigateToExecution: false
- property string currentPatternName: ""
- property string currentPatternPreview: ""
- onCurrentPageIndexChanged: {
- console.log("📱 currentPageIndex changed to:", currentPageIndex)
- }
- onShouldNavigateToExecutionChanged: {
- if (shouldNavigateToExecution) {
- console.log("🎯 Navigating to execution page")
- console.log("🎯 Current stack depth:", stackView.depth)
- // If we're in a sub-page (like PatternDetailPage), pop back to main view first
- if (stackView.depth > 1) {
- console.log("🎯 Popping back to main view first")
- stackView.pop()
- }
- // Then navigate to ExecutionPage tab (index 4)
- console.log("🎯 Setting currentPageIndex to 4")
- currentPageIndex = 4
- shouldNavigateToExecution = false
- }
- }
-
- Backend {
- id: backend
-
- onExecutionStarted: function(patternName, patternPreview) {
- console.log("🎯 QML: ExecutionStarted signal received! patternName='" + patternName + "', preview='" + patternPreview + "'")
- console.log("🎯 Setting shouldNavigateToExecution = true")
- // Store pattern info for ExecutionPage
- window.currentPatternName = patternName
- window.currentPatternPreview = patternPreview
- // Navigate to Execution tab (index 3) instead of pushing page
- shouldNavigateToExecution = true
- console.log("🎯 shouldNavigateToExecution set to:", shouldNavigateToExecution)
- }
-
- onErrorOccurred: function(error) {
- // Use custom dialog on Pi 5 for proper rotation
- if (typeof rotateDisplay !== 'undefined' && rotateDisplay) {
- customErrorDialog.errorText = error
- customErrorDialog.open()
- } else {
- errorDialog.text = error
- errorDialog.open()
- }
- }
-
- onScreenStateChanged: function(isOn) {
- console.log("🖥️ Screen state changed:", isOn ? "ON" : "OFF")
- }
-
- onBackendConnectionChanged: function(connected) {
- console.log("🔗 Backend connection changed:", connected)
- if (connected && stackView.currentItem.toString().indexOf("ConnectionSplash") !== -1) {
- console.log("✅ Backend connected, switching to main view")
- stackView.replace(mainSwipeView)
- } else if (!connected && stackView.currentItem.toString().indexOf("ConnectionSplash") === -1) {
- console.log("❌ Backend disconnected, switching to splash screen")
- stackView.replace(connectionSplash)
- }
- }
- }
-
- // Global touch/mouse handler for activity tracking
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.NoButton // Don't interfere with other mouse areas
- hoverEnabled: true
- propagateComposedEvents: true
-
- onPressed: {
- console.log("🖥️ QML: Touch/press detected - resetting activity timer")
- backend.resetActivityTimer()
- }
-
- onPositionChanged: {
- console.log("🖥️ QML: Mouse movement detected - resetting activity timer")
- backend.resetActivityTimer()
- }
-
- onClicked: {
- console.log("🖥️ QML: Click detected - resetting activity timer")
- backend.resetActivityTimer()
- }
- }
-
- PatternModel {
- id: patternModel
- }
- // Rotation container for Pi 5
- Item {
- id: rotationContainer
- anchors.fill: parent
- rotation: typeof rotateDisplay !== 'undefined' && rotateDisplay ? 180 : 0
- transformOrigin: Item.Center
- StackView {
- id: stackView
- anchors.fill: parent
- initialItem: backend.backendConnected ? mainSwipeView : connectionSplash
-
- Component {
- id: connectionSplash
-
- ConnectionSplash {
- statusText: backend.reconnectStatus
- showRetryButton: backend.reconnectStatus === "Cannot connect to backend"
-
- onRetryConnection: {
- console.log("🔄 Manual retry requested")
- backend.retryConnection()
- }
- }
- }
-
- Component {
- id: mainSwipeView
-
- Item {
- // Main content area
- StackLayout {
- id: stackLayout
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: bottomNav.top
- currentIndex: window.currentPageIndex
-
- Component.onCompleted: {
- console.log("📱 StackLayout created with currentIndex:", currentIndex, "bound to window.currentPageIndex:", window.currentPageIndex)
- }
-
- // Patterns Page
- Loader {
- source: "pages/ModernPatternListPage.qml"
- onLoaded: {
- item.patternModel = patternModel
- item.backend = backend
- item.stackView = stackView
- }
- }
-
- // Playlists Page
- Loader {
- source: "pages/ModernPlaylistPage.qml"
- onLoaded: {
- item.backend = backend
- item.stackView = stackView
- item.mainWindow = window
- }
- }
-
- // Control Page
- Loader {
- source: "pages/TableControlPage.qml"
- onLoaded: {
- item.backend = backend
- }
- }
- // LED Control Page (index 3)
- Loader {
- source: "pages/LedControlPage.qml"
- onLoaded: {
- item.backend = backend
- }
- }
- // Execution Page (index 4)
- Loader {
- source: "pages/ExecutionPage.qml"
- onLoaded: {
- item.backend = backend
- item.stackView = stackView
- item.patternName = Qt.binding(function() { return window.currentPatternName })
- item.patternPreview = Qt.binding(function() { return window.currentPatternPreview })
- }
- }
- }
-
- // Bottom Navigation
- BottomNavigation {
- id: bottomNav
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- currentIndex: window.currentPageIndex
-
- onTabClicked: function(index) {
- console.log("📱 Tab clicked:", index)
- window.currentPageIndex = index
- }
- }
- }
- }
- }
- } // End rotationContainer
- // Virtual Keyboard Support - outside rotation container for proper positioning
- InputPanel {
- id: inputPanel
- z: 99999
- y: window.height
- anchors.left: parent.left
- anchors.right: parent.right
- // Rotate keyboard for Pi 5
- rotation: typeof rotateDisplay !== 'undefined' && rotateDisplay ? 180 : 0
- transformOrigin: Item.Center
- states: State {
- name: "visible"
- when: inputPanel.active
- PropertyChanges {
- target: inputPanel
- y: typeof rotateDisplay !== 'undefined' && rotateDisplay ? 0 : window.height - inputPanel.height
- }
- }
- transitions: Transition {
- from: ""
- to: "visible"
- reversible: true
- ParallelAnimation {
- NumberAnimation {
- target: inputPanel
- property: "y"
- duration: 250
- easing.type: Easing.InOutQuad
- }
- }
- }
- }
- // Error dialog - note: MessageDialog is a system dialog, rotation may not work
- // If rotation doesn't work, we'll need to replace with a custom Dialog
- MessageDialog {
- id: errorDialog
- title: "Error"
- buttons: MessageDialog.Ok
- }
- // Custom error dialog as fallback for Pi 5 rotation
- Popup {
- id: customErrorDialog
- modal: true
- x: (window.width - width) / 2
- y: (window.height - height) / 2
- width: 320
- height: 180
- closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
- property string errorText: ""
- background: Rectangle {
- color: "#2d2d2d"
- radius: 12
- border.color: "#404040"
- border.width: 1
- // Rotate the entire dialog content for Pi 5
- rotation: typeof rotateDisplay !== 'undefined' && rotateDisplay ? 180 : 0
- transformOrigin: Item.Center
- }
- contentItem: Item {
- rotation: typeof rotateDisplay !== 'undefined' && rotateDisplay ? 180 : 0
- transformOrigin: Item.Center
- Column {
- anchors.fill: parent
- anchors.margins: 20
- spacing: 15
- Label {
- text: "Error"
- font.pixelSize: 18
- font.bold: true
- color: "#ff6b6b"
- anchors.horizontalCenter: parent.horizontalCenter
- }
- Label {
- text: customErrorDialog.errorText
- wrapMode: Text.WordWrap
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- color: "#ffffff"
- font.pixelSize: 14
- }
- Button {
- text: "OK"
- anchors.horizontalCenter: parent.horizontalCenter
- onClicked: customErrorDialog.close()
- }
- }
- }
- }
- }
|