From 0144b5c3005763fb74904ea882c33eb4d5f92758 Mon Sep 17 00:00:00 2001 From: Alex Spataru Date: Sun, 11 Aug 2024 18:20:03 -0500 Subject: [PATCH] Halway over the UI revamp --- CMakeLists.txt | 10 + app/CMakeLists.txt | 11 - app/qml/Dialogs/About.qml | 89 +- app/qml/Dialogs/Acknowledgements.qml | 62 +- app/qml/Dialogs/CsvPlayer.qml | 92 +- app/qml/Dialogs/Donate.qml | 89 +- app/qml/Dialogs/MQTTConfiguration.qml | 935 +++++++++--------- .../MainWindow/Dashboard/DashboardTitle.qml | 12 +- app/qml/MainWindow/Dashboard/ViewOptions.qml | 29 +- .../Dashboard/ViewOptionsDelegate.qml | 14 +- .../MainWindow/Dashboard/WidgetDelegate.qml | 21 +- app/qml/MainWindow/Dashboard/WidgetGrid.qml | 38 +- app/qml/MainWindow/Panes/Console.qml | 41 +- app/qml/MainWindow/Panes/Dashboard.qml | 114 +-- app/qml/MainWindow/Panes/Setup.qml | 327 +++--- .../Panes/SetupPanes/Devices/BluetoothLE.qml | 18 +- .../Panes/SetupPanes/Devices/Network.qml | 20 +- .../Panes/SetupPanes/Devices/Serial.qml | 110 +-- .../MainWindow/Panes/SetupPanes/Hardware.qml | 36 +- app/qml/MainWindow/Panes/SetupPanes/MQTT.qml | 286 ------ .../MainWindow/Panes/SetupPanes/Settings.qml | 85 +- app/qml/MainWindow/Panes/Toolbar.qml | 451 ++++----- app/qml/MainWindow/Root.qml | 315 +++--- app/qml/ProjectEditor/Root.qml | 73 +- app/qml/ProjectEditor/Sections/Footer.qml | 8 +- .../ProjectEditor/Sections/GroupEditor.qml | 6 +- app/qml/ProjectEditor/Sections/Header.qml | 35 +- .../Sections/JsonDatasetDelegate.qml | 37 +- .../Sections/JsonGroupDelegate.qml | 32 +- app/qml/ProjectEditor/Sections/TreeView.qml | 14 +- app/qml/Widgets/BigButton.qml | 3 +- app/qml/Widgets/GpsMap.qml | 6 +- app/qml/Widgets/JSONDropArea.qml | 17 +- app/qml/Widgets/Pane.qml | 2 +- app/qml/Widgets/Terminal.qml | 87 +- app/qml/main.qml | 108 +- app/rcc/icons/buttons/apply.svg | 6 + app/rcc/icons/buttons/clear.svg | 6 + app/rcc/icons/buttons/close.svg | 6 + app/rcc/icons/buttons/connected.svg | 6 + app/rcc/icons/buttons/disconnected.svg | 6 + app/rcc/icons/buttons/media-next.svg | 6 + app/rcc/icons/buttons/media-pause.svg | 6 + app/rcc/icons/buttons/media-play.svg | 6 + app/rcc/icons/buttons/media-prev.svg | 6 + app/rcc/icons/buttons/open.svg | 6 + app/rcc/icons/buttons/print.svg | 6 + app/rcc/icons/buttons/save.svg | 6 + app/rcc/icons/buttons/visibility.svg | 6 + app/rcc/icons/panes/console.svg | 9 + app/rcc/icons/panes/dashboard.svg | 22 + app/rcc/icons/panes/setup.svg | 16 + app/rcc/icons/panes/view.svg | 11 + app/rcc/icons/toolbar/about.svg | 8 + app/rcc/icons/toolbar/bug.svg | 13 - app/rcc/icons/toolbar/connect.svg | 20 +- app/rcc/icons/toolbar/console.svg | 12 +- app/rcc/icons/toolbar/csv.svg | 16 +- app/rcc/icons/toolbar/dashboard.svg | 54 +- app/rcc/icons/toolbar/device-setup.svg | 22 + app/rcc/icons/toolbar/disconnect.svg | 28 +- app/rcc/icons/toolbar/github.svg | 8 + app/rcc/icons/toolbar/help.svg | 15 +- app/rcc/icons/toolbar/mqtt.svg | 16 + app/rcc/icons/toolbar/project-editor.svg | 11 - app/rcc/icons/toolbar/project-setup.svg | 11 + app/rcc/icons/toolbar/setup.svg | 14 - app/rcc/images/code.svg | 10 + app/rcc/images/microcontroller.svg | 51 + app/rcc/images/tip.svg | 12 + app/rcc/rcc.qrc | 28 +- app/rcc/themes/Breeze.json | 129 +-- app/rcc/themes/Dark.json | 6 +- app/rcc/themes/Light.json | 6 +- app/src/Misc/CommonFonts.cpp | 13 +- app/src/Misc/CommonFonts.h | 6 +- app/src/Misc/ModuleManager.cpp | 34 +- app/src/Misc/ThemeManager.cpp | 70 +- app/src/Misc/ThemeManager.h | 3 - app/src/Project/CodeEditor.cpp | 18 +- app/src/Project/Model.cpp | 6 +- app/src/UI/Widgets/Terminal.cpp | 11 +- app/src/main.cpp | 2 + 83 files changed, 2017 insertions(+), 2405 deletions(-) delete mode 100644 app/qml/MainWindow/Panes/SetupPanes/MQTT.qml create mode 100644 app/rcc/icons/buttons/apply.svg create mode 100644 app/rcc/icons/buttons/clear.svg create mode 100644 app/rcc/icons/buttons/close.svg create mode 100644 app/rcc/icons/buttons/connected.svg create mode 100644 app/rcc/icons/buttons/disconnected.svg create mode 100644 app/rcc/icons/buttons/media-next.svg create mode 100644 app/rcc/icons/buttons/media-pause.svg create mode 100644 app/rcc/icons/buttons/media-play.svg create mode 100644 app/rcc/icons/buttons/media-prev.svg create mode 100644 app/rcc/icons/buttons/open.svg create mode 100644 app/rcc/icons/buttons/print.svg create mode 100644 app/rcc/icons/buttons/save.svg create mode 100644 app/rcc/icons/buttons/visibility.svg create mode 100644 app/rcc/icons/panes/console.svg create mode 100644 app/rcc/icons/panes/dashboard.svg create mode 100644 app/rcc/icons/panes/setup.svg create mode 100644 app/rcc/icons/panes/view.svg create mode 100644 app/rcc/icons/toolbar/about.svg delete mode 100644 app/rcc/icons/toolbar/bug.svg create mode 100644 app/rcc/icons/toolbar/device-setup.svg create mode 100644 app/rcc/icons/toolbar/github.svg create mode 100644 app/rcc/icons/toolbar/mqtt.svg delete mode 100644 app/rcc/icons/toolbar/project-editor.svg create mode 100644 app/rcc/icons/toolbar/project-setup.svg delete mode 100644 app/rcc/icons/toolbar/setup.svg create mode 100644 app/rcc/images/code.svg create mode 100644 app/rcc/images/microcontroller.svg create mode 100644 app/rcc/images/tip.svg diff --git a/CMakeLists.txt b/CMakeLists.txt index 13d63c5d..2cc15345 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,16 @@ set(PROJECT_DESCRIPTION_FILE "${PROJECT_ROOT_DIR}/README.md") set(PROJECT_FILE_NAME "${PROJECT_EXECUTABLE}-v${PROJECT_VERSION}") set(PROJECT_FILE_LICENSE "${PROJECT_ROOT_DIR}/LICENSE.md") +#------------------------------------------------------------------------------- +# Allow source code to access project information +#------------------------------------------------------------------------------- + +add_definitions(-DPROJECT_VENDOR="${PROJECT_VENDOR}") +add_definitions(-DPROJECT_CONTACT="${PROJECT_CONTACT}") +add_definitions(-DPROJECT_VERSION="${PROJECT_VERSION}") +add_definitions(-DPROJECT_APPCAST="${PROJECT_APPCAST}") +add_definitions(-DPROJECT_DISPNAME="${PROJECT_DISPNAME}") + #------------------------------------------------------------------------------- # Compiler flags #------------------------------------------------------------------------------- diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 716846c2..ff33a004 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -37,16 +37,6 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -#------------------------------------------------------------------------------- -# Allow source code to access project information -#------------------------------------------------------------------------------- - -add_definitions(-DPROJECT_VENDOR="${PROJECT_VENDOR}") -add_definitions(-DPROJECT_CONTACT="${PROJECT_CONTACT}") -add_definitions(-DPROJECT_VERSION="${PROJECT_VERSION}") -add_definitions(-DPROJECT_APPCAST="${PROJECT_APPCAST}") -add_definitions(-DPROJECT_DISPNAME="${PROJECT_DISPNAME}") - #------------------------------------------------------------------------------- # Add external dependencies (Qt) #------------------------------------------------------------------------------- @@ -182,7 +172,6 @@ set(QML_CODE qml/MainWindow/Panes/Dashboard.qml qml/MainWindow/Panes/SetupPanes/Settings.qml qml/MainWindow/Panes/SetupPanes/Hardware.qml - qml/MainWindow/Panes/SetupPanes/MQTT.qml qml/MainWindow/Panes/SetupPanes/Devices/Serial.qml qml/MainWindow/Panes/SetupPanes/Devices/BluetoothLE.qml qml/MainWindow/Panes/SetupPanes/Devices/Network.qml diff --git a/app/qml/Dialogs/About.qml b/app/qml/Dialogs/About.qml index da4f2c84..4b03aca4 100644 --- a/app/qml/Dialogs/About.qml +++ b/app/qml/Dialogs/About.qml @@ -41,72 +41,42 @@ Window { height: minimumHeight x: (Screen.desktopAvailableWidth - width) / 2 y: (Screen.desktopAvailableHeight - height) / 2 - minimumWidth: column.implicitWidth + 4 * app.spacing - maximumWidth: column.implicitWidth + 4 * app.spacing - minimumHeight: column.implicitHeight + 4 * app.spacing - maximumHeight: column.implicitHeight + 4 * app.spacing + minimumWidth: column.implicitWidth + 32 + maximumWidth: column.implicitWidth + 32 + minimumHeight: column.implicitHeight + 32 + maximumHeight: column.implicitHeight + 32 + Component.onCompleted: { + root.flags = Qt.Dialog | + Qt.WindowTitleHint | + Qt.WindowStaysOnTopHint | + Qt.WindowCloseButtonHint + } // // Use page item to set application palette // Page { anchors.fill: parent - palette.alternateBase: Cpp_ThemeManager.base - palette.base: Cpp_ThemeManager.base - palette.brightText: Cpp_ThemeManager.brightText - palette.button: Cpp_ThemeManager.button - palette.buttonText: Cpp_ThemeManager.buttonText - palette.highlight: Cpp_ThemeManager.highlight - palette.highlightedText: Cpp_ThemeManager.highlightedText - palette.link: Cpp_ThemeManager.link - palette.placeholderText: Cpp_ThemeManager.placeholderText - palette.text: Cpp_ThemeManager.text - palette.toolTipBase: Cpp_ThemeManager.tooltipBase - palette.toolTipText: Cpp_ThemeManager.tooltipText - palette.window: Cpp_ThemeManager.window - palette.windowText: Cpp_ThemeManager.windowText - - background: Rectangle { - radius: root.radius - color: root.backgroundColor - - Rectangle { - height: root.radius - color: root.backgroundColor - - anchors { - top: parent.top - left: parent.left - right: parent.right - } - } - } - - // - // Window drag handler - // - Item { - anchors.fill: parent - - MouseArea { - anchors.fill: parent - onPressedChanged: { - if (pressed) - root.startSystemMove() - } - } - } + palette.base: Cpp_ThemeManager.colors["base"] + palette.text: Cpp_ThemeManager.colors["text"] + palette.button: Cpp_ThemeManager.colors["button"] + palette.window: Cpp_ThemeManager.colors["window"] + palette.windowText: Cpp_ThemeManager.colors["text"] + palette.buttonText: Cpp_ThemeManager.colors["button_text"] + palette.highlight: Cpp_ThemeManager.colors["switch_highlight"] + palette.placeholderText: Cpp_ThemeManager.colors["placeholder_text"] + palette.highlightedText: Cpp_ThemeManager.colors["highlighted_text"] // // Window controls // ColumnLayout { id: column - spacing: app.spacing + spacing: 4 anchors.centerIn: parent RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true Image { @@ -123,7 +93,7 @@ Window { } ColumnLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter @@ -154,12 +124,11 @@ Window { Layout.fillWidth: true Layout.maximumWidth: 320 wrapMode: Label.WrapAtWordBoundaryOrAnywhere - color: Cpp_ThemeManager.highlightedTextAlternative text: qsTr("The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.") } Item { - height: app.spacing + height: 8 } Button { @@ -170,13 +139,13 @@ Window { Button { Layout.fillWidth: true - text: qsTr("Make a donation") - onClicked: app.donateDialog.show() + text: qsTr("Make a Donation") + onClicked: donateDialog.show() } Button { Layout.fillWidth: true - text: qsTr("Report bug") + text: qsTr("Report Bug") onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/issues") } @@ -189,17 +158,17 @@ Window { Button { Layout.fillWidth: true text: qsTr("Acknowledgements") - onClicked: acknowledgementsDialog.show() + onClicked: app.showAcknowledgements() } Item { - height: app.spacing + height: 8 } Button { + text: qsTr("Close") Layout.fillWidth: true onClicked: root.close() - text: qsTr("Close") } } } diff --git a/app/qml/Dialogs/Acknowledgements.qml b/app/qml/Dialogs/Acknowledgements.qml index 52f3c30b..e69692e1 100644 --- a/app/qml/Dialogs/Acknowledgements.qml +++ b/app/qml/Dialogs/Acknowledgements.qml @@ -36,58 +36,38 @@ Window { title: qsTr("Acknowledgements") x: (Screen.desktopAvailableWidth - width) / 2 y: (Screen.desktopAvailableHeight - height) / 2 - minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin - maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin - minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin - maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin + minimumWidth: column.implicitWidth + 32 + maximumWidth: column.implicitWidth + 32 + minimumHeight: column.implicitHeight + 32 + maximumHeight: column.implicitHeight + 32 + Component.onCompleted: { + root.flags = Qt.Dialog | + Qt.WindowTitleHint | + Qt.WindowStaysOnTopHint | + Qt.WindowCloseButtonHint + } // // Use page item to set application palette // Page { - anchors { - fill: parent - margins: root.shadowMargin - topMargin: titlebar.height + root.shadowMargin - } - - palette.alternateBase: Cpp_ThemeManager.base - palette.base: Cpp_ThemeManager.base - palette.brightText: Cpp_ThemeManager.brightText - palette.button: Cpp_ThemeManager.button - palette.buttonText: Cpp_ThemeManager.buttonText - palette.highlight: Cpp_ThemeManager.highlight - palette.highlightedText: Cpp_ThemeManager.highlightedText - palette.link: Cpp_ThemeManager.link - palette.placeholderText: Cpp_ThemeManager.placeholderText - palette.text: Cpp_ThemeManager.text - palette.toolTipBase: Cpp_ThemeManager.tooltipBase - palette.toolTipText: Cpp_ThemeManager.tooltipText - palette.window: Cpp_ThemeManager.window - palette.windowText: Cpp_ThemeManager.windowText - - background: Rectangle { - radius: root.radius - color: root.backgroundColor - - Rectangle { - height: root.radius - color: root.backgroundColor - - anchors { - top: parent.top - left: parent.left - right: parent.right - } - } - } + anchors.fill: parent + palette.base: Cpp_ThemeManager.colors["base"] + palette.text: Cpp_ThemeManager.colors["text"] + palette.button: Cpp_ThemeManager.colors["button"] + palette.window: Cpp_ThemeManager.colors["window"] + palette.windowText: Cpp_ThemeManager.colors["text"] + palette.buttonText: Cpp_ThemeManager.colors["button_text"] + palette.highlight: Cpp_ThemeManager.colors["switch_highlight"] + palette.placeholderText: Cpp_ThemeManager.colors["placeholder_text"] + palette.highlightedText: Cpp_ThemeManager.colors["highlighted_text"] // // Window controls // ColumnLayout { id: column - spacing: app.spacing + spacing: 8 anchors.centerIn: parent ScrollView { diff --git a/app/qml/Dialogs/CsvPlayer.qml b/app/qml/Dialogs/CsvPlayer.qml index a77325f5..6eb56a4d 100644 --- a/app/qml/Dialogs/CsvPlayer.qml +++ b/app/qml/Dialogs/CsvPlayer.qml @@ -34,12 +34,18 @@ Window { width: minimumWidth height: minimumHeight title: qsTr("CSV Player") + minimumWidth: column.implicitWidth + 32 + maximumWidth: column.implicitWidth + 32 + minimumHeight: column.implicitHeight + 32 + maximumHeight: column.implicitHeight + 32 x: (Screen.desktopAvailableWidth - width) / 2 y: (Screen.desktopAvailableHeight - height) / 2 - minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin - maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin - minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin - maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin + Component.onCompleted: { + root.flags = Qt.Dialog | + Qt.WindowTitleHint | + Qt.WindowStaysOnTopHint | + Qt.WindowCloseButtonHint + } // // Close CSV file when window is closed @@ -66,50 +72,25 @@ Window { // Use page item to set application palette // Page { - anchors { - fill: parent - margins: root.shadowMargin - topMargin: titlebar.height + root.shadowMargin - } - - palette.alternateBase: Cpp_ThemeManager.base - palette.base: Cpp_ThemeManager.base - palette.brightText: Cpp_ThemeManager.brightText - palette.button: Cpp_ThemeManager.button - palette.buttonText: Cpp_ThemeManager.buttonText - palette.highlight: Cpp_ThemeManager.highlight - palette.highlightedText: Cpp_ThemeManager.highlightedText - palette.link: Cpp_ThemeManager.link - palette.placeholderText: Cpp_ThemeManager.placeholderText - palette.text: Cpp_ThemeManager.text - palette.toolTipBase: Cpp_ThemeManager.tooltipBase - palette.toolTipText: Cpp_ThemeManager.tooltipText - palette.window: Cpp_ThemeManager.window - palette.windowText: Cpp_ThemeManager.windowText - - background: Rectangle { - radius: root.radius - color: root.backgroundColor - - Rectangle { - height: root.radius - color: root.backgroundColor - - anchors { - top: parent.top - left: parent.left - right: parent.right - } - } - } + anchors.fill: parent + palette.base: Cpp_ThemeManager.colors["base"] + palette.text: Cpp_ThemeManager.colors["text"] + palette.button: Cpp_ThemeManager.colors["button"] + palette.window: Cpp_ThemeManager.colors["window"] + palette.windowText: Cpp_ThemeManager.colors["text"] + palette.buttonText: Cpp_ThemeManager.colors["button_text"] + palette.highlight: Cpp_ThemeManager.colors["switch_highlight"] + palette.placeholderText: Cpp_ThemeManager.colors["placeholder_text"] + palette.highlightedText: Cpp_ThemeManager.colors["highlighted_text"] // // Window controls // ColumnLayout { id: column - anchors.centerIn: parent - spacing: app.spacing * 2 + spacing: 4 + anchors.margins: 16 + anchors.fill: parent // // Timestamp display @@ -132,40 +113,51 @@ Window { } } + // + // Spacer + // + Item { + Layout.minimumHeight: 4 + } + // // Play/pause buttons // RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true Layout.fillHeight: true Layout.alignment: Qt.AlignHCenter Button { + icon.width: 18 + icon.height: 18 opacity: enabled ? 1 : 0.5 - icon.color: Cpp_ThemeManager.text Layout.alignment: Qt.AlignVCenter onClicked: Cpp_CSV_Player.previousFrame() - icon.source: "qrc:/icons/media-prev.svg" + icon.source: "qrc:/icons/buttons/media-prev.svg" + icon.color: Cpp_ThemeManager.colors["button_text"] enabled: Cpp_CSV_Player.progress > 0 && !Cpp_CSV_Player.isPlaying } Button { icon.width: 32 icon.height: 32 - icon.color: Cpp_ThemeManager.text onClicked: Cpp_CSV_Player.toggle() Layout.alignment: Qt.AlignVCenter - icon.source: Cpp_CSV_Player.isPlaying ? "qrc:/icons/media-pause.svg" : - "qrc:/icons/media-play.svg" + icon.color: Cpp_ThemeManager.colors["button_text"] + icon.source: Cpp_CSV_Player.isPlaying ? "qrc:/icons/buttons/media-pause.svg" : + "qrc:/icons/buttons/media-play.svg" } Button { + icon.width: 18 + icon.height: 18 opacity: enabled ? 1 : 0.5 - icon.color: Cpp_ThemeManager.text Layout.alignment: Qt.AlignVCenter onClicked: Cpp_CSV_Player.nextFrame() - icon.source: "qrc:/icons/media-next.svg" + icon.source: "qrc:/icons/buttons/media-next.svg" + icon.color: Cpp_ThemeManager.colors["button_text"] enabled: Cpp_CSV_Player.progress < 1 && !Cpp_CSV_Player.isPlaying } } diff --git a/app/qml/Dialogs/Donate.qml b/app/qml/Dialogs/Donate.qml index 497a4c10..59552b5e 100644 --- a/app/qml/Dialogs/Donate.qml +++ b/app/qml/Dialogs/Donate.qml @@ -35,12 +35,18 @@ Window { title: qsTr("Donate") width: minimumWidth height: minimumHeight + minimumWidth: column.implicitWidth + 32 + maximumWidth: column.implicitWidth + 32 + minimumHeight: column.implicitHeight + 32 + maximumHeight: column.implicitHeight + 32 x: (Screen.desktopAvailableWidth - width) / 2 y: (Screen.desktopAvailableHeight - height) / 2 - minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin - maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin - minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin - maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin + Component.onCompleted: { + root.flags = Qt.Dialog | + Qt.WindowTitleHint | + Qt.WindowStaysOnTopHint | + Qt.WindowCloseButtonHint + } // // Custom properties @@ -84,70 +90,29 @@ Window { // Use page item to set application palette // Page { - anchors { - fill: parent - margins: root.shadowMargin - topMargin: titlebar.height + root.shadowMargin - } - - palette.alternateBase: Cpp_ThemeManager.base - palette.base: Cpp_ThemeManager.base - palette.brightText: Cpp_ThemeManager.brightText - palette.button: Cpp_ThemeManager.button - palette.buttonText: Cpp_ThemeManager.buttonText - palette.highlight: Cpp_ThemeManager.highlight - palette.highlightedText: Cpp_ThemeManager.highlightedText - palette.link: Cpp_ThemeManager.link - palette.placeholderText: Cpp_ThemeManager.placeholderText - palette.text: Cpp_ThemeManager.text - palette.toolTipBase: Cpp_ThemeManager.tooltipBase - palette.toolTipText: Cpp_ThemeManager.tooltipText - palette.window: Cpp_ThemeManager.window - palette.windowText: Cpp_ThemeManager.windowText - - background: Rectangle { - radius: root.radius - color: root.backgroundColor - - Rectangle { - height: root.radius - color: root.backgroundColor - - anchors { - top: parent.top - left: parent.left - right: parent.right - } - } - } - - // - // Window drag handler - // - Item { - anchors.fill: parent - - MouseArea { - anchors.fill: parent - onPressedChanged: { - if (pressed) - root.startSystemMove() - } - } - } + anchors.fill: parent + palette.base: Cpp_ThemeManager.colors["base"] + palette.text: Cpp_ThemeManager.colors["text"] + palette.button: Cpp_ThemeManager.colors["button"] + palette.window: Cpp_ThemeManager.colors["window"] + palette.windowText: Cpp_ThemeManager.colors["text"] + palette.buttonText: Cpp_ThemeManager.colors["button_text"] + palette.highlight: Cpp_ThemeManager.colors["switch_highlight"] + palette.placeholderText: Cpp_ThemeManager.colors["placeholder_text"] + palette.highlightedText: Cpp_ThemeManager.colors["highlighted_text"] // // Window controls // ColumnLayout { id: column + spacing: 16 anchors.centerIn: parent - spacing: app.spacing * 2 RowLayout { + spacing: 16 Layout.fillWidth: true Layout.fillHeight: true - spacing: app.spacing * 2 Image { sourceSize: Qt.size(120, 120) @@ -163,7 +128,7 @@ Window { } ColumnLayout { - spacing: app.spacing * 2 + spacing: 4 Layout.fillWidth: true Layout.fillHeight: true @@ -173,10 +138,9 @@ Window { Label { id: title - font.bold: true - font.pixelSize: 16 Layout.fillWidth: true Layout.minimumHeight: font.pixelSize + font: Cpp_Misc_CommonFonts.customUiFont(16, true) text: qsTr("Support the development of %1!").arg(Cpp_AppName) } @@ -196,7 +160,6 @@ Window { Layout.minimumHeight: font.pixelSize * 2 Layout.maximumWidth: title.implicitWidth wrapMode: Label.WrapAtWordBoundaryOrAnywhere - color: Cpp_ThemeManager.highlightedTextAlternative text: qsTr("You can also support this project by sharing it, reporting bugs and proposing new features!") } @@ -207,12 +170,12 @@ Window { } RowLayout { + spacing: 4 Layout.fillWidth: true - spacing: app.spacing CheckBox { + Layout.leftMargin: -6 id: doNotShowAgainCheck - Layout.leftMargin: -app.spacing Layout.alignment: Qt.AlignVCenter text: qsTr("Don't annoy me again!") } diff --git a/app/qml/Dialogs/MQTTConfiguration.qml b/app/qml/Dialogs/MQTTConfiguration.qml index 3c1c0137..b170bf10 100644 --- a/app/qml/Dialogs/MQTTConfiguration.qml +++ b/app/qml/Dialogs/MQTTConfiguration.qml @@ -39,13 +39,19 @@ Window { // width: minimumWidth height: minimumHeight - title: qsTr("MQTT Configuration") + title: qsTr("MQTT Setup") + minimumWidth: column.implicitWidth + 32 + maximumWidth: column.implicitWidth + 32 + minimumHeight: column.implicitHeight + 32 + maximumHeight: column.implicitHeight + 32 x: (Screen.desktopAvailableWidth - width) / 2 y: (Screen.desktopAvailableHeight - height) / 2 - minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin - maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin - minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin - maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin + Component.onCompleted: { + root.flags = Qt.Dialog | + Qt.WindowTitleHint | + Qt.WindowStaysOnTopHint | + Qt.WindowCloseButtonHint + } // // Save settings @@ -64,542 +70,509 @@ Window { property alias ssl: _ssl.checked property alias certificate: _certificateMode.currentIndex property alias protocol: _protocols.currentIndex - property alias caFilePath: _caFile.text } // // Use page item to set application palette // Page { - anchors { - fill: parent - margins: root.shadowMargin - topMargin: titlebar.height + root.shadowMargin - } - - palette.alternateBase: Cpp_ThemeManager.base - palette.base: Cpp_ThemeManager.base - palette.brightText: Cpp_ThemeManager.brightText - palette.button: Cpp_ThemeManager.button - palette.buttonText: Cpp_ThemeManager.buttonText - palette.highlight: Cpp_ThemeManager.highlight - palette.highlightedText: Cpp_ThemeManager.highlightedText - palette.link: Cpp_ThemeManager.link - palette.placeholderText: Cpp_ThemeManager.placeholderText - palette.text: Cpp_ThemeManager.text - palette.toolTipBase: Cpp_ThemeManager.tooltipBase - palette.toolTipText: Cpp_ThemeManager.tooltipText - palette.window: Cpp_ThemeManager.window - palette.windowText: Cpp_ThemeManager.windowText - - background: Rectangle { - radius: root.radius - color: root.backgroundColor - - Rectangle { - height: root.radius - color: root.backgroundColor - - anchors { - top: parent.top - left: parent.left - right: parent.right - } - } - } + anchors.fill: parent + palette.base: Cpp_ThemeManager.colors["base"] + palette.text: Cpp_ThemeManager.colors["text"] + palette.button: Cpp_ThemeManager.colors["button"] + palette.window: Cpp_ThemeManager.colors["window"] + palette.highlight: Cpp_ThemeManager.colors["highlight"] + palette.buttonText: Cpp_ThemeManager.colors["button_text"] + palette.placeholderText: Cpp_ThemeManager.colors["placeholder_text"] + palette.highlightedText: Cpp_ThemeManager.colors["highlighted_text"] // // Window controls // ColumnLayout { id: column - spacing: app.spacing + spacing: 8 anchors.centerIn: parent - GridLayout { - columns: 2 - rowSpacing: 0 + GroupBox { Layout.fillWidth: true - columnSpacing: app.spacing - // - // Version & mode titles - // - Label { - text: qsTr("Version") + ":" - } Label { - text: qsTr("Mode") + ":" + background: Rectangle { + radius: 2 + border.width: 1 + color: Cpp_ThemeManager.colors["groupbox_background"] + border.color: Cpp_ThemeManager.colors["groupbox_border"] } - // - // MQTT version - // - ComboBox { - id: _version + GridLayout { + columns: 2 + rowSpacing: 0 Layout.fillWidth: true - Layout.minimumWidth: 256 - model: Cpp_MQTT_Client.mqttVersions - currentIndex: Cpp_MQTT_Client.mqttVersion - onCurrentIndexChanged: { - if (Cpp_MQTT_Client.mqttVersion !== currentIndex) - Cpp_MQTT_Client.mqttVersion = currentIndex - } - } + columnSpacing: 8 - // - // Client mode version - // - ComboBox { - id: _mode - Layout.fillWidth: true - Layout.minimumWidth: 256 - model: Cpp_MQTT_Client.clientModes - currentIndex: Cpp_MQTT_Client.clientMode - onCurrentIndexChanged: { - if (Cpp_MQTT_Client.clientMode !== currentIndex) - Cpp_MQTT_Client.clientMode = currentIndex - } - } - - // - // Spacers - // - Item { - height: app.spacing - } Item { - height: app.spacing - } - - // - // QOS Level & Keep Alive - // - Label { - opacity: enabled ? 1 : 0.5 - text: qsTr("QOS level") + ":" - enabled: !Cpp_MQTT_Client.isConnectedToHost - } Label { - opacity: enabled ? 1 : 0.5 - text: qsTr("Keep alive (s)") + ":" - enabled: !Cpp_MQTT_Client.isConnectedToHost - } - - // - // QOS - // - ComboBox { - id: _qos - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - model: Cpp_MQTT_Client.qosLevels - currentIndex: Cpp_MQTT_Client.qos - enabled: !Cpp_MQTT_Client.isConnectedToHost - - onCurrentIndexChanged: { - if (Cpp_MQTT_Client.qos !== currentIndex) - Cpp_MQTT_Client.qos = currentIndex - } - } - - // - // Keep alive - // - TextField { - id: _keepAlive - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - placeholderText: Cpp_MQTT_Client.keepAlive - enabled: !Cpp_MQTT_Client.isConnectedToHost - Component.onCompleted: text = Cpp_MQTT_Client.keepAlive - - onTextChanged: { - if (Cpp_MQTT_Client.keepAlive !== text && text.length > 0) - Cpp_MQTT_Client.keepAlive = text - - if (text.length === 0) - Cpp_MQTT_Client.keepAlive = 1 + // + // Version & mode titles + // + Label { + text: qsTr("Version") + ":" + color: Cpp_ThemeManager.colors["text"] + } Label { + text: qsTr("Mode") + ":" + color: Cpp_ThemeManager.colors["text"] } - validator: IntValidator { - bottom: 1 - top: 65535 - } - } - - // - // Spacers - // - Item { - height: app.spacing - } Item { - height: app.spacing - } - - // - // Host & port titles - // - Label { - text: qsTr("Host") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } Label { - text: qsTr("Port") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } - - // - // Host - // - TextField { - id: _host - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - placeholderText: Cpp_MQTT_Client.defaultHost - Component.onCompleted: text = Cpp_MQTT_Client.host - - onTextChanged: { - if (Cpp_MQTT_Client.host !== text && text.length > 0) - Cpp_MQTT_Client.host = text - - if (text.length === 0) - Cpp_MQTT_Client.host = Cpp_MQTT_Client.defaultHost - } - } - - // - // Port - // - TextField { - id: _port - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - placeholderText: Cpp_MQTT_Client.defaultPort - Component.onCompleted: text = Cpp_MQTT_Client.port - - onTextChanged: { - if (Cpp_MQTT_Client.port !== text && text.length > 0) - Cpp_MQTT_Client.port = text - - if (text.length === 0) - Cpp_MQTT_Client.port = Cpp_MQTT_Client.defaultPort + // + // MQTT version + // + ComboBox { + id: _version + Layout.fillWidth: true + Layout.minimumWidth: 256 + model: Cpp_MQTT_Client.mqttVersions + currentIndex: Cpp_MQTT_Client.mqttVersion + onCurrentIndexChanged: { + if (Cpp_MQTT_Client.mqttVersion !== currentIndex) + Cpp_MQTT_Client.mqttVersion = currentIndex + } } - validator: IntValidator { - bottom: 0 - top: 65535 + // + // Client mode version + // + ComboBox { + id: _mode + Layout.fillWidth: true + Layout.minimumWidth: 256 + model: Cpp_MQTT_Client.clientModes + currentIndex: Cpp_MQTT_Client.clientMode + onCurrentIndexChanged: { + if (Cpp_MQTT_Client.clientMode !== currentIndex) + Cpp_MQTT_Client.clientMode = currentIndex + } } - } - // - // Spacers - // - Item { - height: app.spacing - } Item { - height: app.spacing - } - - // - // Topic & retain labels - // - Label { - text: qsTr("Topic") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } Label { - text: qsTr("Retain") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } - - // - // Topic - // - TextField { - id: _topic - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - text: Cpp_MQTT_Client.topic - placeholderText: qsTr("MQTT topic") - enabled: !Cpp_MQTT_Client.isConnectedToHost - - onTextChanged: { - if (Cpp_MQTT_Client.topic !== text) - Cpp_MQTT_Client.topic = text + // + // Spacers + // + Item { + height: 8 + } Item { + height: 8 } - } - // - // Retain checkbox - // - CheckBox { - id: _retain - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - text: qsTr("Add retain flag") - Layout.leftMargin: -app.spacing - checked: Cpp_MQTT_Client.retain - enabled: !Cpp_MQTT_Client.isConnectedToHost - - onCheckedChanged: { - if (Cpp_MQTT_Client.retain != checked) - Cpp_MQTT_Client.retain = checked + // + // QOS Level & Keep Alive + // + Label { + opacity: enabled ? 1 : 0.5 + text: qsTr("QOS Level") + ":" + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost + } Label { + opacity: enabled ? 1 : 0.5 + text: qsTr("Keep Alive (s)") + ":" + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost } - } - // - // Spacers - // - Item { - height: app.spacing - } Item { - height: app.spacing - } - - // - // Username & password titles - // - Label { - text: qsTr("User") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } Label { - text: qsTr("Password") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } - - // - // Username - // - TextField { - id: _user - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - text: Cpp_MQTT_Client.username - placeholderText: qsTr("MQTT username") - enabled: !Cpp_MQTT_Client.isConnectedToHost - - onTextChanged: { - if (Cpp_MQTT_Client.username !== text) - Cpp_MQTT_Client.username = text - } - } - - // - // Password - // - RowLayout { - Layout.fillWidth: true - spacing: app.spacing - - TextField { - id: _password + // + // QOS + // + ComboBox { + id: _qos Layout.fillWidth: true opacity: enabled ? 1 : 0.5 - echoMode: TextField.Password - text: Cpp_MQTT_Client.password - placeholderText: qsTr("MQTT password") + model: Cpp_MQTT_Client.qosLevels + currentIndex: Cpp_MQTT_Client.qos + enabled: !Cpp_MQTT_Client.isConnectedToHost + + onCurrentIndexChanged: { + if (Cpp_MQTT_Client.qos !== currentIndex) + Cpp_MQTT_Client.qos = currentIndex + } + } + + // + // Keep alive + // + TextField { + id: _keepAlive + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + placeholderText: Cpp_MQTT_Client.keepAlive + enabled: !Cpp_MQTT_Client.isConnectedToHost + Component.onCompleted: text = Cpp_MQTT_Client.keepAlive + + onTextChanged: { + if (Cpp_MQTT_Client.keepAlive !== text && text.length > 0) + Cpp_MQTT_Client.keepAlive = text + + if (text.length === 0) + Cpp_MQTT_Client.keepAlive = 1 + } + + validator: IntValidator { + bottom: 1 + top: 65535 + } + } + + // + // Spacers + // + Item { + height: 8 + } Item { + height: 8 + } + + // + // Host & port titles + // + Label { + text: qsTr("Host") + ":" + opacity: enabled ? 1 : 0.5 + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost + } Label { + text: qsTr("Port") + ":" + opacity: enabled ? 1 : 0.5 + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost + } + + // + // Host + // + TextField { + id: _host + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + enabled: !Cpp_MQTT_Client.isConnectedToHost + placeholderText: Cpp_MQTT_Client.defaultHost + + onTextChanged: { + if (Cpp_MQTT_Client.host !== text && text.length > 0) + Cpp_MQTT_Client.host = text + + else if (text.length === 0) + Cpp_MQTT_Client.host = Cpp_MQTT_Client.defaultHost + } + } + + // + // Port + // + TextField { + id: _port + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + enabled: !Cpp_MQTT_Client.isConnectedToHost + placeholderText: Cpp_MQTT_Client.defaultPort + Component.onCompleted: text = Cpp_MQTT_Client.port + + onTextChanged: { + if (Cpp_MQTT_Client.port !== text && text.length > 0) + Cpp_MQTT_Client.port = text + + if (text.length === 0) + Cpp_MQTT_Client.port = Cpp_MQTT_Client.defaultPort + } + + validator: IntValidator { + bottom: 0 + top: 65535 + } + } + + // + // Spacers + // + Item { + height: 8 + } Item { + height: 8 + } + + // + // Topic & retain labels + // + Label { + text: qsTr("Topic") + ":" + opacity: enabled ? 1 : 0.5 + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost + } Label { + text: qsTr("Retain") + ":" + opacity: enabled ? 1 : 0.5 + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost + } + + // + // Topic + // + TextField { + id: _topic + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + text: Cpp_MQTT_Client.topic + placeholderText: qsTr("MQTT Topic") enabled: !Cpp_MQTT_Client.isConnectedToHost onTextChanged: { - if (Cpp_MQTT_Client.password !== text) - Cpp_MQTT_Client.password = text + if (Cpp_MQTT_Client.topic !== text) + Cpp_MQTT_Client.topic = text } } - Button { - checkable: true - icon.color: palette.text - Layout.maximumWidth: height - Layout.alignment: Qt.AlignVCenter - icon.source: "qrc:/icons/visibility.svg" - onCheckedChanged: _password.echoMode = (checked ? TextField.Normal : - TextField.Password) - } - } - - // Spacers - // - Item { - height: app.spacing - } Item { - height: app.spacing - } - - // - // SSL & certificate titles - // - Label { - text: qsTr("Enable SSL/TLS:") - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } Label { - text: qsTr("Certificate:") - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost && _ssl.checked - } - - // - // SSL/TLS switch - // - Switch { - id: _ssl - opacity: enabled ? 1 : 0.5 - Layout.leftMargin: -app.spacing - checked: Cpp_MQTT_Client.sslEnabled - enabled: !Cpp_MQTT_Client.isConnectedToHost - - onCheckedChanged: { - if (Cpp_MQTT_Client.sslEnabled !== checked) - Cpp_MQTT_Client.sslEnabled = checked - } - } - - // - // Certificate selection - // - RowLayout { - spacing: app.spacing - Layout.fillWidth: true - - ComboBox { - id: _certificateMode + // + // Retain checkbox + // + CheckBox { + id: _retain + Layout.leftMargin: -6 Layout.fillWidth: true opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost && _ssl.checked - model: [ - qsTr("Use system database"), - qsTr("Custom CA file") - ] + text: qsTr("Add Retain Flag") + checked: Cpp_MQTT_Client.retain + enabled: !Cpp_MQTT_Client.isConnectedToHost - onCurrentIndexChanged: { - if (currentIndex == 0) - Cpp_MQTT_Client.loadCaFile("") + onCheckedChanged: { + if (Cpp_MQTT_Client.retain != checked) + Cpp_MQTT_Client.retain = checked } } - Button { - icon.color: palette.text + // + // Spacers + // + Item { + height: 8 + } Item { + height: 8 + } + + // + // Username & password titles + // + Label { + text: qsTr("User") + ":" opacity: enabled ? 1 : 0.5 - Layout.maximumWidth: height - Layout.alignment: Qt.AlignVCenter - icon.source: "qrc:/icons/open.svg" - onClicked: Cpp_MQTT_Client.loadCaFile() - enabled: _certificateMode.currentIndex == 1 && _ssl.checked + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost + } Label { + text: qsTr("Password") + ":" + opacity: enabled ? 1 : 0.5 + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost + } + + // + // Username + // + TextField { + id: _user + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + text: Cpp_MQTT_Client.username + placeholderText: qsTr("MQTT Username") + enabled: !Cpp_MQTT_Client.isConnectedToHost + + onTextChanged: { + if (Cpp_MQTT_Client.username !== text) + Cpp_MQTT_Client.username = text + } + } + + // + // Password + // + RowLayout { + Layout.fillWidth: true + spacing: 8 + + TextField { + id: _password + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + echoMode: TextField.Password + text: Cpp_MQTT_Client.password + placeholderText: qsTr("MQTT Password") + enabled: !Cpp_MQTT_Client.isConnectedToHost + + onTextChanged: { + if (Cpp_MQTT_Client.password !== text) + Cpp_MQTT_Client.password = text + } + } + + Button { + checkable: true + icon.color: palette.text + Layout.maximumWidth: height + Layout.alignment: Qt.AlignVCenter + icon.source: "qrc:/icons/buttons/visibility.svg" + onCheckedChanged: _password.echoMode = (checked ? TextField.Normal : + TextField.Password) + } + } + + // Spacers + // + Item { + height: 8 + } Item { + height: 8 + } + + // + // SSL & certificate titles + // + Label { + text: qsTr("Enable SSL/TLS:") + opacity: enabled ? 1 : 0.5 + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost + } Label { + text: qsTr("Certificate:") + opacity: enabled ? 1 : 0.5 + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost && _ssl.checked + } + + // + // SSL/TLS switch + // + Switch { + id: _ssl + opacity: enabled ? 1 : 0.5 + Layout.leftMargin: -8 + checked: Cpp_MQTT_Client.sslEnabled + enabled: !Cpp_MQTT_Client.isConnectedToHost + + onCheckedChanged: { + if (Cpp_MQTT_Client.sslEnabled !== checked) + Cpp_MQTT_Client.sslEnabled = checked + } + } + + // + // Certificate selection + // + RowLayout { + spacing: 8 + Layout.fillWidth: true + + ComboBox { + id: _certificateMode + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + enabled: !Cpp_MQTT_Client.isConnectedToHost && _ssl.checked + model: [ + qsTr("Use System Database"), + qsTr("Custom CA File") + ] + + onCurrentIndexChanged: { + if (currentIndex === 0) + Cpp_MQTT_Client.loadCaFile("") + } + } + + Button { + icon.color: palette.text + opacity: enabled ? 1 : 0.5 + Layout.maximumWidth: height + Layout.alignment: Qt.AlignVCenter + onClicked: Cpp_MQTT_Client.loadCaFile() + icon.source: "qrc:/icons/buttons/open.svg" + enabled: _certificateMode.currentIndex === 1 && _ssl.checked + } + } + + // + // Spacers + // + Item { + height: 8 + } Item { + height: 8 + } + + // + // SSL/TLS protocol selection title + // + Item { + Layout.fillWidth: true + } Label { + text: qsTr("Protocol:") + opacity: enabled ? 1 : 0.5 + color: Cpp_ThemeManager.colors["text"] + enabled: !Cpp_MQTT_Client.isConnectedToHost && _ssl.checked + } + + // + // SSL/TLS protocol selection + // + Item { + Layout.fillWidth: true + } ComboBox { + id: _protocols + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + model: Cpp_MQTT_Client.sslProtocols + enabled: !Cpp_MQTT_Client.isConnectedToHost && _ssl.checked + + onCurrentIndexChanged: { + if (currentIndex !== Cpp_MQTT_Client.sslProtocol) + Cpp_MQTT_Client.sslProtocol = currentIndex + } + } + + // + // Spacers + // + Item { + height: 8 + } Item { + height: 8 } } - - // - // Spacers - // - Item { - height: app.spacing - } Item { - height: app.spacing - } - - // - // SSL/TLS protocol selection title - // - Item { - Layout.fillWidth: true - } Label { - text: qsTr("Protocol:") - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost && _ssl.checked - } - - // - // SSL/TLS protocol selection - // - Item { - Layout.fillWidth: true - } ComboBox { - id: _protocols - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - model: Cpp_MQTT_Client.sslProtocols - enabled: !Cpp_MQTT_Client.isConnectedToHost && _ssl.checked - - onCurrentIndexChanged: { - if (currentIndex !== Cpp_MQTT_Client.sslProtocol) - Cpp_MQTT_Client.sslProtocol = currentIndex - } - } - } - - // - // Spacer - // - Item { - height: app.spacing - visible: Cpp_MQTT_Client.caFilePath.length > 0 - } - - // - // CA file display - // - RowLayout { - spacing: app.spacing - Layout.fillWidth: true - visible: Cpp_MQTT_Client.caFilePath.length > 0 - - Label { - font.bold: true - text: qsTr("CA file:") - Layout.alignment: Qt.AlignVCenter - } - - Label { - id: _caFile - text: Cpp_MQTT_Client.caFilePath - onTextChanged: { - if (text !== Cpp_MQTT_Client.caFilePath) - Cpp_MQTT_Client.loadCaFile(text) - } - } - } - - // - // Spacer - // - Item { - height: app.spacing * 2 - visible: Cpp_MQTT_Client.caFilePath.length <= 0 } // // Buttons // RowLayout { - spacing: app.spacing + spacing: 4 Layout.fillWidth: true Button { - icon.width: 24 - icon.height: 24 - font.bold: true + icon.width: 18 + icon.height: 18 + onClicked: root.close() + text: qsTr("Close") + " " + Layout.alignment: Qt.AlignVCenter + icon.source: "qrc:/icons/buttons/close.svg" + icon.color: Cpp_ThemeManager.colors["button_text"] + } + + Item { Layout.fillWidth: true - icon.color: Cpp_ThemeManager.mqttButton - checked: Cpp_MQTT_Client.isConnectedToHost - onClicked: Cpp_MQTT_Client.toggleConnection() - palette.buttonText: Cpp_ThemeManager.mqttButton - text: (checked ? qsTr("Disconnect") : qsTr("Connect")) + " " - icon.source: checked ? "qrc:/icons/disconnect.svg" : - "qrc:/icons/connect.svg" } Button { - icon.width: 24 - icon.height: 24 - Layout.fillWidth: true - onClicked: root.close() - text: qsTr("Apply") + " " - icon.color: palette.buttonText - icon.source: "qrc:/icons/apply.svg" + icon.width: 18 + icon.height: 18 + highlighted: true + Layout.alignment: Qt.AlignVCenter + checked: Cpp_MQTT_Client.isConnectedToHost + onClicked: Cpp_MQTT_Client.toggleConnection() + icon.color: Cpp_ThemeManager.colors["button_text"] + text: (checked ? qsTr("Disconnect") : qsTr("Connect")) + " " + icon.source: checked ? "qrc:/icons/buttons/connected.svg" : + "qrc:/icons/buttons/disconnected.svg" } } } diff --git a/app/qml/MainWindow/Dashboard/DashboardTitle.qml b/app/qml/MainWindow/Dashboard/DashboardTitle.qml index f9a841c4..2ffabc79 100644 --- a/app/qml/MainWindow/Dashboard/DashboardTitle.qml +++ b/app/qml/MainWindow/Dashboard/DashboardTitle.qml @@ -25,7 +25,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets +import "../../Widgets" as Widgets Rectangle { id: root @@ -50,21 +50,21 @@ Rectangle { } RowLayout { - spacing: app.spacing + spacing: 8 anchors { margins: 0 left: parent.left right: parent.right - leftMargin: app.spacing - rightMargin: app.spacing + leftMargin: 8 + rightMargin: 8 verticalCenter: parent.verticalCenter } - Widgets.Icon { + /*Widgets.Icon { Layout.alignment: Qt.AlignVCenter source: "qrc:/icons/arrow-right.svg" - } + }*/ Label { color: palette.brightText diff --git a/app/qml/MainWindow/Dashboard/ViewOptions.qml b/app/qml/MainWindow/Dashboard/ViewOptions.qml index f3c31027..a2c844eb 100644 --- a/app/qml/MainWindow/Dashboard/ViewOptions.qml +++ b/app/qml/MainWindow/Dashboard/ViewOptions.qml @@ -33,11 +33,8 @@ Widgets.Pane { // // Window properties // - gradient: true title: qsTr("View") - headerDoubleClickEnabled: false - icon.source: "qrc:/icons/visibility.svg" - backgroundColor: Cpp_ThemeManager.paneWindowBackground + icon: "qrc:/icons/panes/view.svg" // // Signals @@ -87,7 +84,7 @@ Widgets.Pane { clip: true contentWidth: -1 anchors.fill: parent - anchors.margins: app.spacing + anchors.margins: 8 anchors.topMargin: root.borderWidth anchors.bottomMargin: root.borderWidth @@ -96,31 +93,31 @@ Widgets.Pane { // ColumnLayout { id: layout - x: app.spacing - spacing: app.spacing / 2 - width: parent.width - 10 - 2 * app.spacing + x: 8 + spacing: 8 / 2 + width: parent.width - 10 - 2 * 8 // // Spacer // Item { - height: app.spacing + height: 8 } // // View options title // RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0 - Widgets.Icon { + /*Widgets.Icon { width: 18 height: 18 color: palette.text source: "qrc:/icons/visibility.svg" - } + }*/ Label { font.bold: true @@ -136,7 +133,7 @@ Widgets.Pane { // Spacer // Item { - height: app.spacing + height: 8 } // @@ -144,8 +141,8 @@ Widgets.Pane { // GridLayout { columns: 3 - rowSpacing: app.spacing - columnSpacing: app.spacing + rowSpacing: 8 + columnSpacing: 8 // // Number of plot points slider @@ -208,7 +205,7 @@ Widgets.Pane { // Spacer // Item { - height: app.spacing + height: 8 } // diff --git a/app/qml/MainWindow/Dashboard/ViewOptionsDelegate.qml b/app/qml/MainWindow/Dashboard/ViewOptionsDelegate.qml index fe113661..f3004186 100644 --- a/app/qml/MainWindow/Dashboard/ViewOptionsDelegate.qml +++ b/app/qml/MainWindow/Dashboard/ViewOptionsDelegate.qml @@ -2,12 +2,10 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets - ColumnLayout { id: root visible: count > 0 - spacing: app.spacing + spacing: 8 property int count: 0 property var titles:[""] @@ -25,16 +23,16 @@ ColumnLayout { } RowLayout { - spacing: app.spacing + spacing: 8 visible: root.count > 0 - Widgets.Icon { + /*Widgets.Icon { width: 18 height: 18 source: root.icon color: palette.text opacity: hideAll.checked ? 0.5 : 1 - } + }*/ Label { font.bold: true @@ -53,7 +51,7 @@ ColumnLayout { flat: true checkable: true icon.color: palette.text - Layout.rightMargin: -app.spacing + Layout.rightMargin: -8 icon.source: checked ? "qrc:/icons/show-all.svg" : "qrc:/icons/hide-all.svg" onCheckedChanged: { for (var i = 0; i < root.count; ++i) @@ -74,7 +72,7 @@ ColumnLayout { } Item { - height: app.spacing + height: 8 visible: !hideAll.checked && count > 0 } } diff --git a/app/qml/MainWindow/Dashboard/WidgetDelegate.qml b/app/qml/MainWindow/Dashboard/WidgetDelegate.qml index 486afe2c..b014fc81 100644 --- a/app/qml/MainWindow/Dashboard/WidgetDelegate.qml +++ b/app/qml/MainWindow/Dashboard/WidgetDelegate.qml @@ -26,7 +26,7 @@ import QtQuick.Controls import SerialStudio -import "../Widgets" as Widgets +import "../../Widgets" as Widgets Item { id: root @@ -34,19 +34,19 @@ Item { property int widgetIndex: -1 property Window externalWindow: null - Widgets.Window { + Widgets.Pane { id: window anchors.fill: parent title: widget.widgetTitle - icon.source: widget.widgetIcon - headerDoubleClickEnabled: true + icon: widget.widgetIcon + /*headerDoubleClickEnabled: true borderColor: Cpp_ThemeManager.widgetWindowBorder onHeaderDoubleClicked: { if (root.externalWindow !== null) root.externalWindow.showNormal() else externalWindowLoader.active = true - } + }*/ DashboardWidget { id: widget @@ -86,11 +86,6 @@ Item { minimumWidth: 640 minimumHeight: 480 title: externalWidget.widgetTitle - titlebarText: Cpp_ThemeManager.text - titlebarColor: Cpp_ThemeManager.widgetWindowBackground - backgroundColor: Cpp_ThemeManager.widgetWindowBackground - borderColor: isMaximized ? backgroundColor : Cpp_ThemeManager.highlight - extraFlags: Qt.WindowStaysOnTopHint | Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint Timer { id: timer @@ -141,12 +136,6 @@ Item { } } } - - FramelessWindow.ResizeHandles { - window: _window - anchors.fill: parent - handleSize: _window.handleSize - } } } } diff --git a/app/qml/MainWindow/Dashboard/WidgetGrid.qml b/app/qml/MainWindow/Dashboard/WidgetGrid.qml index 960881f8..309352f7 100644 --- a/app/qml/MainWindow/Dashboard/WidgetGrid.qml +++ b/app/qml/MainWindow/Dashboard/WidgetGrid.qml @@ -24,21 +24,16 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets +import "../../Widgets" as Widgets -Widgets.Window { +Widgets.Pane { id: root - - // - // Window properties - // - gradient: true title: qsTr("Data") - headerDoubleClickEnabled: false - icon.source: "qrc:/icons/dataset.svg" - backgroundColor: Cpp_ThemeManager.paneWindowBackground + icon: "qrc:/icons/panes/dashboard.svg" + // // Hacks for calculating cell width + // property int columns: 4 readonly property int cellWidth: (grid.width - 2 * scroll.width) / columns readonly property int cellHeight: cellWidth * (2 / 3) @@ -56,8 +51,8 @@ Widgets.Window { anchors { fill: parent - margins: app.spacing * 2 - rightMargin: app.spacing + margins: 8 + rightMargin: 4 } ScrollBar.vertical: ScrollBar { @@ -66,10 +61,10 @@ Widgets.Window { Grid { id: grid + rowSpacing: 4 + columnSpacing: 4 width: parent.width columns: root.columns - rowSpacing: app.spacing - columnSpacing: app.spacing height: childrenRect.height Timer { @@ -106,19 +101,4 @@ Widgets.Window { } } } - - // - // Redraw bottom window border over flickable items - // - Rectangle { - height: root.borderWidth - color: root.gradientColor1 - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - leftMargin: root.radius - rightMargin: root.radius - } - } } diff --git a/app/qml/MainWindow/Panes/Console.qml b/app/qml/MainWindow/Panes/Console.qml index 6da2abba..abb32435 100644 --- a/app/qml/MainWindow/Panes/Console.qml +++ b/app/qml/MainWindow/Panes/Console.qml @@ -24,10 +24,12 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets +import "../../Widgets" as Widgets -Item { +Widgets.Pane { id: root + title: qsTr("Console") + icon: "qrc:/icons/panes/console.svg" // // Custom properties @@ -47,41 +49,12 @@ Item { terminal.selectAll() } - // - // Load welcome guide - // - function showWelcomeGuide() { - clear() - Cpp_IO_Console.append(Cpp_Misc_Translator.welcomeConsoleText() + "\n") - } - - // - // Re-load welcome text when the language is changed - // - Connections { - target: Cpp_Misc_Translator - function onLanguageChanged() { - root.showWelcomeGuide() - } - } - // // Console window // - Widgets.Window { - id: window - gradient: true + Widgets.Terminal { + id: terminal + widgetEnabled: true anchors.fill: parent - title: qsTr("Console") - headerDoubleClickEnabled: false - icon.source: "qrc:/icons/code.svg" - anchors.margins: (app.spacing * 1.5) - 5 - backgroundColor: Cpp_ThemeManager.paneWindowBackground - - Widgets.Terminal { - id: terminal - widgetEnabled: true - anchors.fill: parent - } } } diff --git a/app/qml/MainWindow/Panes/Dashboard.qml b/app/qml/MainWindow/Panes/Dashboard.qml index d15a7c87..c20abf48 100644 --- a/app/qml/MainWindow/Panes/Dashboard.qml +++ b/app/qml/MainWindow/Panes/Dashboard.qml @@ -24,98 +24,46 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../../Widgets" as Widgets import "../Dashboard" as DashboardItems -Item { +RowLayout { id: root + spacing: 0 // - // Main layout + // View options window // - ColumnLayout { - anchors.fill: parent - spacing: app.spacing - anchors.margins: (app.spacing * 1.5) - 5 + DashboardItems.ViewOptions { + Layout.fillHeight: true + Layout.minimumWidth: 280 + onColumnsChanged:(columns) => widgetGrid.columns = columns + } - // - // Widget selector + widgets - // - RowLayout { - spacing: app.spacing - Layout.fillWidth: true - Layout.fillHeight: true + // + // Panel border rectangle + // + Rectangle { + z: 2 + width: 1 + Layout.fillHeight: true + color: Cpp_ThemeManager.colors["setup_border"] - // - // View options window - // - DashboardItems.ViewOptions { - Layout.fillHeight: true - Layout.minimumWidth: 280 - onColumnsChanged:(columns) => widgetGrid.columns = columns - } - - // - // Widget grid + console - // - ColumnLayout { - spacing: terminalView.enabled ? app.spacing : 0 - - DashboardItems.WidgetGrid { - id: widgetGrid - Layout.fillWidth: true - Layout.fillHeight: true - Layout.minimumWidth: 240 - } - - - Item { - enabled: false - id: terminalView - Layout.fillWidth: true - Layout.fillHeight: false - Layout.maximumHeight: 280 - Layout.minimumHeight: 280 - visible: Layout.bottomMargin > -Layout.minimumHeight - Layout.bottomMargin: enabled ? 0 : -Layout.minimumHeight - - Behavior on Layout.bottomMargin { NumberAnimation{} } - - Widgets.Window { - id: terminal - gradient: true - anchors.fill: parent - title: qsTr("Console") - altButtonEnabled: true - headerDoubleClickEnabled: false - icon.source: "qrc:/icons/code.svg" - altButtonIcon.source: "qrc:/icons/scroll-down.svg" - backgroundColor: Cpp_ThemeManager.paneWindowBackground - onAltButtonClicked: { - terminalView.enabled = false - dbTitle.consoleChecked = false - } - - Widgets.Terminal { - anchors.fill: parent - widgetEnabled: terminalView.enabled - } - } - } - } - } - - // - // Dashboard title window - // - DashboardItems.DashboardTitle { - id: dbTitle + Rectangle { + width: 1 height: 32 - Layout.fillWidth: true - onConsoleCheckedChanged: { - if (terminalView.enabled != consoleChecked) - terminalView.enabled = consoleChecked - } + anchors.top: parent.top + anchors.left: parent.left + color: Cpp_ThemeManager.colors["pane_caption_border"] } } + + // + // Widget grid + // + DashboardItems.WidgetGrid { + id: widgetGrid + Layout.fillWidth: true + Layout.fillHeight: true + Layout.minimumWidth: 240 + } } diff --git a/app/qml/MainWindow/Panes/Setup.qml b/app/qml/MainWindow/Panes/Setup.qml index 0486f8bc..5dafe9b5 100644 --- a/app/qml/MainWindow/Panes/Setup.qml +++ b/app/qml/MainWindow/Panes/Setup.qml @@ -25,18 +25,20 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets import "SetupPanes" as SetupPanes +import "../../Widgets" as Widgets -Item { +Widgets.Pane { id: root + title: qsTr("Device Setup") + icon: "qrc:/icons/panes/setup.svg" // // Custom properties // property int setupMargin: 0 - property int displayedWidth: 380 + app.spacing * 1.5 - readonly property int maxItemWidth: column.width - 2 * spacing + property int displayedWidth: 344 + readonly property int maxItemWidth: column.width - 8 // // Displays the setup panel @@ -70,17 +72,6 @@ Item { property alias tabIndex: tab.currentIndex property alias csvExport: csvLogging.checked - // - // MQTT settings - // - property alias mqttHost: mqtt.host - property alias mqttPort: mqtt.port - property alias mqttUser: mqtt.user - property alias mqttMode: mqtt.mode - property alias mqttTopic: mqtt.topic - property alias mqttVersion: mqtt.version - property alias mqttPassword: mqtt.password - // // App settings // @@ -100,185 +91,163 @@ Item { } // - // Window + // Control arrangement // - Widgets.Window { - gradient: true - title: qsTr("Setup") + ColumnLayout { + id: column + spacing: 4 anchors.fill: parent - anchors.leftMargin: 0 - headerDoubleClickEnabled: false - icon.source: "qrc:/icons/settings.svg" - anchors.margins: (app.spacing * 1.5) - 5 - backgroundColor: Cpp_ThemeManager.paneWindowBackground + anchors.topMargin: -6 // - // Control arrangement + // Device type selector // - ColumnLayout { - id: column - anchors.fill: parent - spacing: app.spacing / 2 - anchors.margins: app.spacing * 1.5 + Label { + text: qsTr("Device Setup") + ":" + font: Cpp_Misc_CommonFonts.customUiFont(10, true) + color: Cpp_ThemeManager.colors["pane_section_label"] + Component.onCompleted: font.capitalization = Font.AllUppercase + } ComboBox { + id: _driverCombo + Layout.fillWidth: true + model: Cpp_IO_Manager.availableDrivers() + displayText: qsTr("I/O Interface: %1").arg(currentText) + onCurrentIndexChanged: Cpp_IO_Manager.selectedDriver = currentIndex + } - // - // Comm mode selector - // - Label { - text: qsTr("Communication Mode") + ":" - font: Cpp_Misc_CommonFonts.customUiFont(12, true) - } RadioButton { - id: commAuto - checked: true - Layout.maximumWidth: root.maxItemWidth - text: qsTr("No parsing (device sends JSON data)") - onCheckedChanged: { - if (checked) - Cpp_JSON_Generator.setOperationMode(1) - else - Cpp_JSON_Generator.setOperationMode(0) - } - } RadioButton { - id: commManual - checked: false - Layout.maximumWidth: root.maxItemWidth - text: qsTr("Parse via JSON project file") - onCheckedChanged: { - if (checked) - Cpp_JSON_Generator.setOperationMode(0) - else - Cpp_JSON_Generator.setOperationMode(1) - } + // + // CSV generator + // + Switch { + id: csvLogging + Layout.leftMargin: -6 + text: qsTr("Create CSV File") + Layout.alignment: Qt.AlignLeft + checked: Cpp_CSV_Export.exportEnabled + palette.highlight: Cpp_ThemeManager.colors["csv_switch"] + + onCheckedChanged: { + if (Cpp_CSV_Export.exportEnabled !== checked) + Cpp_CSV_Export.exportEnabled = checked + } + } + + // + // Spacer + // + Item { + height: 4 + } + + // + // Comm mode selector + // + Label { + text: qsTr("Frame Parsing") + ":" + font: Cpp_Misc_CommonFonts.customUiFont(10, true) + color: Cpp_ThemeManager.colors["pane_section_label"] + Component.onCompleted: font.capitalization = Font.AllUppercase + } RadioButton { + id: commAuto + Layout.maximumHeight: 18 + Layout.maximumWidth: root.maxItemWidth + checked: Cpp_JSON_Generator.operationMode === 1 + text: qsTr("No Parsing (Device Sends JSON Data)") + onCheckedChanged: { + if (checked && Cpp_JSON_Generator.operationMode !== 1) + Cpp_JSON_Generator.setOperationMode(1) + else if (!checked) + Cpp_JSON_Generator.setOperationMode(0) + } + } RadioButton { + id: commManual + Layout.maximumHeight: 18 + Layout.maximumWidth: root.maxItemWidth + text: qsTr("Parse via JSON Project File") + checked: Cpp_JSON_Generator.operationMode === 0 + onCheckedChanged: { + if (checked && Cpp_JSON_Generator.operationMode !== 0) + Cpp_JSON_Generator.setOperationMode(0) + else if (!checked) + Cpp_JSON_Generator.setOperationMode(1) + } + } + + // + // Map file selector button + // + Button { + Layout.fillWidth: true + opacity: enabled ? 1 : 0.5 + enabled: commManual.checked + Layout.maximumWidth: root.maxItemWidth + onClicked: Cpp_JSON_Generator.loadJsonMap() + text: (Cpp_JSON_Generator.jsonMapFilename.length ? + qsTr("Change Project File (%1)").arg(Cpp_JSON_Generator.jsonMapFilename) : + qsTr("Select Project File") + "...") + } + + // + // Spacer + // + Item { + height: 4 + } + + // + // Tab bar + // + TabBar { + height: 24 + id: tab + Layout.fillWidth: true + Layout.maximumWidth: root.maxItemWidth + + TabButton { + text: qsTr("Device") + height: tab.height + 3 + width: implicitWidth + 2 * 8 } - // - // Map file selector button - // - Button { - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - enabled: commManual.checked - Layout.maximumWidth: root.maxItemWidth - onClicked: Cpp_JSON_Generator.loadJsonMap() - text: (Cpp_JSON_Generator.jsonMapFilename.length ? qsTr("Change project file (%1)").arg(Cpp_JSON_Generator.jsonMapFilename) : - qsTr("Select project file") + "...") + TabButton { + text: qsTr("Settings") + height: tab.height + 3 + width: implicitWidth + 2 * 8 } + } - // - // Spacer - // - Item { - height: app.spacing / 2 - } + // + // Tab bar contents + // + StackLayout { + id: stack + clip: true + Layout.fillWidth: true + Layout.fillHeight: true + currentIndex: tab.currentIndex + Layout.topMargin: -parent.spacing - 1 - // - // Enable/disable CSV logging - // - RowLayout { - Layout.fillWidth: true - - Switch { - id: csvLogging - text: qsTr("Create CSV file") - Layout.alignment: Qt.AlignVCenter - checked: Cpp_CSV_Export.exportEnabled - Layout.maximumWidth: root.maxItemWidth - palette.highlight: Cpp_ThemeManager.csvCheckbox - - onCheckedChanged: { - if (Cpp_CSV_Export.exportEnabled !== checked) - Cpp_CSV_Export.exportEnabled = checked - } - } - - Item { - Layout.fillWidth: true - } - - RoundButton { - icon.width: 24 - icon.height: 24 - icon.color: Cpp_ThemeManager.text - Layout.alignment: Qt.AlignVCenter - icon.source: "qrc:/icons/help.svg" - onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki") - } - } - - // - // Spacer - // - Item { - height: app.spacing / 2 - } - - // - // Tab bar - // - TabBar { - height: 24 - id: tab - Layout.fillWidth: true - Layout.maximumWidth: root.maxItemWidth - - TabButton { - text: qsTr("Device") - height: tab.height + 3 - width: implicitWidth + 2 * app.spacing - } - - TabButton { - text: qsTr("MQTT") - height: tab.height + 3 - width: implicitWidth + 2 * app.spacing - } - - TabButton { - text: qsTr("Settings") - height: tab.height + 3 - width: implicitWidth + 2 * app.spacing - } - } - - // - // Tab bar contents - // - StackLayout { - id: stack - clip: true + SetupPanes.Hardware { + id: hardware Layout.fillWidth: true Layout.fillHeight: true - currentIndex: tab.currentIndex - Layout.topMargin: -parent.spacing - 1 - - SetupPanes.Hardware { - id: hardware - Layout.fillWidth: true - Layout.fillHeight: true - background: TextField { - enabled: false - palette.base: Cpp_ThemeManager.setupPanelBackground - } + background: Rectangle { + radius: 2 + border.width: 1 + color: Cpp_ThemeManager.colors["groupbox_background"] + border.color: Cpp_ThemeManager.colors["groupbox_border"] } + } - SetupPanes.MQTT { - id: mqtt - Layout.fillWidth: true - Layout.fillHeight: true - background: TextField { - enabled: false - palette.base: Cpp_ThemeManager.setupPanelBackground - } - } - - SetupPanes.Settings { - id: settings - Layout.fillWidth: true - Layout.fillHeight: true - background: TextField { - enabled: false - palette.base: Cpp_ThemeManager.setupPanelBackground - } + SetupPanes.Settings { + id: settings + Layout.fillWidth: true + Layout.fillHeight: true + background: Rectangle { + radius: 2 + border.width: 1 + color: Cpp_ThemeManager.colors["groupbox_background"] + border.color: Cpp_ThemeManager.colors["groupbox_border"] } } } diff --git a/app/qml/MainWindow/Panes/SetupPanes/Devices/BluetoothLE.qml b/app/qml/MainWindow/Panes/SetupPanes/Devices/BluetoothLE.qml index 0e474aff..c502a7b5 100644 --- a/app/qml/MainWindow/Panes/SetupPanes/Devices/BluetoothLE.qml +++ b/app/qml/MainWindow/Panes/SetupPanes/Devices/BluetoothLE.qml @@ -24,7 +24,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -Control { +Item { id: root // @@ -42,15 +42,15 @@ Control { // ColumnLayout { id: layout - spacing: app.spacing + spacing: 4 + anchors.margins: 0 anchors.fill: parent - anchors.margins: app.spacing // // Device selector + refresh button // RowLayout { - spacing: app.spacing + spacing: 4 visible: opacity > 0 opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && Cpp_IO_Bluetooth_LE.deviceCount > 0 ? 1 : 0 @@ -93,7 +93,7 @@ Control { // Service selector // RowLayout { - spacing: app.spacing + spacing: 4 visible: opacity > 0 opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && serviceNames.count > 1 ? 1 : 0 @@ -116,7 +116,7 @@ Control { // Scanning indicator // RowLayout { - spacing: app.spacing + spacing: 4 visible: opacity > 0 opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && Cpp_IO_Bluetooth_LE.deviceCount < 1 ? 1 : 0 @@ -138,7 +138,7 @@ Control { // OS not supported indicator // RowLayout { - spacing: app.spacing + spacing: 4 visible: opacity > 0 opacity: !Cpp_IO_Bluetooth_LE.operatingSystemSupported @@ -156,9 +156,9 @@ Control { Layout.fillWidth: true wrapMode: Label.WordWrap Layout.alignment: Qt.AlignVCenter - text: qsTr("Sorry, this version of %1 is not supported yet. " + + text: qsTr("Sorry, this system is not supported yet. " + "We'll update Serial Studio to work with this operating " + - "system as soon as Qt officially supports it.").arg(Cpp_OSName); + "system as soon as Qt officially supports it.") } } diff --git a/app/qml/MainWindow/Panes/SetupPanes/Devices/Network.qml b/app/qml/MainWindow/Panes/SetupPanes/Devices/Network.qml index 7b6bbb9a..f2541535 100644 --- a/app/qml/MainWindow/Panes/SetupPanes/Devices/Network.qml +++ b/app/qml/MainWindow/Panes/SetupPanes/Devices/Network.qml @@ -24,7 +24,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -Control { +Item { id: root // @@ -66,14 +66,14 @@ Control { // ColumnLayout { id: layout + anchors.margins: 0 anchors.fill: parent - anchors.margins: app.spacing GridLayout { columns: 2 + rowSpacing: 4 + columnSpacing: 4 Layout.fillWidth: true - rowSpacing: app.spacing / 2 - columnSpacing: app.spacing / 2 // // Socket type @@ -229,7 +229,7 @@ Control { id: _udpMulticast opacity: enabled ? 1 : 0.5 Layout.alignment: Qt.AlignLeft - Layout.leftMargin: -app.spacing + Layout.leftMargin: -8 checked: Cpp_IO_Network.udpMulticast visible: Cpp_IO_Network.socketTypeIndex === 1 palette.base: Cpp_ThemeManager.setupPanelBackground @@ -252,7 +252,7 @@ Control { id: _udpProcessDatagrams opacity: enabled ? 1 : 0.5 Layout.alignment: Qt.AlignLeft - Layout.leftMargin: -app.spacing + Layout.leftMargin: -8 visible: Cpp_IO_Network.socketTypeIndex === 1 checked: Cpp_IO_Network.udpIgnoreFrameSequences palette.base: Cpp_ThemeManager.setupPanelBackground @@ -265,14 +265,6 @@ Control { } } - // - // Spacer - // - Item { - Layout.fillHeight: true - Layout.minimumHeight: app.spacing - } - // // Spacer // diff --git a/app/qml/MainWindow/Panes/SetupPanes/Devices/Serial.qml b/app/qml/MainWindow/Panes/SetupPanes/Devices/Serial.qml index 6b29283f..30afb3cc 100644 --- a/app/qml/MainWindow/Panes/SetupPanes/Devices/Serial.qml +++ b/app/qml/MainWindow/Panes/SetupPanes/Devices/Serial.qml @@ -24,7 +24,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -Control { +Item { id: root // @@ -62,10 +62,10 @@ Control { GridLayout { id: layout columns: 2 + rowSpacing: 4 + columnSpacing: 4 + anchors.margins: 0 anchors.fill: parent - anchors.margins: app.spacing - rowSpacing: app.spacing / 2 - columnSpacing: app.spacing / 2 // // COM port selector @@ -121,58 +121,11 @@ Control { // Spacer // Item { - Layout.minimumHeight: app.spacing / 2 - Layout.maximumHeight: app.spacing / 2 + Layout.minimumHeight: 8 / 2 + Layout.maximumHeight: 8 / 2 } Item { - Layout.minimumHeight: app.spacing / 2 - Layout.maximumHeight: app.spacing / 2 - } - - // - // Auto-reconnect - // - Label { - text: qsTr("Auto-reconnect") + ":" - } CheckBox { - id: _autoreconnect - Layout.maximumHeight: 18 - Layout.leftMargin: -app.spacing - checked: Cpp_IO_Serial.autoReconnect - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - palette.base: Cpp_ThemeManager.setupPanelBackground - onCheckedChanged: { - if (Cpp_IO_Serial.autoReconnect !== checked) - Cpp_IO_Serial.autoReconnect = checked - } - } - - // - // DTR Signal - // - Label { - text: qsTr("Send DTR Signal") + ":" - } CheckBox { - id: _dtr - Layout.maximumHeight: 18 - Layout.leftMargin: -app.spacing - checked: Cpp_IO_Serial.dtrEnabled - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - palette.base: Cpp_ThemeManager.setupPanelBackground - onCheckedChanged: { - if (Cpp_IO_Serial.dtrEnabled !== checked) - Cpp_IO_Serial.dtrEnabled = checked - } - } - - // - // Spacer - // - Item { - Layout.minimumHeight: app.spacing / 2 - Layout.maximumHeight: app.spacing / 2 - } Item { - Layout.minimumHeight: app.spacing / 2 - Layout.maximumHeight: app.spacing / 2 + Layout.minimumHeight: 8 / 2 + Layout.maximumHeight: 8 / 2 } // @@ -243,6 +196,53 @@ Control { } } + // + // Spacer + // + Item { + Layout.minimumHeight: 8 / 2 + Layout.maximumHeight: 8 / 2 + } Item { + Layout.minimumHeight: 8 / 2 + Layout.maximumHeight: 8 / 2 + } + + // + // Auto-reconnect + // + Label { + text: qsTr("Auto Reconnect") + ":" + } CheckBox { + id: _autoreconnect + Layout.maximumHeight: 18 + Layout.leftMargin: -8 + checked: Cpp_IO_Serial.autoReconnect + Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter + palette.base: Cpp_ThemeManager.setupPanelBackground + onCheckedChanged: { + if (Cpp_IO_Serial.autoReconnect !== checked) + Cpp_IO_Serial.autoReconnect = checked + } + } + + // + // DTR Signal + // + Label { + text: qsTr("Send DTR Signal") + ":" + } CheckBox { + id: _dtr + Layout.maximumHeight: 18 + Layout.leftMargin: -8 + checked: Cpp_IO_Serial.dtrEnabled + Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter + palette.base: Cpp_ThemeManager.setupPanelBackground + onCheckedChanged: { + if (Cpp_IO_Serial.dtrEnabled !== checked) + Cpp_IO_Serial.dtrEnabled = checked + } + } + // // Vertical spacer // diff --git a/app/qml/MainWindow/Panes/SetupPanes/Hardware.qml b/app/qml/MainWindow/Panes/SetupPanes/Hardware.qml index abaacf73..c610c1ce 100644 --- a/app/qml/MainWindow/Panes/SetupPanes/Hardware.qml +++ b/app/qml/MainWindow/Panes/SetupPanes/Hardware.qml @@ -26,7 +26,6 @@ import QtQuick.Controls import QtCore as QtSettings import "Devices" as Devices -import "../../Windows" as Windows Control { id: root @@ -35,8 +34,6 @@ Control { // Save settings // QtSettings.Settings { - property alias driver: _driverCombo.currentIndex - property alias dtr: serial.dtr property alias parity: serial.parity property alias baudRate: serial.baudRate @@ -56,29 +53,9 @@ Control { ColumnLayout { id: layout + spacing: 4 + anchors.margins: 8 anchors.fill: parent - anchors.margins: app.spacing - - // - // Device type selector - // - RowLayout { - spacing: app.spacing - Layout.fillWidth: true - - Label { - text: qsTr("Data source") + ":" - Layout.alignment: Qt.AlignVCenter - } - - ComboBox { - id: _driverCombo - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter - model: Cpp_IO_Manager.availableDrivers() - onCurrentIndexChanged: Cpp_IO_Manager.selectedDriver = currentIndex - } - } // // Device configuration @@ -94,27 +71,18 @@ Control { id: serial Layout.fillWidth: true Layout.fillHeight: true - background: TextField { - enabled: false - } } Devices.Network { id: network Layout.fillWidth: true Layout.fillHeight: true - background: TextField { - enabled: false - } } Devices.BluetoothLE { id: bluetoothLE Layout.fillWidth: true Layout.fillHeight: true - background: TextField { - enabled: false - } } } } diff --git a/app/qml/MainWindow/Panes/SetupPanes/MQTT.qml b/app/qml/MainWindow/Panes/SetupPanes/MQTT.qml deleted file mode 100644 index 61d3d0ac..00000000 --- a/app/qml/MainWindow/Panes/SetupPanes/MQTT.qml +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2020-2023 Alex Spataru - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls - -import "../../Windows" as Windows - -Control { - id: root - - // - // Aliases - // - property alias host: _host.text - property alias port: _port.text - property alias topic: _topic.text - property alias user: _user.text - property alias password: _password.text - property alias version: _version.currentIndex - property alias mode: _mode.currentIndex - - // - // React to events from MQTT module - // - Connections { - target: Cpp_MQTT_Client - - function onHostChanged() { - if (_host.text.length > 0) - _host.text = Cpp_MQTT_Client.host - } - - function onPortChanged() { - if (_port.text.length > 0) - _port.text = Cpp_MQTT_Client.port - } - } - - // - // Layout - // - ColumnLayout { - id: layout - anchors.fill: parent - anchors.margins: app.spacing - - GridLayout { - columns: 2 - Layout.fillWidth: true - rowSpacing: app.spacing / 2 - columnSpacing: app.spacing / 2 - - // - // MQTT version - // - Label { - text: qsTr("Version") + ":" - } ComboBox { - id: _version - Layout.fillWidth: true - model: Cpp_MQTT_Client.mqttVersions - currentIndex: Cpp_MQTT_Client.mqttVersion - onCurrentIndexChanged: { - if (Cpp_MQTT_Client.mqttVersion !== currentIndex) - Cpp_MQTT_Client.mqttVersion = currentIndex - } - } - - // - // Client mode version - // - Label { - text: qsTr("Mode") + ":" - } ComboBox { - id: _mode - Layout.fillWidth: true - model: Cpp_MQTT_Client.clientModes - currentIndex: Cpp_MQTT_Client.clientMode - onCurrentIndexChanged: { - if (Cpp_MQTT_Client.clientMode !== currentIndex) - Cpp_MQTT_Client.clientMode = currentIndex - } - } - - // - // Host - // - Label { - text: qsTr("Host") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } TextField { - id: _host - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - placeholderText: Cpp_MQTT_Client.defaultHost - Component.onCompleted: text = Cpp_MQTT_Client.host - - onTextChanged: { - if (Cpp_MQTT_Client.host !== text && text.length > 0) - Cpp_MQTT_Client.host = text - - if (text.length === 0) - Cpp_MQTT_Client.host = Cpp_MQTT_Client.defaultHost - } - } - - // - // Port - // - Label { - text: qsTr("Port") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } TextField { - id: _port - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - placeholderText: Cpp_MQTT_Client.defaultPort - Component.onCompleted: text = Cpp_MQTT_Client.port - onTextChanged: { - if (Cpp_MQTT_Client.port !== text && text.length > 0) - Cpp_MQTT_Client.port = text - - if (text.length === 0) - Cpp_MQTT_Client.port = Cpp_MQTT_Client.defaultPort - } - - validator: IntValidator { - bottom: 0 - top: 65535 - } - } - - // - // Topic - // - Label { - text: qsTr("Topic") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } TextField { - id: _topic - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - text: Cpp_MQTT_Client.topic - placeholderText: qsTr("MQTT topic") - enabled: !Cpp_MQTT_Client.isConnectedToHost - - onTextChanged: { - if (Cpp_MQTT_Client.topic !== text) - Cpp_MQTT_Client.topic = text - } - } - - // - // Username - // - Label { - text: qsTr("User") + ":" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_MQTT_Client.isConnectedToHost - } TextField { - id: _user - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - text: Cpp_MQTT_Client.username - placeholderText: qsTr("MQTT username") - enabled: !Cpp_MQTT_Client.isConnectedToHost - - onTextChanged: { - if (Cpp_MQTT_Client.username !== text) - Cpp_MQTT_Client.username = text - } - } - - // - // Password - // - Label { - opacity: enabled ? 1 : 0.5 - text: qsTr("Password") + ":" - enabled: !Cpp_MQTT_Client.isConnectedToHost - } RowLayout { - Layout.fillWidth: true - spacing: app.spacing / 2 - - TextField { - id: _password - Layout.fillWidth: true - opacity: enabled ? 1 : 0.5 - echoMode: TextField.Password - text: Cpp_MQTT_Client.password - placeholderText: qsTr("MQTT password") - enabled: !Cpp_MQTT_Client.isConnectedToHost - - onTextChanged: { - if (Cpp_MQTT_Client.password !== text) - Cpp_MQTT_Client.password = text - } - } - - Button { - checkable: true - icon.color: palette.text - Layout.maximumWidth: height - Layout.alignment: Qt.AlignVCenter - icon.source: "qrc:/icons/visibility.svg" - onCheckedChanged: _password.echoMode = (checked ? TextField.Normal : - TextField.Password) - } - } - } - - // - // Spacer - // - Item { - Layout.fillHeight: true - Layout.minimumHeight: app.spacing - } - - // - // Advanced setup & connect/disconnect button - // - RowLayout { - spacing: app.spacing - Layout.fillWidth: true - - Button { - icon.width: 24 - icon.height: 24 - Layout.fillWidth: true - onClicked: mqttSetup.show() - icon.color: palette.buttonText - text: qsTr("Advanced setup") + " " - icon.source: "qrc:/icons/settings.svg" - } - - Button { - icon.width: 24 - icon.height: 24 - font.bold: true - Layout.fillWidth: true - icon.color: Cpp_ThemeManager.mqttButton - checked: Cpp_MQTT_Client.isConnectedToHost - palette.buttonText: Cpp_ThemeManager.mqttButton - onClicked: Cpp_MQTT_Client.toggleConnection() - text: (checked ? qsTr("Disconnect") : - qsTr("Connect to broker")) + " " - icon.source: checked ? "qrc:/icons/disconnect.svg" : - "qrc:/icons/connect.svg" - } - } - } - - // - // MQTT setup dialog - // - Windows.MQTTConfiguration { - id: mqttSetup - } -} diff --git a/app/qml/MainWindow/Panes/SetupPanes/Settings.qml b/app/qml/MainWindow/Panes/SetupPanes/Settings.qml index 3d014e9a..e4c29d0b 100644 --- a/app/qml/MainWindow/Panes/SetupPanes/Settings.qml +++ b/app/qml/MainWindow/Panes/SetupPanes/Settings.qml @@ -39,7 +39,7 @@ Control { ColumnLayout { id: layout anchors.fill: parent - anchors.margins: app.spacing + anchors.margins: 8 // // Controls @@ -47,8 +47,8 @@ Control { GridLayout { columns: 2 Layout.fillWidth: true - rowSpacing: app.spacing / 2 - columnSpacing: app.spacing / 2 + rowSpacing: 8 / 2 + columnSpacing: 8 / 2 // // Language selector @@ -74,10 +74,10 @@ Control { } ComboBox { id: _themeCombo Layout.fillWidth: true + currentIndex: Cpp_ThemeManager.theme model: Cpp_ThemeManager.availableThemes - currentIndex: Cpp_ThemeManager.themeId onCurrentIndexChanged: { - if (currentIndex !== Cpp_ThemeManager.themeId) + if (currentIndex !== Cpp_ThemeManager.theme) Cpp_ThemeManager.setTheme(currentIndex) } } @@ -86,12 +86,13 @@ Control { // Plugins enabled // Label { - text: qsTr("Plugin system") + ": " + text: qsTr("Plugin System") + ": " } Switch { id: _tcpPlugins - Layout.leftMargin: -app.spacing + Layout.leftMargin: -8 Layout.alignment: Qt.AlignLeft checked: Cpp_Plugins_Bridge.enabled + palette.highlight: Cpp_ThemeManager.colors["switch_highlight"] onCheckedChanged: { if (checked !== Cpp_Plugins_Bridge.enabled) Cpp_Plugins_Bridge.enabled = checked @@ -99,17 +100,71 @@ Control { } } + // + // Vertical spacer + // + Item { + Layout.fillHeight: true + } + // // Plugins label // - Label { - opacity: 0.8 - font.pixelSize: 12 - Layout.fillWidth: true - wrapMode: Label.WrapAtWordBoundaryOrAnywhere - color: Cpp_ThemeManager.highlightedTextAlternative - text: qsTr("Applications/plugins can interact with %1 by " + - "establishing a TCP connection on port 7777.").arg(Cpp_AppName) + RowLayout { + spacing: 8 + + Image { + sourceSize: Qt.size(48, 48) + source: "qrc:/images/tip.svg" + Layout.alignment: Qt.AlignVCenter + } + + Label { + opacity: 0.6 + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + wrapMode: Label.WrapAtWordBoundaryOrAnywhere + text: qsTr("Using the plugin system, other applications \& scripts can " + + "interact with %1 by establishing a TCP connection on port " + + "7777.").arg(Cpp_AppName) + } + + Item { + Layout.minimumWidth: 16 + } + } + + // + // Spacer + // + Item { + Layout.minimumHeight: 16 + } + + // + // Examples label + // + RowLayout { + spacing: 8 + + Image { + sourceSize: Qt.size(48, 48) + source: "qrc:/images/code.svg" + Layout.alignment: Qt.AlignVCenter + } + + Label { + opacity: 0.6 + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + wrapMode: Label.WrapAtWordBoundaryOrAnywhere + text: qsTr("Reproducible test cases and examples in the wiki make use " + + "of a Python script that acts as a %1 plugin.").arg(Cpp_AppName) + } + + Item { + Layout.minimumWidth: 16 + } } // diff --git a/app/qml/MainWindow/Panes/Toolbar.qml b/app/qml/MainWindow/Panes/Toolbar.qml index b5a07c1a..7d34f5f1 100644 --- a/app/qml/MainWindow/Panes/Toolbar.qml +++ b/app/qml/MainWindow/Panes/Toolbar.qml @@ -27,19 +27,8 @@ import QtQuick.Controls import "../../Widgets" as Widgets -Control { +ToolBar { id: root - implicitHeight: 76 - - // - // Reference to parent window to be able to drag it with the toolbar - // - property Window window - - // - // Dummy string to increase width of buttons - // - readonly property string _btSpacer: " " // // Custom signals @@ -57,29 +46,57 @@ Control { property alias dashboardChecked: dashboardBt.checked // - // Background gradient + border + // Calculate offset based on platform // - Rectangle { - id: bg - anchors.fill: parent - - gradient: Gradient { - GradientStop { position: 0; color: Cpp_ThemeManager.toolbarGradient1 } - GradientStop { position: 1; color: Cpp_ThemeManager.toolbarGradient2 } + property int titlebarHeight: Cpp_NativeWindow.titlebarHeight(mainWindow) + Connections { + target: mainWindow + function onVisibilityChanged() { + root.titlebarHeight = Cpp_NativeWindow.titlebarHeight(mainWindow) } + } - Rectangle { - border.width: 1 - anchors.fill: parent - color: "transparent" - visible: Cpp_ThemeManager.titlebarSeparator - border.color: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5) + // + // Set toolbar height + // + Layout.minimumHeight: titlebarHeight + 76 + Layout.maximumHeight: titlebarHeight + 76 + + // + // Titlebar text + // + Label { + text: mainWindow.title + visible: root.titlebarHeight > 0 + color: Cpp_ThemeManager.colors["titlebar_text"] + font: Cpp_Misc_CommonFonts.customUiFont(13, true) + + anchors { + topMargin: 6 + top: parent.top + horizontalCenter: parent.horizontalCenter + } + } + + // + // Toolbar background + // + background: Rectangle { + gradient: Gradient { + GradientStop { + position: 0 + color: Cpp_ThemeManager.colors["toolbar_top"] + } + + GradientStop { + position: 1 + color: Cpp_ThemeManager.colors["toolbar_bottom"] + } } Rectangle { height: 1 - visible: Cpp_ThemeManager.titlebarSeparator - color: Qt.darker(Cpp_ThemeManager.toolbarGradient1, 1.5) + color: Cpp_ThemeManager.colors["toolbar_border"] anchors { left: parent.left @@ -87,33 +104,49 @@ Control { bottom: parent.bottom } } + + DragHandler { + target: null + onActiveChanged: { + if (active) + mainWindow.startSystemMove() + } + } } // - // Toolbar icons + // Toolbar controls // RowLayout { - spacing: app.spacing - anchors.fill: parent - anchors.margins: app.spacing + spacing: 8 - Button { - flat: true - icon.width: 27 - icon.height: 27 - Layout.fillHeight: true - icon.color: "transparent" + anchors { + margins: 2 + left: parent.left + right: parent.right + verticalCenter: parent.verticalCenter + verticalCenterOffset: root.titlebarHeight / 2 + } + + // + // Project Editor + // + Widgets.BigButton { text: qsTr("Project Setup") - display: AbstractButton.TextUnderIcon - onClicked: root.projectEditorClicked() - Layout.minimumWidth: Math.max(implicitWidth, 81) - Layout.maximumWidth: Math.max(implicitWidth, 81) - palette.buttonText: Cpp_ThemeManager.menubarText - palette.button: Cpp_ThemeManager.toolbarGradient1 - palette.window: Cpp_ThemeManager.toolbarGradient1 - icon.source: "qrc:/toolbar-icons/project-editor.svg" + Layout.alignment: Qt.AlignVCenter + onClicked: app.showProjectEditor() + enabled: Cpp_JSON_Generator.operationMode == 0 + icon.source: "qrc:/icons/toolbar/project-setup.svg" + } - background: Item {} + // + // CSV Player + // + Widgets.BigButton { + text: qsTr("CSV Player") + Layout.alignment: Qt.AlignVCenter + onClicked: Cpp_CSV_Player.openFile() + icon.source: "qrc:/icons/toolbar/csv.svg" } // @@ -121,122 +154,46 @@ Control { // Rectangle { width: 1 - opacity: 0.2 Layout.fillHeight: true Layout.maximumHeight: 64 Layout.alignment: Qt.AlignVCenter - color: Cpp_ThemeManager.menubarText + color: Cpp_ThemeManager.colors["toolbar_separator"] } - Button { - id: setupBt - - flat: true - icon.width: 27 - icon.height: 27 - text: qsTr("Settings") - Layout.fillHeight: true - icon.color: "transparent" - onClicked: root.setupClicked() - display: AbstractButton.TextUnderIcon - icon.source: "qrc:/toolbar-icons/setup.svg" - Layout.minimumWidth: Math.max(implicitWidth, 81) - Layout.maximumWidth: Math.max(implicitWidth, 81) - palette.buttonText: Cpp_ThemeManager.menubarText - palette.button: Cpp_ThemeManager.toolbarGradient1 - palette.window: Cpp_ThemeManager.toolbarGradient1 - - background: Rectangle { - radius: 3 - border.width: 1 - color: "transparent" - border.color: "#040600" - opacity: parent.checked ? 0.2 : 0.0 - - Rectangle { - border.width: 1 - color: "#626262" - anchors.fill: parent - border.color: "#c2c2c2" - radius: parent.radius - 1 - anchors.margins: parent.border.width - } - } - } - - Button { + // + // Console + // + Widgets.BigButton { id: consoleBt - - flat: true - icon.width: 27 - icon.height: 27 - Layout.fillHeight: true - icon.color: "transparent" + opacity: 1 + text: qsTr("Console") enabled: dashboardBt.enabled onClicked: root.consoleClicked() - text: qsTr("Console") - display: AbstractButton.TextUnderIcon - icon.source: "qrc:/toolbar-icons/console.svg" - Layout.minimumWidth: Math.max(implicitWidth, 81) - Layout.maximumWidth: Math.max(implicitWidth, 81) - palette.buttonText: Cpp_ThemeManager.menubarText - palette.button: Cpp_ThemeManager.toolbarGradient1 - palette.window: Cpp_ThemeManager.toolbarGradient1 - - background: Rectangle { - radius: 3 - border.width: 1 - color: "transparent" - border.color: "#040600" - opacity: parent.checked ? 0.2 : 0.0 - - Rectangle { - border.width: 1 - color: "#626262" - anchors.fill: parent - border.color: "#c2c2c2" - radius: parent.radius - 1 - anchors.margins: parent.border.width - } - } + Layout.alignment: Qt.AlignVCenter + icon.source: "qrc:/icons/toolbar/console.svg" } - Button { + // + // Setup + // + Widgets.BigButton { + id: setupBt + text: qsTr("Device Setup") + onClicked: root.setupClicked() + Layout.alignment: Qt.AlignVCenter + icon.source: "qrc:/icons/toolbar/device-setup.svg" + } + + // + // Dashboard + // + Widgets.BigButton { id: dashboardBt - - flat: true - icon.width: 27 - icon.height: 27 - Layout.fillHeight: true - icon.color: "transparent" - opacity: enabled ? 1 : 0.5 - onClicked: root.dashboardClicked() - enabled: Cpp_UI_Dashboard.available text: qsTr("Dashboard") - display: AbstractButton.TextUnderIcon - icon.source: "qrc:/toolbar-icons/dashboard.svg" - Layout.minimumWidth: Math.max(implicitWidth, 81) - Layout.maximumWidth: Math.max(implicitWidth, 81) - palette.buttonText: Cpp_ThemeManager.menubarText - palette.button: Cpp_ThemeManager.toolbarGradient1 - palette.window: Cpp_ThemeManager.toolbarGradient1 - - background: Rectangle { - radius: 3 - border.width: 1 - color: "transparent" - border.color: "#040600" - opacity: parent.checked ? 0.2 : 0.0 - - Rectangle { - border.width: 1 - color: "#626262" - anchors.fill: parent - border.color: "#c2c2c2" - radius: parent.radius - 1 - anchors.margins: parent.border.width - } - } + onClicked: root.dashboardClicked() + Layout.alignment: Qt.AlignVCenter + enabled: Cpp_UI_Dashboard.available + icon.source: "qrc:/icons/toolbar/dashboard.svg" } // @@ -244,124 +201,85 @@ Control { // Rectangle { width: 1 - opacity: 0.2 Layout.fillHeight: true Layout.maximumHeight: 64 Layout.alignment: Qt.AlignVCenter - color: Cpp_ThemeManager.menubarText - } - - Button { - flat: true - icon.width: 27 - icon.height: 27 - Layout.fillHeight: true - icon.color: "transparent" - text: qsTr("Help") - display: AbstractButton.TextUnderIcon - Layout.minimumWidth: Math.max(implicitWidth, 81) - Layout.maximumWidth: Math.max(implicitWidth, 81) - palette.buttonText: Cpp_ThemeManager.menubarText - palette.button: Cpp_ThemeManager.toolbarGradient1 - palette.window: Cpp_ThemeManager.toolbarGradient1 - icon.source: "qrc:/toolbar-icons/help.svg" - - background: Item {} - } - - Button { - flat: true - icon.width: 27 - icon.height: 27 - Layout.fillHeight: true - icon.color: "transparent" - text: qsTr("Report Bug") - display: AbstractButton.TextUnderIcon - Layout.minimumWidth: Math.max(implicitWidth, 81) - Layout.maximumWidth: Math.max(implicitWidth, 81) - palette.buttonText: Cpp_ThemeManager.menubarText - palette.button: Cpp_ThemeManager.toolbarGradient1 - palette.window: Cpp_ThemeManager.toolbarGradient1 - icon.source: "qrc:/toolbar-icons/bug.svg" - - background: Item {} + color: Cpp_ThemeManager.colors["toolbar_separator"] } // - // Window drag handler + // MQTT Setup + // + Widgets.BigButton { + text: qsTr("MQTT Setup") + Layout.alignment: Qt.AlignVCenter + onClicked: app.showMqttConfiguration() + icon.source: "qrc:/icons/toolbar/mqtt.svg" + } + + // + // Separator + // + Rectangle { + width: 1 + Layout.fillHeight: true + Layout.maximumHeight: 64 + Layout.alignment: Qt.AlignVCenter + color: Cpp_ThemeManager.colors["toolbar_separator"] + } + + // + // Report Bug + // + Widgets.BigButton { + text: qsTr("Report Bug") + Layout.alignment: Qt.AlignVCenter + icon.source: "qrc:/icons/toolbar/github.svg" + onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/issues") + } + + // + // Help + // + Widgets.BigButton { + text: qsTr("Help") + Layout.alignment: Qt.AlignVCenter + icon.source: "qrc:/icons/toolbar/help.svg" + onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki") + } + + // + // Help + // + Widgets.BigButton { + text: qsTr("About") + onClicked: app.showAboutDialog() + Layout.alignment: Qt.AlignVCenter + icon.source: "qrc:/icons/toolbar/about.svg" + } + + // + // Horizontal spacer // Item { - height: parent.height Layout.fillWidth: true - - MouseArea { - anchors.fill: parent - onPressedChanged: { - if (pressed) - window.startSystemMove() - } - } } - Button { - flat: true - icon.width: 27 - icon.height: 27 - Layout.fillHeight: true - icon.color: "transparent" - opacity: enabled ? 1 : 0.5 - enabled: !Cpp_CSV_Player.isOpen - text: qsTr("Open CSV") - display: AbstractButton.TextUnderIcon - icon.source: "qrc:/toolbar-icons/csv.svg" - Layout.minimumWidth: Math.max(implicitWidth, 81) - Layout.maximumWidth: Math.max(implicitWidth, 81) - palette.buttonText: Cpp_ThemeManager.menubarText - palette.button: Cpp_ThemeManager.toolbarGradient1 - palette.window: Cpp_ThemeManager.toolbarGradient1 - - onClicked: { - if (Cpp_CSV_Export.isOpen) - Cpp_CSV_Export.openCurrentCsv() - else - Cpp_CSV_Player.openFile() - } - - background: Item{} - } - - Button { - id: connectBt - - // - // Button properties - // - flat: true - icon.width: 27 - icon.height: 27 - Layout.fillHeight: true - font: Cpp_Misc_CommonFonts.customUiFont(12, true) - - // - // Connection-dependent - // - icon.color: "transparent" + // + // Connect/Disconnect button + // + Widgets.BigButton { checked: Cpp_IO_Manager.connected - display: AbstractButton.TextUnderIcon - Layout.minimumWidth: Math.max(implicitWidth, 81) - Layout.maximumWidth: Math.max(implicitWidth, 81) - palette.buttonText: Cpp_ThemeManager.menubarText - palette.button: Cpp_ThemeManager.toolbarGradient1 - palette.window: Cpp_ThemeManager.toolbarGradient1 - text: (checked ? qsTr("Disconnect") : qsTr("Connect")) - icon.source: checked ? "qrc:/toolbar-icons/disconnect.svg" : - "qrc:/toolbar-icons/connect.svg" - - // - // Only enable button if it can be clicked - // - opacity: enabled ? 1 : 0.5 + Layout.alignment: Qt.AlignVCenter + font: Cpp_Misc_CommonFonts.boldUiFont + Layout.minimumWidth: metrics.width + 32 + Layout.maximumWidth: metrics.width + 32 enabled: Cpp_IO_Manager.configurationOk + text: checked ? qsTr("Disconnect") : qsTr("Connect") + icon.source: checked ? "qrc:/icons/toolbar/connect.svg" : + "qrc:/icons/toolbar/disconnect.svg" + + // // Connect/disconnect device when button is clicked @@ -369,23 +287,12 @@ Control { onClicked: Cpp_IO_Manager.toggleConnection() // - // Custom button background + // Obtain maximum width of the button // - background: Rectangle { - radius: 3 - border.width: 1 - color: "transparent" - border.color: "#040600" - opacity: parent.checked ? 0.2 : 0.0 - - Rectangle { - border.width: 1 - color: "#626262" - anchors.fill: parent - border.color: "#c2c2c2" - radius: parent.radius - 1 - anchors.margins: parent.border.width - } + TextMetrics { + id: metrics + font: Cpp_Misc_CommonFonts.boldUiFont + text: " " + qsTr("Disconnect") + " " } } } diff --git a/app/qml/MainWindow/Root.qml b/app/qml/MainWindow/Root.qml index ffc7af69..d2dd89a4 100644 --- a/app/qml/MainWindow/Root.qml +++ b/app/qml/MainWindow/Root.qml @@ -31,6 +31,16 @@ import "../Widgets" as Widgets Window { id: root + title: qsTr("%1 - %2").arg(documentTitle).arg(Cpp_AppName) + + // + // Custom properties + // + property int appLaunchCount: 0 + property bool isMaximized: false + property string documentTitle: "" + property bool firstValidFrame: false + property bool automaticUpdates: false // // Global properties @@ -39,14 +49,6 @@ Window { readonly property bool consoleVisible: terminal.visible readonly property bool dashboardVisible: dashboard.visible - // - // Custom properties - // - property int appLaunchCount: 0 - property bool firstValidFrame: false - property bool automaticUpdates: false - property alias vt100emulation: terminal.vt100emulation - // // Toolbar functions aliases // @@ -55,8 +57,61 @@ Window { function showDashboard() { dbTimer.start() } // - // Wait a little before showing the dashboard to avoid UI glitches and/or overloading - // the rendering engine + // Obtain document title + // + function updateDocumentTitle() { + if (Cpp_JSON_Generator.operationMode == 1) + documentTitle = qsTr("Device Defined Project") + + else if (Cpp_JSON_Generator.jsonMapFilename.length > 0) + documentTitle = Cpp_Project_Model.title + + else + documentTitle = qsTr("Empty Project") + } + + // + // Ensure that window is visible + // + function displayWindow() { + if (root.isMaximized) + root.showMaximized() + + else { + if (root.x > Screen.desktopAvailableWidth - root.minimumWidth || root.x <= 0) + root.x = (Screen.desktopAvailableWidth - root.minimumWidth) / 2 + if (root.y > Screen.desktopAvailableHeight - root.minimumHeight || root.y <= 0) + root.y = (Screen.desktopAvailableHeight - root.minimumHeight) / 2 + if (root.width >= Screen.desktopAvailableWidth - 100) + root.width = root.minimumWidth + if (root.height >= Screen.desktopAvailableHeight - 100) + root.height = root.minimumHeight + + root.showNormal() + } + } + + // + // React to maximize/unmaximize event + // + onVisibilityChanged: { + if (root.visible) { + if (root.visibility === Window.Maximized) + root.isMaximized = true + + else if (root.isMaximized && root.visibility !== Window.Minimized) { + root.isMaximized = false + root.width = root.minimumWidth + root.height = root.minimumHeight + root.x = (Screen.desktopAvailableWidth - root.minimumWidth) / 2 + root.y = (Screen.desktopAvailableHeight - root.minimumHeight) / 2 + } + } + } + + // + // Wait a little before showing the dashboard to avoid UI glitches and/or + // overloading the rendering engine // Timer { id: dbTimer @@ -65,72 +120,29 @@ Window { } // - // Console-related functions + // Update document title automatically // - function consoleCopy() { terminal.copy() } - function consoleClear() { terminal.clear() } - function consoleSelectAll() { terminal.selectAll() } - - // - // Window geometry - // - visible: false - title: Cpp_AppName - width: minimumWidth - height: minimumHeight - minimumWidth: 1120 + 2 * root.shadowMargin - minimumHeight: 650 + 2 * root.shadowMargin + root.titlebar.height - - // - // Startup code - // - Component.onCompleted: { - // Load welcome text - terminal.showWelcomeGuide() - - // Increment app launch count - ++appLaunchCount - - // Show app window - if (root.isFullscreen) - root.showFullScreen() - else if (root.isMaximized) - root.showMaximized() - else { - // Fix maximize not working on first try on macOS & Windows - root.opacity = 0 - var x = root.x - var y = root.y - var w = root.width - var h = root.height - root.showMaximized() - root.showNormal() - root.setGeometry(x, y, w,h) - root.opacity = 1 + Connections { + target: Cpp_JSON_Generator + function onOperationModeChanged() { + updateDocumentTitle() } - // Force active focus - root.requestActivate() - root.requestUpdate() - - // Show donations dialog every 15 launches - if (root.appLaunchCount % 15 == 0 && !app.donateDialog.doNotShowAgain) - app.donateDialog.showAutomatically() - - // Ask user if he/she wants to enable automatic updates - if (root.appLaunchCount == 2 && Cpp_UpdaterEnabled) { - if (Cpp_Misc_Utilities.askAutomaticUpdates()) { - root.automaticUpdates = true - Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl) - } - - else - root.automaticUpdates = false + function onJsonFileMapChanged() { + updateDocumentTitle() } + } - // Check for updates (if we are allowed) - if (root.automaticUpdates && Cpp_UpdaterEnabled) - Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl) + // + // Show console tab on serial disconnect + // + Connections { + target: Cpp_UI_Dashboard + function onDataReset() { + setup.show() + root.showConsole() + root.firstValidFrame = false + } } // @@ -158,86 +170,97 @@ Window { } // - // Show console tab on serial disconnect + // Close shortcut // - Connections { - target: Cpp_UI_Dashboard - function onDataReset() { - setup.show() - root.showConsole() - root.firstValidFrame = false - } + Shortcut { + sequences: [StandardKey.Close] + onActivated: root.close() } // - // Save window size & position + // Quit shortcut + // + Shortcut { + sequences: [StandardKey.Quit] + onActivated: root.close() + } + + // + // Loading code + // + Component.onCompleted: { + // Make window caption same color as toolbar + Cpp_NativeWindow.addWindow(root) + + // Increment app launch count + ++appLaunchCount + + // Show donations dialog every 15 launches + if (root.appLaunchCount % 15 == 0 && !donateDialog.doNotShowAgain) + donateDialog.showAutomatically() + + // Ask user if he/she wants to enable automatic updates + if (root.appLaunchCount == 2 && Cpp_UpdaterEnabled) { + if (Cpp_Misc_Utilities.askAutomaticUpdates()) { + root.automaticUpdates = true + Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl) + } + + else + root.automaticUpdates = false + } + + // Check for updates (if we are allowed) + if (root.automaticUpdates && Cpp_UpdaterEnabled) + Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl) + + // Obtain document title from JSON project editor & display the window + updateDocumentTitle() + displayWindow() + } + + // + // Save settings // Settings { - property alias wx: root.x - property alias wy: root.y - property alias ww: root.width - property alias wh: root.height - property alias wm: root.isMaximized - property alias wf: root.isFullscreen + property alias ax: root.x + property alias ay: root.y + property alias aw: root.width + property alias ah: root.height + property alias am: root.isMaximized property alias appStatus: root.appLaunchCount property alias autoUpdater: root.automaticUpdates } - // - // Rectangle for the menubar (only used if custom window flags are disabled) - // - Rectangle { - color: root.titlebarColor - anchors.fill: menubarLayout - visible: !Cpp_ThemeManager.customWindowDecorations - } - - // - // Main layout + // Load user interface component // Page { - clip: true anchors.fill: parent - - palette.alternateBase: Cpp_ThemeManager.base - palette.base: Cpp_ThemeManager.base - palette.brightText: Cpp_ThemeManager.brightText - palette.button: Cpp_ThemeManager.button - palette.buttonText: Cpp_ThemeManager.buttonText - palette.highlight: Cpp_ThemeManager.highlight - palette.highlightedText: Cpp_ThemeManager.highlightedText - palette.link: Cpp_ThemeManager.link - palette.placeholderText: Cpp_ThemeManager.placeholderText - palette.text: Cpp_ThemeManager.text - palette.toolTipBase: Cpp_ThemeManager.tooltipBase - palette.toolTipText: Cpp_ThemeManager.tooltipText - palette.window: Cpp_ThemeManager.window - palette.windowText: Cpp_ThemeManager.windowText - - background: Rectangle { - radius: root.radius - color: Cpp_ThemeManager.windowBackground - } + palette.base: Cpp_ThemeManager.colors["base"] + palette.text: Cpp_ThemeManager.colors["text"] + palette.button: Cpp_ThemeManager.colors["button"] + palette.window: Cpp_ThemeManager.colors["window"] + palette.highlight: Cpp_ThemeManager.colors["highlight"] + palette.buttonText: Cpp_ThemeManager.colors["button_text"] + palette.placeholderText: Cpp_ThemeManager.colors["placeholder_text"] + palette.highlightedText: Cpp_ThemeManager.colors["highlighted_text"] ColumnLayout { spacing: 0 anchors.fill: parent // - // Application toolbar + // Toolbar // Panes.Toolbar { + z: 2 id: toolbar - window: root - z: titlebar.z Layout.fillWidth: true + setupChecked: root.setupVisible consoleChecked: root.consoleVisible - Layout.minimumHeight: implicitHeight - Layout.maximumHeight: implicitHeight dashboardChecked: root.dashboardVisible - onProjectEditorClicked: app.projectEditorWindow.show() onSetupClicked: setup.visible ? setup.hide() : setup.show() onDashboardClicked: { @@ -260,13 +283,16 @@ Window { } // - // Console, dashboard & setup panel + // User interface // RowLayout { + z: 1 spacing: 0 - Layout.fillWidth: true - Layout.fillHeight: true + Layout.topMargin: -1 + // + // Dashboard + Console view + // StackView { id: stack clip: true @@ -290,6 +316,27 @@ Window { ] } + // + // Panel border rectangle + // + Rectangle { + z: 2 + width: 1 + Layout.fillHeight: true + color: Cpp_ThemeManager.colors["setup_border"] + + Rectangle { + width: 1 + height: 32 + anchors.top: parent.top + anchors.left: parent.left + color: Cpp_ThemeManager.colors["pane_caption_border"] + } + } + + // + // Setup panel + // Panes.Setup { id: setup Layout.fillHeight: true @@ -299,13 +346,13 @@ Window { } } } - } - // - // JSON project drop area - // - Widgets.JSONDropArea { - anchors.fill: parent - enabled: !Cpp_IO_Manager.connected + // + // JSON project drop area + // + Widgets.JSONDropArea { + anchors.fill: parent + enabled: !Cpp_IO_Manager.connected + } } } diff --git a/app/qml/ProjectEditor/Root.qml b/app/qml/ProjectEditor/Root.qml index 6e10a572..a6fde73a 100644 --- a/app/qml/ProjectEditor/Root.qml +++ b/app/qml/ProjectEditor/Root.qml @@ -26,6 +26,7 @@ import QtQuick.Window import QtQuick.Layouts import QtQuick.Controls +import "Sections" import "../ProjectEditor" import "../Widgets" as Widgets @@ -37,7 +38,7 @@ Window { // minimumWidth: 910 minimumHeight: 720 - title: qsTr("Project Editor - %1").arg(Cpp_Project_Model.jsonFileName) + title: qsTr("%1 - Project Editor").arg(Cpp_Project_Model.jsonFileName) // // Ensure that current JSON file is shown @@ -69,40 +70,16 @@ Window { // Use page item to set application palette // Page { - clip: true anchors.fill: parent - anchors.margins: root.shadowMargin - anchors.topMargin: titlebar.height + root.shadowMargin - - palette.alternateBase: Cpp_ThemeManager.base - palette.base: Cpp_ThemeManager.base - palette.brightText: Cpp_ThemeManager.brightText - palette.button: Cpp_ThemeManager.button - palette.buttonText: Cpp_ThemeManager.buttonText - palette.highlight: Cpp_ThemeManager.highlight - palette.highlightedText: Cpp_ThemeManager.highlightedText - palette.link: Cpp_ThemeManager.link - palette.placeholderText: Cpp_ThemeManager.placeholderText - palette.text: Cpp_ThemeManager.text - palette.toolTipBase: Cpp_ThemeManager.tooltipBase - palette.toolTipText: Cpp_ThemeManager.tooltipText - palette.window: Cpp_ThemeManager.window - palette.windowText: Cpp_ThemeManager.windowText - - background: Rectangle { - radius: root.radius - color: Cpp_ThemeManager.windowBackground - } - - // - // Shadows - // - Widgets.Shadow { - anchors.fill: header - } Widgets.Shadow { - anchors.fill: footer - anchors.bottomMargin: footer.height / 2 - } + palette.base: Cpp_ThemeManager.colors["base"] + palette.text: Cpp_ThemeManager.colors["text"] + palette.button: Cpp_ThemeManager.colors["button"] + palette.window: Cpp_ThemeManager.colors["window"] + palette.windowText: Cpp_ThemeManager.colors["text"] + palette.buttonText: Cpp_ThemeManager.colors["button_text"] + palette.highlight: Cpp_ThemeManager.colors["switch_highlight"] + palette.placeholderText: Cpp_ThemeManager.colors["placeholder_text"] + palette.highlightedText: Cpp_ThemeManager.colors["highlighted_text"] // // Header (project properties) @@ -140,7 +117,7 @@ Window { RowLayout { clip: true anchors.fill: parent - spacing: app.spacing + spacing: 8 anchors.topMargin: header.height anchors.bottomMargin: footer.height @@ -149,8 +126,8 @@ Window { // Item { Layout.fillHeight: true - Layout.minimumWidth: app.spacing - Layout.maximumWidth: app.spacing + Layout.minimumWidth: 8 + Layout.maximumWidth: 8 } // @@ -161,8 +138,8 @@ Window { Layout.fillHeight: true Layout.minimumWidth: 240 Layout.maximumWidth: 240 - Layout.topMargin: app.spacing * 2 - Layout.bottomMargin: app.spacing * 2 + Layout.topMargin: 8 * 2 + Layout.bottomMargin: 8 * 2 visible: Cpp_Project_Model.groupCount !== 0 }*/ @@ -185,29 +162,27 @@ Window { visible: Cpp_Project_Model.groupCount === 0 ColumnLayout { - spacing: app.spacing + spacing: 8 anchors.centerIn: parent - Widgets.Icon { - width: 128 - height: 128 - color: Cpp_ThemeManager.text + Image { + sourceSize: Qt.size(128, 128) Layout.alignment: Qt.AlignHCenter - source: "qrc:/icons/developer-board.svg" + source: "qrc:/images/microcontroller.svg" } Label { font.bold: true font.pixelSize: 24 Layout.alignment: Qt.AlignHCenter - text: qsTr("Start something awesome") + text: qsTr("Start Something Awesome") } Label { opacity: 0.8 font.pixelSize: 18 Layout.alignment: Qt.AlignHCenter - text: qsTr("Click on the \"Add group\" button to begin") + text: qsTr("Click on the \"Add Group\" Button to Begin") } } } @@ -217,8 +192,8 @@ Window { // Item { Layout.fillHeight: true - Layout.minimumWidth: app.spacing - Layout.maximumWidth: app.spacing + Layout.minimumWidth: 8 + Layout.maximumWidth: 8 } } } diff --git a/app/qml/ProjectEditor/Sections/Footer.qml b/app/qml/ProjectEditor/Sections/Footer.qml index 5a43df2f..51f0c62b 100644 --- a/app/qml/ProjectEditor/Sections/Footer.qml +++ b/app/qml/ProjectEditor/Sections/Footer.qml @@ -24,12 +24,10 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets - Rectangle { id: root color: Cpp_ThemeManager.toolbarGradient2 - height: footer.implicitHeight + 4 * app.spacing + height: footer.implicitHeight + 32 // // Signals @@ -68,12 +66,12 @@ Rectangle { // RowLayout { id: footer - spacing: app.spacing + spacing: 8 anchors { left: parent.left right: parent.right - margins: app.spacing * 2 + margins: 8 * 2 verticalCenter: parent.verticalCenter } diff --git a/app/qml/ProjectEditor/Sections/GroupEditor.qml b/app/qml/ProjectEditor/Sections/GroupEditor.qml index dbfe052b..461338e5 100644 --- a/app/qml/ProjectEditor/Sections/GroupEditor.qml +++ b/app/qml/ProjectEditor/Sections/GroupEditor.qml @@ -24,8 +24,6 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets - ColumnLayout { id: root spacing: 0 @@ -62,7 +60,7 @@ ColumnLayout { // Spacer // Item { - height: app.spacing + height: 8 } // @@ -111,6 +109,6 @@ ColumnLayout { // Spacer // Item { - height: app.spacing + height: 8 } } diff --git a/app/qml/ProjectEditor/Sections/Header.qml b/app/qml/ProjectEditor/Sections/Header.qml index 17bea0ce..f202acb4 100644 --- a/app/qml/ProjectEditor/Sections/Header.qml +++ b/app/qml/ProjectEditor/Sections/Header.qml @@ -24,11 +24,11 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets +import "../../Widgets" as Widgets Rectangle { id: root - height: header.implicitHeight + 4 * app.spacing + height: header.implicitHeight + 32 // // Background & border @@ -42,7 +42,6 @@ Rectangle { Rectangle { height: 1 - visible: Cpp_ThemeManager.titlebarSeparator color: Qt.darker(Cpp_ThemeManager.toolbarGradient1, 1.5) anchors { @@ -59,13 +58,13 @@ Rectangle { GridLayout { id: header columns: 2 - rowSpacing: app.spacing - columnSpacing: app.spacing * 2 + rowSpacing: 8 + columnSpacing: 8 * 2 anchors { left: parent.left right: parent.right - margins: app.spacing * 2 + margins: 8 * 2 verticalCenter: parent.verticalCenter } @@ -73,13 +72,13 @@ Rectangle { // Project title // RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true - Widgets.Icon { + /*Widgets.Icon { color: Cpp_ThemeManager.menubarText source: "qrc:/icons/registration.svg" - } + }*/ TextField { Layout.fillWidth: true @@ -102,13 +101,13 @@ Rectangle { // Separator character // RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true - Widgets.Icon { + /*Widgets.Icon { color: Cpp_ThemeManager.menubarText source: "qrc:/icons/separator.svg" - } + }*/ TextField { Layout.fillWidth: true @@ -131,13 +130,13 @@ Rectangle { // Start sequence // RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true - Widgets.Icon { + /*Widgets.Icon { color: Cpp_ThemeManager.menubarText source: "qrc:/icons/start-sequence.svg" - } + }*/ TextField { Layout.fillWidth: true @@ -160,13 +159,13 @@ Rectangle { // End sequence // RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true - Widgets.Icon { + /*Widgets.Icon { color: Cpp_ThemeManager.menubarText source: "qrc:/icons/end-sequence.svg" - } + }*/ TextField { Layout.fillWidth: true diff --git a/app/qml/ProjectEditor/Sections/JsonDatasetDelegate.qml b/app/qml/ProjectEditor/Sections/JsonDatasetDelegate.qml index b32b8c06..445b5c36 100644 --- a/app/qml/ProjectEditor/Sections/JsonDatasetDelegate.qml +++ b/app/qml/ProjectEditor/Sections/JsonDatasetDelegate.qml @@ -24,27 +24,18 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets +import "../../Widgets" as Widgets -Widgets.Window { +Widgets.Pane { id: root // // Window properties // - headerDoubleClickEnabled: false - icon.source: "qrc:/icons/dataset.svg" - borderColor: Cpp_ThemeManager.widgetWindowBorder + icon: "qrc:/icons/dataset.svg" palette.window: Cpp_ThemeManager.widgetWindowBackground title: qsTr("Dataset %1 - %2").arg(dataset + 1).arg(Cpp_Project_Model.datasetTitle(group, dataset)) - // - // Delete dataset button - // - altButtonEnabled: !showGroupWidget - altButtonIcon.source: "qrc:/icons/close.svg" - onAltButtonClicked: Cpp_Project_Model.deleteDataset(group, dataset) - // // Custom properties // @@ -71,11 +62,11 @@ Widgets.Window { x: 0 columns: 2 anchors.fill: parent - columnSpacing: app.spacing - anchors.margins: app.spacing - rowSpacing: app.spacing / 2 - anchors.leftMargin: app.spacing * 2 - anchors.rightMargin: app.spacing * 2 + columnSpacing: 8 + anchors.margins: 8 + rowSpacing: 8 / 2 + anchors.leftMargin: 8 * 2 + anchors.rightMargin: 8 * 2 // // Dataset title @@ -126,7 +117,7 @@ Widgets.Window { text: qsTr("Display LED:") } Switch { id: led - Layout.leftMargin: -app.spacing + Layout.leftMargin: -8 checked: Cpp_Project_Model.datasetLED(group, dataset) onCheckedChanged: Cpp_Project_Model.setDatasetLED(group, dataset, checked) } @@ -138,7 +129,7 @@ Widgets.Window { text: qsTr("Generate plot:") } Switch { id: linearPlot - Layout.leftMargin: -app.spacing + Layout.leftMargin: -8 checked: Cpp_Project_Model.datasetGraph(group, dataset) onCheckedChanged: { if (!checked) @@ -157,7 +148,7 @@ Widgets.Window { } CheckBox { id: logPlot visible: linearPlot.checked - Layout.leftMargin: -app.spacing + Layout.leftMargin: -8 checked: Cpp_Project_Model.datasetLogPlot(group, dataset) onCheckedChanged: Cpp_Project_Model.setDatasetLogPlot(group, dataset, checked) } @@ -169,7 +160,7 @@ Widgets.Window { text: qsTr("FFT plot:") } Switch { id: fftCheck - Layout.leftMargin: -app.spacing + Layout.leftMargin: -8 checked: Cpp_Project_Model.datasetFftPlot(group, dataset) onCheckedChanged: Cpp_Project_Model.setDatasetFftPlot(group, dataset, checked) } @@ -288,14 +279,14 @@ Widgets.Window { // // Compass note label // - Widgets.Icon { + /*Widgets.Icon { width: 32 height: 32 color: palette.text source: "qrc:/icons/compass.svg" Layout.alignment: Qt.AlignHCenter visible: widget.currentIndex === 3 - } Label { + }*/ Label { font.pixelSize: 16 Layout.fillWidth: true wrapMode: Label.WordWrap diff --git a/app/qml/ProjectEditor/Sections/JsonGroupDelegate.qml b/app/qml/ProjectEditor/Sections/JsonGroupDelegate.qml index 7f3a3d3c..90558355 100644 --- a/app/qml/ProjectEditor/Sections/JsonGroupDelegate.qml +++ b/app/qml/ProjectEditor/Sections/JsonGroupDelegate.qml @@ -24,8 +24,6 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls -import "../Widgets" as Widgets - Page { id: root @@ -67,9 +65,9 @@ Page { // ColumnLayout { id: column - spacing: app.spacing + spacing: 8 anchors.fill: parent - anchors.margins: app.spacing + anchors.margins: 8 // // Notes rectangle @@ -79,22 +77,22 @@ Page { radius: 16 Layout.fillWidth: true color: Cpp_ThemeManager.highlight - Layout.minimumHeight: 32 + 2 * app.spacing + Layout.minimumHeight: 32 + 2 * 8 visible: widget.currentIndex === 1 || widget.currentIndex === 2 RowLayout { - spacing: app.spacing + spacing: 8 anchors.centerIn: parent Layout.alignment: Qt.AlignHCenter visible: widget.currentIndex === 1 - Widgets.Icon { + /*Widgets.Icon { width: 32 height: 32 color: palette.highlightedText Layout.alignment: Qt.AlignHCenter source: "qrc:/icons/accelerometer.svg" - } Label { + }*/ Label { font.pixelSize: 18 wrapMode: Label.WordWrap color: palette.highlightedText @@ -103,18 +101,18 @@ Page { } RowLayout { - spacing: app.spacing + spacing: 8 anchors.centerIn: parent Layout.alignment: Qt.AlignHCenter visible: widget.currentIndex === 2 - Widgets.Icon { + /*Widgets.Icon { width: 32 height: 32 source: "qrc:/icons/gyro.svg" color: palette.highlightedText Layout.alignment: Qt.AlignHCenter - } Label { + }*/ Label { font.pixelSize: 18 wrapMode: Label.WordWrap color: palette.highlightedText @@ -127,7 +125,7 @@ Page { // Group title // RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true Label { @@ -223,17 +221,17 @@ Page { // Empty group text & icon // ColumnLayout { - spacing: app.spacing + spacing: 8 anchors.centerIn: parent visible: grid.model === 0 - Widgets.Icon { + /*Widgets.Icon { width: 128 height: 128 color: Cpp_ThemeManager.text source: "qrc:/icons/group.svg" Layout.alignment: Qt.AlignHCenter - } + }*/ Label { font.bold: true @@ -247,7 +245,7 @@ Page { font.pixelSize: 18 Layout.alignment: Qt.AlignHCenter wrapMode: Label.WrapAtWordBoundaryOrAnywhere - Layout.maximumWidth: grid.width - 8 * app.spacing + Layout.maximumWidth: grid.width - 8 * 8 text: qsTr("Set group title and click on the \"Add dataset\" button to begin") } } @@ -288,7 +286,7 @@ Page { Loader { id: loader anchors.fill: parent - anchors.margins: app.spacing + anchors.margins: 8 sourceComponent: JsonDatasetDelegate { dataset: index diff --git a/app/qml/ProjectEditor/Sections/TreeView.qml b/app/qml/ProjectEditor/Sections/TreeView.qml index a6ad9034..4f442380 100644 --- a/app/qml/ProjectEditor/Sections/TreeView.qml +++ b/app/qml/ProjectEditor/Sections/TreeView.qml @@ -65,22 +65,22 @@ Widgets.Window { ListView { id: view anchors.fill: parent - spacing: app.spacing * 2 - anchors.margins: app.spacing + spacing: 8 * 2 + anchors.margins: 8 model: Cpp_Project_Model.groupCount delegate: Loader { - width: view.width - app.spacing * 2 + width: view.width - 8 * 2 height: Cpp_Project_Model.datasetCount(index) * 24 + 24 sourceComponent: ColumnLayout { id: groupDelegate - spacing: app.spacing + spacing: 8 readonly property var groupId: index RowLayout { - spacing: app.spacing + spacing: 8 Layout.fillWidth: true Widgets.Icon { @@ -114,10 +114,10 @@ Widgets.Window { delegate: Loader { Layout.fillWidth: true sourceComponent: RowLayout { - spacing: app.spacing + spacing: 8 Item { - width: 2 * app.spacing + width: 2 * 8 } Widgets.Icon { diff --git a/app/qml/Widgets/BigButton.qml b/app/qml/Widgets/BigButton.qml index 7abcc51a..845193e9 100644 --- a/app/qml/Widgets/BigButton.qml +++ b/app/qml/Widgets/BigButton.qml @@ -30,8 +30,7 @@ ToolButton { icon.width: 32 icon.height: 32 icon.color: "transparent" - display: mainWindow.dumbInterface ? AbstractButton.TextBesideIcon : - AbstractButton.TextUnderIcon + display: AbstractButton.TextUnderIcon Layout.minimumWidth: Math.max(implicitWidth, 72) Layout.maximumWidth: Math.max(implicitWidth, 72) diff --git a/app/qml/Widgets/GpsMap.qml b/app/qml/Widgets/GpsMap.qml index 217fbac7..1b5239e6 100644 --- a/app/qml/Widgets/GpsMap.qml +++ b/app/qml/Widgets/GpsMap.qml @@ -67,12 +67,12 @@ Item { // UI controls // ColumnLayout { - spacing: app.spacing + spacing: 8 anchors.fill: parent - anchors.margins: app.spacing + anchors.margins: 8 RowLayout { - spacing: app.spacing + spacing: 8 Label { text: qsTr("Map Type:") diff --git a/app/qml/Widgets/JSONDropArea.qml b/app/qml/Widgets/JSONDropArea.qml index bf6d185e..e87a3b59 100644 --- a/app/qml/Widgets/JSONDropArea.qml +++ b/app/qml/Widgets/JSONDropArea.qml @@ -94,14 +94,14 @@ DropArea { opacity: 0 border.width: 1 anchors.centerIn: parent - color: Cpp_ThemeManager.highlight - border.color: Cpp_ThemeManager.text - width: dropLayout.implicitWidth + 6 * app.spacing - height: dropLayout.implicitHeight + 6 * app.spacing + width: dropLayout.implicitWidth + 48 + height: dropLayout.implicitHeight + 48 + color: Cpp_ThemeManager.colors["highlight"] + border.color: Cpp_ThemeManager.colors["text"] ColumnLayout { + spacing: 16 id: dropLayout - spacing: app.spacing * 2 anchors.centerIn: parent ToolButton { @@ -111,15 +111,14 @@ DropArea { icon.height: 128 Layout.alignment: Qt.AlignHCenter icon.source: "qrc:/icons/drag-drop.svg" - icon.color: Cpp_ThemeManager.highlightedText + icon.color: Cpp_ThemeManager.colors["highlighted_text"] } Label { - font.bold: true - font.pixelSize: 24 Layout.alignment: Qt.AlignHCenter - color: Cpp_ThemeManager.highlightedText text: qsTr("Drop JSON and CSV files here") + font: Cpp_Misc_CommonFonts.customUiFont(24, true) + color: Cpp_ThemeManager.colors["highlighted_text"] } } diff --git a/app/qml/Widgets/Pane.qml b/app/qml/Widgets/Pane.qml index 796c33f4..ea836764 100644 --- a/app/qml/Widgets/Pane.qml +++ b/app/qml/Widgets/Pane.qml @@ -127,8 +127,8 @@ Controls.GroupBox { Controls.Label { id: _title text: root.title - font: Cpp_CommonFonts.boldUiFont Layout.alignment: Qt.AlignVCenter + font: Cpp_Misc_CommonFonts.boldUiFont Layout.leftMargin: root.hardBorder ? -6 : undefined color: root.hardBorder ? Cpp_ThemeManager.colors["pane_hard_caption_foreground"] : diff --git a/app/qml/Widgets/Terminal.qml b/app/qml/Widgets/Terminal.qml index 8a7f5203..d60e187f 100644 --- a/app/qml/Widgets/Terminal.qml +++ b/app/qml/Widgets/Terminal.qml @@ -28,7 +28,6 @@ import SerialStudio as SerialStudio Item { id: root - property bool isExternalWindow: false property alias widgetEnabled: textEdit.widgetEnabled property alias vt100emulation: textEdit.vt100emulation @@ -45,6 +44,14 @@ Item { property alias displayMode: displayModeCombo.currentIndex } + // + // Load welcome guide + // + function showWelcomeGuide() { + clear() + Cpp_IO_Console.append(Cpp_Misc_Translator.welcomeConsoleText() + "\n") + } + // // Function to send through serial port data // @@ -75,6 +82,17 @@ Item { textEdit.selectAll() } + // + // Re-load welcome text when the language is changed + // + Component.onCompleted: root.showWelcomeGuide() + Connections { + target: Cpp_Misc_Translator + function onLanguageChanged() { + root.showWelcomeGuide() + } + } + // // Right-click context menu // @@ -124,9 +142,9 @@ Item { // Controls // ColumnLayout { + spacing: 4 anchors.fill: parent - spacing: app.spacing - anchors.margins: app.spacing * 1.5 + anchors.topMargin: -6 // // Console display @@ -178,20 +196,15 @@ Item { opacity: enabled ? 1 : 0.5 Layout.alignment: Qt.AlignVCenter enabled: Cpp_IO_Manager.readWrite - palette.text: Cpp_ThemeManager.consoleText - palette.base: Cpp_ThemeManager.consoleBase - placeholderText: qsTr("Send data to device") + "..." - Component.onCompleted: { - if (Cpp_Qt6) - placeholderTextColor = Cpp_ThemeManager.consolePlaceholderText - } + placeholderText: qsTr("Send Data to Device") + "..." - // - // Validate hex strings - // - //validator: RegExpValidator { - // regExp: hexCheckbox.checked ? /^(?:([a-f0-9]{2})\s*)+$/i : /[\s\S]*/ - //} + palette.base: Cpp_ThemeManager.colors["console_base"] + palette.text: Cpp_ThemeManager.colors["console_text"] + palette.button: Cpp_ThemeManager.colors["console_button"] + palette.window: Cpp_ThemeManager.colors["console_window"] + palette.buttonText: Cpp_ThemeManager.colors["console_button_text"] + palette.placeholderText: Cpp_ThemeManager.colors["console_placeholder_text"] + palette.highlightedText: Cpp_ThemeManager.colors["console_highlighted_text"] // // Send data on @@ -280,7 +293,7 @@ Item { CheckBox { id: timestampCheck - text: qsTr("Show timestamp") + text: qsTr("Show Timestamp") Layout.alignment: Qt.AlignVCenter checked: Cpp_IO_Console.showTimestamp onCheckedChanged: { @@ -289,15 +302,29 @@ Item { } } + CheckBox { + id: vt100Check + text: qsTr("Emulate VT-100") + Layout.alignment: Qt.AlignVCenter + checked: textEdit.vt100emulation + onCheckedChanged: { + if (textEdit.vt100emulation !== checked) + textEdit.vt100emulation = checked + } + } + Item { Layout.fillWidth: true } ComboBox { id: displayModeCombo + Layout.fillWidth: true + Layout.maximumWidth: 164 Layout.alignment: Qt.AlignVCenter model: Cpp_IO_Console.displayModes() currentIndex: Cpp_IO_Console.displayMode + displayText: qsTr("Display: %1").arg(currentText) onCurrentIndexChanged: { if (currentIndex !== Cpp_IO_Console.displayMode) Cpp_IO_Console.displayMode = currentIndex @@ -306,22 +333,38 @@ Item { Button { height: 24 + icon.width: 18 + icon.height: 18 Layout.maximumWidth: 32 - icon.color: palette.text opacity: enabled ? 1 : 0.5 onClicked: Cpp_IO_Console.save() - icon.source: "qrc:/icons/save.svg" enabled: Cpp_IO_Console.saveAvailable + icon.source: "qrc:/icons/buttons/save.svg" + icon.color: Cpp_ThemeManager.colors["button_text"] } Button { height: 24 + icon.width: 18 + icon.height: 18 Layout.maximumWidth: 32 - icon.color: palette.text opacity: enabled ? 1 : 0.5 - onClicked: root.clear() - icon.source: "qrc:/icons/delete.svg" + onClicked: Cpp_IO_Console.print() enabled: Cpp_IO_Console.saveAvailable + icon.source: "qrc:/icons/buttons/print.svg" + icon.color: Cpp_ThemeManager.colors["button_text"] + } + + Button { + height: 24 + icon.width: 18 + icon.height: 18 + onClicked: root.clear() + Layout.maximumWidth: 32 + opacity: enabled ? 1 : 0.5 + enabled: Cpp_IO_Console.saveAvailable + icon.source: "qrc:/icons/buttons/clear.svg" + icon.color: Cpp_ThemeManager.colors["button_text"] } } } diff --git a/app/qml/main.qml b/app/qml/main.qml index 2ee83560..a5ba60dd 100644 --- a/app/qml/main.qml +++ b/app/qml/main.qml @@ -24,29 +24,13 @@ import QtQuick import QtQuick.Window import QtQuick.Controls -import "Dialogs" as Windows +import "Dialogs" as Dialogs import "MainWindow" as MainWindow import "ProjectEditor" as ProjectEditor Item { id: app - // - // Global propeties - // - readonly property int spacing: 8 - readonly property string monoFont: "Roboto Mono" - - // - // Access to dialogs & windows - // - property Window aboutDialog: null - property Window donateDialog: null - property Window mainWindow: null - property Window csvPlayerDialog: null - property Window projectEditorWindow: null - property Window acknowledgementsDialog: null - // // Check for updates (non-silent mode) // @@ -56,65 +40,45 @@ Item { } // - // MainWindow + // Main window + subdialogs // - Loader { - asynchronous: true - sourceComponent: MainWindow.Root { - Component.onCompleted: { - app.forceActiveFocus() - app.mainWindow = this - } + MainWindow.Root { + id: mainWindow + + Dialogs.CsvPlayer { + id: csvPlayer + } + + Dialogs.Donate { + id: donateDialog + } + + DialogLoader { + id: projectEditor + source: "qrc:/app/qml/ProjectEditor/Root.qml" + } + + DialogLoader { + id: mqttConfiguration + source: "qrc:/app/qml/Dialogs/MQTTConfiguration.qml" + } + + DialogLoader { + id: aboutDialog + source: "qrc:/app/qml/Dialogs/About.qml" + } + + DialogLoader { + id: acknowledgementsDialog + source: "qrc:/app/qml/Dialogs/Acknowledgements.qml" } } // - // About window + // Dialog display functions // - Loader { - asynchronous: true - sourceComponent: Windows.About { - Component.onCompleted: app.aboutDialog = this - } - } - - // - // CSV player window - // - Loader { - asynchronous: true - sourceComponent: Windows.CsvPlayer { - Component.onCompleted: app.csvPlayerDialog = this - } - } - - // - // Project editor dialog - // - Loader { - asynchronous: true - sourceComponent: ProjectEditor.Root { - Component.onCompleted: app.projectEditorWindow = this - } - } - - // - // Donations dialog - // - Loader { - asynchronous: false - sourceComponent: Windows.Donate { - Component.onCompleted: app.donateDialog = this - } - } - - // - // Acknowledgements dialog - // - Loader { - asynchronous: true - sourceComponent: Windows.Acknowledgements { - Component.onCompleted: app.acknowledgementsDialog = this - } - } + function showAboutDialog() { aboutDialog.active = true } + function showProjectEditor() { projectEditor.active = true } + function showMqttConfiguration() { mqttConfiguration.active = true } + function showAcknowledgements() { acknowledgementsDialog.active = true } } diff --git a/app/rcc/icons/buttons/apply.svg b/app/rcc/icons/buttons/apply.svg new file mode 100644 index 00000000..0914f320 --- /dev/null +++ b/app/rcc/icons/buttons/apply.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/clear.svg b/app/rcc/icons/buttons/clear.svg new file mode 100644 index 00000000..eff9511f --- /dev/null +++ b/app/rcc/icons/buttons/clear.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/close.svg b/app/rcc/icons/buttons/close.svg new file mode 100644 index 00000000..3fc9e350 --- /dev/null +++ b/app/rcc/icons/buttons/close.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/connected.svg b/app/rcc/icons/buttons/connected.svg new file mode 100644 index 00000000..f267aace --- /dev/null +++ b/app/rcc/icons/buttons/connected.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/disconnected.svg b/app/rcc/icons/buttons/disconnected.svg new file mode 100644 index 00000000..9d756fc1 --- /dev/null +++ b/app/rcc/icons/buttons/disconnected.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/media-next.svg b/app/rcc/icons/buttons/media-next.svg new file mode 100644 index 00000000..4597dc51 --- /dev/null +++ b/app/rcc/icons/buttons/media-next.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/media-pause.svg b/app/rcc/icons/buttons/media-pause.svg new file mode 100644 index 00000000..6ef9e72c --- /dev/null +++ b/app/rcc/icons/buttons/media-pause.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/media-play.svg b/app/rcc/icons/buttons/media-play.svg new file mode 100644 index 00000000..32a7d62d --- /dev/null +++ b/app/rcc/icons/buttons/media-play.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/media-prev.svg b/app/rcc/icons/buttons/media-prev.svg new file mode 100644 index 00000000..e5988fa0 --- /dev/null +++ b/app/rcc/icons/buttons/media-prev.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/open.svg b/app/rcc/icons/buttons/open.svg new file mode 100644 index 00000000..33f42432 --- /dev/null +++ b/app/rcc/icons/buttons/open.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/print.svg b/app/rcc/icons/buttons/print.svg new file mode 100644 index 00000000..969c31e2 --- /dev/null +++ b/app/rcc/icons/buttons/print.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/save.svg b/app/rcc/icons/buttons/save.svg new file mode 100644 index 00000000..b59af0af --- /dev/null +++ b/app/rcc/icons/buttons/save.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/buttons/visibility.svg b/app/rcc/icons/buttons/visibility.svg new file mode 100644 index 00000000..c13af72f --- /dev/null +++ b/app/rcc/icons/buttons/visibility.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/rcc/icons/panes/console.svg b/app/rcc/icons/panes/console.svg new file mode 100644 index 00000000..9eb85627 --- /dev/null +++ b/app/rcc/icons/panes/console.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/app/rcc/icons/panes/dashboard.svg b/app/rcc/icons/panes/dashboard.svg new file mode 100644 index 00000000..9f996922 --- /dev/null +++ b/app/rcc/icons/panes/dashboard.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/rcc/icons/panes/setup.svg b/app/rcc/icons/panes/setup.svg new file mode 100644 index 00000000..de6f7511 --- /dev/null +++ b/app/rcc/icons/panes/setup.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/app/rcc/icons/panes/view.svg b/app/rcc/icons/panes/view.svg new file mode 100644 index 00000000..d682d440 --- /dev/null +++ b/app/rcc/icons/panes/view.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/rcc/icons/toolbar/about.svg b/app/rcc/icons/toolbar/about.svg new file mode 100644 index 00000000..4364de3f --- /dev/null +++ b/app/rcc/icons/toolbar/about.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app/rcc/icons/toolbar/bug.svg b/app/rcc/icons/toolbar/bug.svg deleted file mode 100644 index 7c981241..00000000 --- a/app/rcc/icons/toolbar/bug.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/app/rcc/icons/toolbar/connect.svg b/app/rcc/icons/toolbar/connect.svg index a7a46345..6184cadd 100644 --- a/app/rcc/icons/toolbar/connect.svg +++ b/app/rcc/icons/toolbar/connect.svg @@ -1,13 +1,13 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/app/rcc/icons/toolbar/console.svg b/app/rcc/icons/toolbar/console.svg index a77dd684..517bd6a1 100644 --- a/app/rcc/icons/toolbar/console.svg +++ b/app/rcc/icons/toolbar/console.svg @@ -1,9 +1,9 @@ - - - - - - + + + + + + diff --git a/app/rcc/icons/toolbar/csv.svg b/app/rcc/icons/toolbar/csv.svg index 65fa80b5..d94f38a2 100644 --- a/app/rcc/icons/toolbar/csv.svg +++ b/app/rcc/icons/toolbar/csv.svg @@ -1,10 +1,12 @@ - - - - - - - + + + + + + + + + diff --git a/app/rcc/icons/toolbar/dashboard.svg b/app/rcc/icons/toolbar/dashboard.svg index d66667bc..f1c1cc78 100644 --- a/app/rcc/icons/toolbar/dashboard.svg +++ b/app/rcc/icons/toolbar/dashboard.svg @@ -1,30 +1,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/rcc/icons/toolbar/device-setup.svg b/app/rcc/icons/toolbar/device-setup.svg new file mode 100644 index 00000000..dfaf4525 --- /dev/null +++ b/app/rcc/icons/toolbar/device-setup.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/rcc/icons/toolbar/disconnect.svg b/app/rcc/icons/toolbar/disconnect.svg index c85da402..92bc0f38 100644 --- a/app/rcc/icons/toolbar/disconnect.svg +++ b/app/rcc/icons/toolbar/disconnect.svg @@ -1,17 +1,17 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/app/rcc/icons/toolbar/github.svg b/app/rcc/icons/toolbar/github.svg new file mode 100644 index 00000000..4e4ee83e --- /dev/null +++ b/app/rcc/icons/toolbar/github.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app/rcc/icons/toolbar/help.svg b/app/rcc/icons/toolbar/help.svg index 52516cf2..f16e529d 100644 --- a/app/rcc/icons/toolbar/help.svg +++ b/app/rcc/icons/toolbar/help.svg @@ -1,9 +1,12 @@ - - - - - - + + + + + + + + + diff --git a/app/rcc/icons/toolbar/mqtt.svg b/app/rcc/icons/toolbar/mqtt.svg new file mode 100644 index 00000000..11092be5 --- /dev/null +++ b/app/rcc/icons/toolbar/mqtt.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/app/rcc/icons/toolbar/project-editor.svg b/app/rcc/icons/toolbar/project-editor.svg deleted file mode 100644 index a410c687..00000000 --- a/app/rcc/icons/toolbar/project-editor.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/app/rcc/icons/toolbar/project-setup.svg b/app/rcc/icons/toolbar/project-setup.svg new file mode 100644 index 00000000..fece2732 --- /dev/null +++ b/app/rcc/icons/toolbar/project-setup.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/rcc/icons/toolbar/setup.svg b/app/rcc/icons/toolbar/setup.svg deleted file mode 100644 index 10c84a94..00000000 --- a/app/rcc/icons/toolbar/setup.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/rcc/images/code.svg b/app/rcc/images/code.svg new file mode 100644 index 00000000..8efca51f --- /dev/null +++ b/app/rcc/images/code.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/app/rcc/images/microcontroller.svg b/app/rcc/images/microcontroller.svg new file mode 100644 index 00000000..b796c273 --- /dev/null +++ b/app/rcc/images/microcontroller.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/rcc/images/tip.svg b/app/rcc/images/tip.svg new file mode 100644 index 00000000..b45de3e2 --- /dev/null +++ b/app/rcc/images/tip.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/app/rcc/rcc.qrc b/app/rcc/rcc.qrc index d517a81c..7489e535 100644 --- a/app/rcc/rcc.qrc +++ b/app/rcc/rcc.qrc @@ -12,15 +12,19 @@ icons/code-editor/redo.svg icons/code-editor/save.svg icons/code-editor/undo.svg - icons/toolbar/bug.svg + icons/panes/console.svg + icons/panes/setup.svg + icons/toolbar/about.svg icons/toolbar/connect.svg icons/toolbar/console.svg icons/toolbar/csv.svg icons/toolbar/dashboard.svg + icons/toolbar/device-setup.svg icons/toolbar/disconnect.svg + icons/toolbar/github.svg icons/toolbar/help.svg - icons/toolbar/project-editor.svg - icons/toolbar/setup.svg + icons/toolbar/mqtt.svg + icons/toolbar/project-setup.svg images/donate-qr.svg images/icon-small@1x.png images/icon-small@2x.png @@ -36,5 +40,23 @@ themes/Breeze.json themes/Dark.json themes/Light.json + images/tip.svg + images/code.svg + icons/buttons/media-next.svg + icons/buttons/media-pause.svg + icons/buttons/media-play.svg + icons/buttons/media-prev.svg + icons/buttons/apply.svg + icons/buttons/open.svg + icons/buttons/visibility.svg + icons/buttons/connected.svg + icons/buttons/disconnected.svg + icons/buttons/close.svg + icons/buttons/clear.svg + icons/buttons/print.svg + icons/buttons/save.svg + images/microcontroller.svg + icons/panes/dashboard.svg + icons/panes/view.svg diff --git a/app/rcc/themes/Breeze.json b/app/rcc/themes/Breeze.json index 9e37d5bd..2bf4d276 100644 --- a/app/rcc/themes/Breeze.json +++ b/app/rcc/themes/Breeze.json @@ -1,65 +1,68 @@ { - "title": "Classic", - "colors": { - "groupbox_background": "#eff0f1", - "groupbox_border": "#c2c2c2", - "groupbox_hard_border": "#d4d4d4", - "titlebar_text": "#ffffff", - "switch_highlight": "#3daee9", - "tooltip_background": "#e7e8eb", - "tooltip_border": "#b2b2b2", - "tooltip_text": "#232629", - "toolbar_active_top": "#475057", - "toolbar_active_bottom": "#475057", - "toolbar_inactive_top": "#475057", - "toolbar_inactive_bottom": "#475057", - "toolbar_border": "#595E63", - "toolbar_separator": "#595E63", - "toolbar_text": "#ffffff", - "preview_background": "#E0E3E5", - "setup_border": "#b2b2b2", - "inventory_tag_border":"#b2b2b2", - "inventory_tag_background": "#E0E3E5", - "inventory_background": "#fcfcfc", - "inventory_model_highlight": "#3daee9", - "inventory_switch_highlight": "#3daee9", - "pane_caption_bg_top": "#394046", - "pane_caption_bg_bottom": "#475057", - "pane_caption_foreground": "#ffffff", - "pane_caption_border": "#595E63", - "pane_hard_caption_bg_top": "#D5D8DA", - "pane_hard_caption_bg_bottom": "#cbced1", - "pane_hard_caption_foreground": "#232629", - "pane_hard_caption_border": "#bebebe", - "pane_background": "#F9F9F9", - "pane_section_label": "#232629", - "toolbar_checked_button_border": "#394046", - "toolbar_checked_button_background": "#394046", - "toolbar_checked_button_opacity": 0.7, - "text": "#232629", - "base": "#F9F9F9", - "button": "#eff0f1", - "window": "#F9F9F9", - "highlight": "#3daee9", - "button_text": "#232629", - "highlighted_text": "#ffffff", - "placeholder_text": "#929497", - "console_foreground":"#B0E1BA", - "console_background":"#3F4E5D", - "console_placeholder":"#7c948b", - "widget_control": "#000", - "widget_text": "#000", - "widget_colors": [ - "#7eb9f5", - "#fcb9b2", - "#f9e07f", - "#b0e1ba", - "#f7d6e0", - "#ff8eb0", - "#bebebe", - "#c1e7e3", - "#ffc195", - "#b8a9c9" - ] - } + "title": "Breeze", + "colors": { + "groupbox_border": "#c2c2c2", + "groupbox_background": "#eff0f1", + "groupbox_hard_border": "#d4d4d4", + + "pane_background": "#f9f9f9", + "pane_section_label": "#232629", + "pane_caption_bg_top": "#394046", + "pane_caption_border": "#595E63", + "pane_caption_bg_bottom": "#475057", + "pane_caption_foreground": "#ffffff", + + "pane_hard_caption_bg_top": "#d5d8dA", + "pane_hard_caption_border": "#bebebe", + "pane_hard_caption_bg_bottom": "#cbced1", + "pane_hard_caption_foreground": "#232629", + + "setup_border": "#b2b2b2", + "toolbar_top": "#475057", + "titlebar_text": "#ffffff", + "toolbar_text": "#ffffff", + "toolbar_bottom": "#475057", + "toolbar_border": "#595E63", + "toolbar_separator": "#595E63", + "toolbar_checked_button_opacity": 0.7, + "toolbar_checked_button_border": "#394046", + "toolbar_checked_button_background": "#394046", + + "csv_switch": "#3dae2f", + "view_switch": "#3daee9", + "switch_highlight": "#3daee9", + + "text": "#232629", + "base": "#f9f9f9", + "button": "#eff0f1", + "window": "#f9f9f9", + "highlight": "#3daee9", + "button_text": "#232629", + "highlighted_text": "#ffffff", + "placeholder_text": "#929497", + + "console_text": "#434649", + "console_base": "#fcfcfc", + "console_button": "#eff0f1", + "console_window": "#f9f9f9", + "console_highlight": "#3daee9", + "console_button_text": "#232629", + "console_highlighted_text": "#ffffff", + "console_placeholder_text": "#929497", + + "widget_control": "#f6f6f6", + "widget_text": "#232629", + "widget_colors": [ + "#7eb9f5", + "#fcb9b2", + "#f9e07f", + "#b0e1ba", + "#f7d6e0", + "#ff8eb0", + "#bebebe", + "#c1e7e3", + "#ffc195", + "#b8a9c9" + ] + } } diff --git a/app/rcc/themes/Dark.json b/app/rcc/themes/Dark.json index 2f2099cb..e9123b9c 100644 --- a/app/rcc/themes/Dark.json +++ b/app/rcc/themes/Dark.json @@ -12,10 +12,8 @@ "tooltip_background": "#2e3439", "tooltip_border": "#43494F", "tooltip_text": "#eff0f1", - "toolbar_active_top": "#31363A", - "toolbar_active_bottom": "#31363A", - "toolbar_inactive_top": "#31363A", - "toolbar_inactive_bottom": "#31363A", + "toolbar_top": "#31363A", + "toolbar_bottom": "#31363A", "toolbar_border": "#43494F", "toolbar_separator": "#43494F", "toolbar_text": "#eff0f1", diff --git a/app/rcc/themes/Light.json b/app/rcc/themes/Light.json index e9aa2a11..6cec6659 100644 --- a/app/rcc/themes/Light.json +++ b/app/rcc/themes/Light.json @@ -12,10 +12,8 @@ "tooltip_background": "#e7e8eb", "tooltip_border": "#b2b2b2", "tooltip_text": "#232629", - "toolbar_active_top": "#dee0e2", - "toolbar_active_bottom": "#dee0e2", - "toolbar_inactive_top": "#dee0e2", - "toolbar_inactive_bottom": "#dee0e2", + "toolbar_top": "#dee0e2", + "toolbar_bottom": "#dee0e2", "toolbar_border": "#bebebe", "toolbar_separator": "#bebebe", "toolbar_text": "#232629", diff --git a/app/src/Misc/CommonFonts.cpp b/app/src/Misc/CommonFonts.cpp index 3c060e65..e3f69b99 100644 --- a/app/src/Misc/CommonFonts.cpp +++ b/app/src/Misc/CommonFonts.cpp @@ -53,11 +53,13 @@ Misc::CommonFonts::CommonFonts() QStringLiteral("Regular"), 12); m_monoFont = QFontDatabase::font(QStringLiteral("Hack"), QStringLiteral("Regular"), 12); + m_boldUiFont = QFontDatabase::font(QStringLiteral("Inter"), + QStringLiteral("Bold"), 12); // Set pixel sizes for each font m_uiFont.setPixelSize(12); m_monoFont.setPixelSize(12); - m_sansFont.setPixelSize(12); + m_boldUiFont.setPixelSize(12); } /** @@ -88,6 +90,15 @@ const QFont &Misc::CommonFonts::monoFont() const return m_monoFont; } +/** + * @brief Retrieves the bold UI font. + * @return The bold UI font. + */ +const QFont &Misc::CommonFonts::boldUiFont() const +{ + return m_boldUiFont; +} + /** * @brief Creates a custom UI font with specified pixel size and boldness. * @param pixelSize The pixel size of the font. diff --git a/app/src/Misc/CommonFonts.h b/app/src/Misc/CommonFonts.h index 7ef7f02d..64e71033 100644 --- a/app/src/Misc/CommonFonts.h +++ b/app/src/Misc/CommonFonts.h @@ -41,6 +41,9 @@ class CommonFonts : public QObject Q_PROPERTY(const QFont& monoFont READ monoFont CONSTANT) + Q_PROPERTY(const QFont& boldUiFont + READ boldUiFont + CONSTANT) // clang-format on private: @@ -56,13 +59,14 @@ public: [[nodiscard]] const QFont &uiFont() const; [[nodiscard]] const QFont &monoFont() const; + [[nodiscard]] const QFont &boldUiFont() const; Q_INVOKABLE static QFont customUiFont(int pixelSize = 12, bool bold = false); Q_INVOKABLE static QFont customMonoFont(int pixelSize = 12); private: QFont m_uiFont; - QFont m_sansFont; QFont m_monoFont; + QFont m_boldUiFont; }; } // namespace Misc diff --git a/app/src/Misc/ModuleManager.cpp b/app/src/Misc/ModuleManager.cpp index f2174363..b39e391b 100644 --- a/app/src/Misc/ModuleManager.cpp +++ b/app/src/Misc/ModuleManager.cpp @@ -55,6 +55,7 @@ #include #include +#include /** * Configures the application font and configures application signals/slots to @@ -152,31 +153,8 @@ void Misc::ModuleManager::initializeQmlInterface() // Initialize third-party modules auto updater = QSimpleUpdater::getInstance(); - // Operating system flags - bool isWin = false; - bool isMac = false; - bool isNix = false; - QString osName = tr("Unknown OS"); -#if defined(Q_OS_MAC) - isMac = true; - osName = "macOS"; -#elif defined(Q_OS_WIN) - isWin = true; - osName = "Windows"; -#elif defined(Q_OS_LINUX) - isNix = true; - osName = "GNU/Linux"; -#else - isNix = true; - osName = "UNIX"; -#endif - - // Qt version QML flag -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - const bool qt6 = false; -#else - const bool qt6 = true; -#endif + // Initialize non-singleton modules + NativeWindow nativeWindow; // Start common event timers miscTimerEvents->startTimers(); @@ -187,11 +165,6 @@ void Misc::ModuleManager::initializeQmlInterface() // Register C++ modules with QML auto c = engine()->rootContext(); - c->setContextProperty("Cpp_Qt6", qt6); - c->setContextProperty("Cpp_IsWin", isWin); - c->setContextProperty("Cpp_IsMac", isMac); - c->setContextProperty("Cpp_IsNix", isNix); - c->setContextProperty("Cpp_OSName", osName); c->setContextProperty("Cpp_Updater", updater); c->setContextProperty("Cpp_IO_Serial", ioSerial); c->setContextProperty("Cpp_CSV_Export", csvExport); @@ -200,6 +173,7 @@ void Misc::ModuleManager::initializeQmlInterface() c->setContextProperty("Cpp_IO_Manager", ioManager); c->setContextProperty("Cpp_IO_Network", ioNetwork); c->setContextProperty("Cpp_MQTT_Client", mqttClient); + c->setContextProperty("Cpp_NativeWindow", &nativeWindow); c->setContextProperty("Cpp_UI_Dashboard", uiDashboard); c->setContextProperty("Cpp_Project_Model", projectModel); c->setContextProperty("Cpp_JSON_Generator", jsonGenerator); diff --git a/app/src/Misc/ThemeManager.cpp b/app/src/Misc/ThemeManager.cpp index 7a8de7f1..b0f45b9c 100644 --- a/app/src/Misc/ThemeManager.cpp +++ b/app/src/Misc/ThemeManager.cpp @@ -41,13 +41,28 @@ Misc::ThemeManager::ThemeManager() { // Set theme files QStringList themes = { - QStringLiteral(":/rcc/themes/Breeze.json"), - QStringLiteral(":/rcc/themes/Light.json"), - QStringLiteral(":/rcc/themes/Dark.json"), + QStringLiteral(":/themes/Breeze.json"), + QStringLiteral(":/themes/Light.json"), + QStringLiteral(":/themes/Dark.json"), }; + // Load theme files + foreach (auto theme, themes) + { + QFile file(theme); + if (file.open(QFile::ReadOnly)) + { + auto document = QJsonDocument::fromJson(file.readAll()); + auto title = document.object().value("title").toString(); + auto colors = document.object().value("colors").toObject(); + m_themes.insert(title, colors); + + file.close(); + } + } + // Set application theme - setTheme(m_settings.value("Theme", 1).toInt()); + setTheme(0); // Automatically react to theme changes qApp->installEventFilter(this); @@ -112,33 +127,6 @@ QColor Misc::ThemeManager::getColor(const QString &name) const return QColor("#f0f"); } -/** - * @brief Event filter to intercept application-wide events. - * - * This method is an overridden event filter that specifically listens for the - * @c QEvent::ApplicationPaletteChange event. - * - * When this event is detected, it triggers a theme update to match the new - * system palette. - * - * @param watched The object where the event originated. - * @param event The event that is being filtered. - * @return true if the event was handled and should not be processed further - */ -bool Misc::ThemeManager::eventFilter(QObject *watched, QEvent *event) -{ - if (event->type() == QEvent::ApplicationPaletteChange) - { - if (theme() == 0) - { - setTheme(0); - return true; - } - } - - return QObject::eventFilter(watched, event); -} - /** * @brief Sets the current theme to the theme at the specified index. * @@ -149,18 +137,12 @@ bool Misc::ThemeManager::eventFilter(QObject *watched, QEvent *event) */ void Misc::ThemeManager::setTheme(const int index) { - // Load colors from theme - auto fixedIndex = index; - if (index > 0 && index < availableThemes().count()) + if (index >= 0 && index < availableThemes().count()) + { + m_theme = index; + m_settings.setValue("Theme", index); m_themeName = availableThemes().at(index); - else - fixedIndex = 0; - - // Update the theme - m_theme = fixedIndex; - m_settings.setValue("Theme", fixedIndex); - m_colors = m_themes.value(m_themeName); - - // Update UI - Q_EMIT themeChanged(); + m_colors = m_themes.value(m_themeName); + Q_EMIT themeChanged(); + } } diff --git a/app/src/Misc/ThemeManager.h b/app/src/Misc/ThemeManager.h index e0c21a5e..30225b38 100644 --- a/app/src/Misc/ThemeManager.h +++ b/app/src/Misc/ThemeManager.h @@ -109,9 +109,6 @@ public: public Q_SLOTS: void setTheme(int index); -protected: - bool eventFilter(QObject *watched, QEvent *event) override; - private: int m_theme; QString m_themeName; diff --git a/app/src/Project/CodeEditor.cpp b/app/src/Project/CodeEditor.cpp index 51e12c4e..bbb7c03a 100644 --- a/app/src/Project/CodeEditor.cpp +++ b/app/src/Project/CodeEditor.cpp @@ -44,18 +44,18 @@ Project::CodeEditor::CodeEditor() // Setup toolbar // clang-format off - auto acNew = m_toolbar.addAction(QIcon(":/code-editor-icons/new.svg"), tr("New")); - auto acOpen = m_toolbar.addAction(QIcon(":/code-editor-icons/open.svg"), tr("Open")); - auto acSave = m_toolbar.addAction(QIcon(":/code-editor-icons/save.svg"), tr("Save")); + auto acNew = m_toolbar.addAction(QIcon(":/icons/code-editor/new.svg"), tr("New")); + auto acOpen = m_toolbar.addAction(QIcon(":/icons/code-editor/open.svg"), tr("Open")); + auto acSave = m_toolbar.addAction(QIcon(":/icons/code-editor/save.svg"), tr("Save")); m_toolbar.addSeparator(); - auto acUndo = m_toolbar.addAction(QIcon(":/code-editor-icons/undo.svg"), tr("Undo")); - auto acRedo = m_toolbar.addAction(QIcon(":/code-editor-icons/redo.svg"), tr("Redo")); + auto acUndo = m_toolbar.addAction(QIcon(":/icons/code-editor/undo.svg"), tr("Undo")); + auto acRedo = m_toolbar.addAction(QIcon(":/icons/code-editor/redo.svg"), tr("Redo")); m_toolbar.addSeparator(); - auto acCut = m_toolbar.addAction(QIcon(":/code-editor-icons/cut.svg"), tr("Cut")); - auto acCopy = m_toolbar.addAction(QIcon(":/code-editor-icons/copy.svg"), tr("Copy")); - auto acPaste = m_toolbar.addAction(QIcon(":/code-editor-icons/paste.svg"), tr("Paste")); + auto acCut = m_toolbar.addAction(QIcon(":/icons/code-editor/cut.svg"), tr("Cut")); + auto acCopy = m_toolbar.addAction(QIcon(":/icons/code-editor/copy.svg"), tr("Copy")); + auto acPaste = m_toolbar.addAction(QIcon(":/icons/code-editor/paste.svg"), tr("Paste")); m_toolbar.addSeparator(); - auto acHelp = m_toolbar.addAction(QIcon(":/code-editor-icons/help.svg"), tr("Help")); + auto acHelp = m_toolbar.addAction(QIcon(":/icons/code-editor/help.svg"), tr("Help")); // clang-format on // Connect action signals/slots diff --git a/app/src/Project/Model.cpp b/app/src/Project/Model.cpp index ef5a3f1c..69f8abe5 100644 --- a/app/src/Project/Model.cpp +++ b/app/src/Project/Model.cpp @@ -80,9 +80,13 @@ Project::Model::Model() connect(this, &Project::Model::frameStartSequenceChanged, this, &Project::Model::onModelChanged); - // Load current JSON map file into C++ model + // Re-load JSON map file into C++ model connect(&JSON::Generator::instance(), &JSON::Generator::jsonFileMapChanged, this, &Project::Model::onJsonLoaded); + + // Load current JSON map file into C++ model + if (!JSON::Generator::instance().jsonMapFilepath().isEmpty()) + onJsonLoaded(); } /** diff --git a/app/src/UI/Widgets/Terminal.cpp b/app/src/UI/Widgets/Terminal.cpp index 45d68aa3..19bf85d6 100644 --- a/app/src/UI/Widgets/Terminal.cpp +++ b/app/src/UI/Widgets/Terminal.cpp @@ -53,20 +53,19 @@ Widgets::Terminal::Terminal(QQuickItem *parent) m_textEdit.setSizeAdjustPolicy(QPlainTextEdit::AdjustToContents); // Set widget palette + // clang-format off QPalette palette; auto theme = &Misc::ThemeManager::instance(); palette.setColor(QPalette::Text, theme->getColor("console_text")); palette.setColor(QPalette::Base, theme->getColor("console_base")); palette.setColor(QPalette::Button, theme->getColor("console_button")); palette.setColor(QPalette::Window, theme->getColor("console_window")); + palette.setColor(QPalette::ButtonText, theme->getColor("console_button")); palette.setColor(QPalette::Highlight, theme->getColor("console_highlight")); - palette.setColor(QPalette::HighlightedText, - theme->getColor("console_highlighted_text")); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - palette.setColor(QPalette::PlaceholderText, - theme->getColor("console_placeholder")); -#endif + palette.setColor(QPalette::HighlightedText, theme->getColor("console_highlighted_text")); + palette.setColor(QPalette::PlaceholderText, theme->getColor("console_placeholder_text")); m_textEdit.setPalette(palette); + // clang-format on // Connect signals/slots connect(&IO::Console::instance(), &IO::Console::stringReceived, this, diff --git a/app/src/main.cpp b/app/src/main.cpp index c8995052..1c3d25af 100644 --- a/app/src/main.cpp +++ b/app/src/main.cpp @@ -87,6 +87,8 @@ int main(int argc, char **argv) // Init. application QApplication app(argc, argv); + + // Set application information app.setApplicationName(APP_NAME); app.setApplicationVersion(APP_VERSION); app.setOrganizationName(APP_DEVELOPER);