From a2e2b7b947b78abf6b3f29efa6b74520577416d2 Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Fri, 8 Oct 2021 01:44:12 -0400 Subject: [PATCH 1/9] Add new 'SwiftNav' style * This creates a new Qt Quick Controls 2 style which I have named "SwiftNav". It is selected in the qtquickcontrols2.conf file, and is based on the Material style, with a fallback to the material style in cases where a control is not defined in the style. * Initially I added a TabBar and TabButton control. The TabBar and TabButton controls are styled similar to what is desired in the new orange styling that SwiftNav folks desired. * Note that there are a lot of changes in the colors of the TabButton elements from the old keithel-qt/orange-styling branch. This is to more closely blend in with the connection button on the bottom, and it looks nicer. --- resources/SideNavBar.qml | 15 ++- resources/Theme/Theme.qml | 74 ++++++++++++ resources/Theme/qmldir | 2 + resources/console_resources.qrc | 5 + resources/qtquickcontrols2.conf | 6 +- resources/styles/SwiftNav/CheckBox.qml | 146 ++++++++++++++++++++++++ resources/styles/SwiftNav/TabBar.qml | 53 +++++++++ resources/styles/SwiftNav/TabButton.qml | 88 ++++++++++++++ swiftnav_console/main.py | 1 + 9 files changed, 384 insertions(+), 6 deletions(-) create mode 100644 resources/Theme/Theme.qml create mode 100644 resources/Theme/qmldir create mode 100644 resources/styles/SwiftNav/CheckBox.qml create mode 100644 resources/styles/SwiftNav/TabBar.qml create mode 100644 resources/styles/SwiftNav/TabButton.qml diff --git a/resources/SideNavBar.qml b/resources/SideNavBar.qml index 2bf34a5fb..99c1ba78f 100644 --- a/resources/SideNavBar.qml +++ b/resources/SideNavBar.qml @@ -4,7 +4,7 @@ import QtQuick.Controls 2.3 import QtQuick.Layouts 1.15 import SwiftConsole 1.0 -Rectangle { +Item { property alias curIndex: tab.currentIndex property var tabModel: [{ "name": "Tracking", @@ -36,8 +36,6 @@ Rectangle { "source": Constants.sideNavBar.advancedPath }] - color: Constants.sideNavBar.backgroundColor - ConnectionData { id: connectionData } @@ -83,6 +81,10 @@ Rectangle { contentHeight: Constants.sideNavBar.tabBarHeight contentWidth: Constants.sideNavBar.tabBarWidth currentIndex: Globals.initialMainTabIndex + 1 + background: Rectangle { + color: "#323F48" + } + Component.onCompleted: { logo.checkable = false; } @@ -102,7 +104,9 @@ Rectangle { width: Constants.sideNavBar.tabBarWidth anchors.horizontalCenter: parent.horizontalCenter icon.source: modelData.source - icon.color: checked ? Constants.swiftOrange : Constants.materialGrey + icon.color: !enabled ? Qt.darker("white", 2) : down || checked || hovered ? Constants.swiftOrange : "white" + labelColor: !enabled ? Qt.darker("white", 2) : down || checked ? Constants.swiftOrange : "white" + backgroundColor: hovered ? Qt.darker("#323F48", 1.1) : "#323F48" display: AbstractButton.TextUnderIcon font.pointSize: Constants.smallPointSize padding: Constants.sideNavBar.buttonPadding @@ -135,7 +139,8 @@ Rectangle { Layout.alignment: Qt.AlignBottom Layout.preferredWidth: Constants.sideNavBar.tabBarWidth icon.source: Constants.icons.lightningBoltPath - icon.color: checked ? Constants.swiftOrange : Constants.materialGrey + icon.color: !enabled ? Constants.materialGrey : Constants.swiftOrange + backgroundColor: hovered ? Qt.darker("white", 1.1) : "white" checkable: false padding: Constants.sideNavBar.buttonPadding rightInset: Constants.sideNavBar.buttonInset diff --git a/resources/Theme/Theme.qml b/resources/Theme/Theme.qml new file mode 100644 index 000000000..9018ece5f --- /dev/null +++ b/resources/Theme/Theme.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton + +import QtQuick 2.12 + +QtObject { + readonly property color gray: "#b2b1b1" + readonly property color lightGray: "#dddddd" + readonly property color light: "#ffffff" + readonly property color blue: "#2d548b" + property color mainColor: "#17a81a" + readonly property color dark: "#222222" + readonly property color mainColorDarker: Qt.darker(mainColor, 1.5) + + property int baseSize: 10 + + readonly property int smallSize: 10 + readonly property int largeSize: 16 + + property font font + font.bold: true + font.underline: false + font.pixelSize: 14 + font.family: "arial" +} diff --git a/resources/Theme/qmldir b/resources/Theme/qmldir new file mode 100644 index 000000000..4a58c13a9 --- /dev/null +++ b/resources/Theme/qmldir @@ -0,0 +1,2 @@ +module Theme +singleton Theme 1.0 Theme.qml diff --git a/resources/console_resources.qrc b/resources/console_resources.qrc index 032027b2c..9c136444a 100644 --- a/resources/console_resources.qrc +++ b/resources/console_resources.qrc @@ -100,5 +100,10 @@ BaseComponents/SmallCheckBox.qml BaseComponents/SwiftGroupBox.qml ChartLegend.qml + Theme/qmldir + Theme/Theme.qml + styles/SwiftNav/CheckBox.qml + styles/SwiftNav/TabBar.qml + styles/SwiftNav/TabButton.qml diff --git a/resources/qtquickcontrols2.conf b/resources/qtquickcontrols2.conf index 70d12b8de..2f6cccfa4 100644 --- a/resources/qtquickcontrols2.conf +++ b/resources/qtquickcontrols2.conf @@ -1,8 +1,12 @@ [Controls] -Style=Material +Style=SwiftNav +FallbackStyle=Material [Material] Variant=Dense +# Theme=Light +# Accent= +# Primary= [Default] Font\Family=Roboto diff --git a/resources/styles/SwiftNav/CheckBox.qml b/resources/styles/SwiftNav/CheckBox.qml new file mode 100644 index 000000000..ae819afa9 --- /dev/null +++ b/resources/styles/SwiftNav/CheckBox.qml @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Templates 2.12 as T +import Theme 1.0 + +T.CheckBox { + id: control + + font: Theme.font + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(contentItem.implicitHeight, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + leftPadding: 4 + indicator: Rectangle { + id: checkboxHandle + implicitWidth: Theme.baseSize * 2.6 + implicitHeight: Theme.baseSize * 2.6 + x: control.leftPadding + anchors.verticalCenter: parent.verticalCenter + radius: 2 + border.color: Theme.mainColor + + Rectangle { + id: rectangle + width: Theme.baseSize * 1.4 + height: Theme.baseSize * 1.4 + x: Theme.baseSize * 0.6 + y: Theme.baseSize * 0.6 + radius: Theme.baseSize * 0.4 + visible: false + color: Theme.mainColor + } + + states: [ + State { + name: "unchecked" + when: !control.checked && !control.down + }, + State { + name: "checked" + when: control.checked && !control.down + + PropertyChanges { + target: rectangle + visible: true + } + }, + State { + name: "unchecked_down" + when: !control.checked && control.down + + PropertyChanges { + target: rectangle + color: Theme.mainColorDarker + } + + PropertyChanges { + target: checkboxHandle + border.color: Theme.mainColorDarker + } + }, + State { + name: "checked_down" + extend: "unchecked_down" + when: control.checked && control.down + + PropertyChanges { + target: rectangle + visible: true + } + } + ] + } + + background: Rectangle { + implicitWidth: 140 + implicitHeight: Theme.baseSize * 3.8 + color: Theme.lightGray + border.color: Theme.gray + } + + contentItem: Text { + leftPadding: control.indicator.width + 4 + + text: control.text + font: control.font + color: Theme.dark + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } +} + diff --git a/resources/styles/SwiftNav/TabBar.qml b/resources/styles/SwiftNav/TabBar.qml new file mode 100644 index 000000000..517b5d953 --- /dev/null +++ b/resources/styles/SwiftNav/TabBar.qml @@ -0,0 +1,53 @@ +import QtQuick 2.12 +import QtQuick.Templates 2.12 as T +import QtQuick.Controls.Material 2.12 +import QtQuick.Controls.Material.impl 2.12 + +T.TabBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 1 + + contentItem: ListView { + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem + + highlightMoveDuration: 250 + highlightResizeDuration: 0 + highlightFollowsCurrentItem: true + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 48 + preferredHighlightEnd: width - 48 + + highlight: Item { + z: 2 + Rectangle { + height: 2 + width: parent.width + y: control.position === T.TabBar.Footer ? 0 : parent.height - height + color: control.Material.accentColor + } + } + } + + background: Rectangle { + color: control.Material.backgroundColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + fullWidth: true + } + } +} diff --git a/resources/styles/SwiftNav/TabButton.qml b/resources/styles/SwiftNav/TabButton.qml new file mode 100644 index 000000000..e3c09e122 --- /dev/null +++ b/resources/styles/SwiftNav/TabButton.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Templates 2.12 as T +import QtQuick.Controls 2.12 +import QtQuick.Controls.impl 2.12 +import QtQuick.Controls.Material 2.12 +import QtQuick.Controls.Material.impl 2.12 +import "../Constants" + +T.TabButton { + id: control + + property color labelColor: !control.enabled ? control.Material.hintTextColor : control.down || control.checked ? "white" : control.Material.foreground + property color backgroundColor: down || checked ? Constants.swiftOrange : hovered ? Qt.darker("white", 1.1) : "white" + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 6 + + icon.width: 24 + icon.height: 24 + icon.color: !enabled ? Material.hintTextColor : down || checked ? Constants.swiftOrange : Material.foreground + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.labelColor + } + + background: Rectangle { + implicitHeight: control.Material.touchTarget + + clip: true + color: backgroundColor + } + // background: Ripple { + // implicitHeight: control.Material.touchTarget + + // clip: true + // pressed: control.pressed + // anchor: control + // active: control.down || control.checked || control.visualFocus || control.hovered + // color: backgroundColor + // } +} diff --git a/swiftnav_console/main.py b/swiftnav_console/main.py index 642028a8f..625b40699 100644 --- a/swiftnav_console/main.py +++ b/swiftnav_console/main.py @@ -837,6 +837,7 @@ def handle_qml_load_errors(obj, _url): capnp_path = get_capnp_path() engine.addImportPath("PySide2") + engine.addImportPath(":/") engine.load(QUrl("qrc:/view.qml")) if not qml_object_created[0]: return 1 From 30ae6cd13cd3b408e995ad2b6b663ffc13a467b7 Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Fri, 8 Oct 2021 19:33:44 -0400 Subject: [PATCH 2/9] TabBar and TabButton orange styling * This achieves 90% of the new orange styling guidelines for TabBars and TabButtons used in the console. * Current problems exist in the sidebar outlining. This isn't quite right, and I think the outline should not be drawn in the style control in this case, and instead drawn by the code using it. cherry-pick notes: Significant changes from the version of this commit in the old keithel-qt/orange-styling. --- resources/Constants/Constants.qml | 2 +- resources/SideNavBar.qml | 2 ++ resources/TrackingTab.qml | 2 ++ resources/qtquickcontrols2.conf | 2 +- resources/styles/SwiftNav/TabBar.qml | 35 +++++++++++++++++++------ resources/styles/SwiftNav/TabButton.qml | 14 ++++++++-- resources/view.qml | 3 +-- 7 files changed, 46 insertions(+), 14 deletions(-) diff --git a/resources/Constants/Constants.qml b/resources/Constants/Constants.qml index a958b6726..a2aa67dce 100644 --- a/resources/Constants/Constants.qml +++ b/resources/Constants/Constants.qml @@ -6,7 +6,7 @@ pragma Singleton QtObject { readonly property real margins: 2 readonly property real tabBarWidth: 70 - readonly property real tabBarHeight: 40 + readonly property real tabBarHeight: 45 readonly property real topLevelSpacing: 0 readonly property real logPanelPreferredHeight: 100 readonly property int loggingBarPreferredHeight: 50 diff --git a/resources/SideNavBar.qml b/resources/SideNavBar.qml index 99c1ba78f..505416d32 100644 --- a/resources/SideNavBar.qml +++ b/resources/SideNavBar.qml @@ -103,6 +103,7 @@ Item { text: modelData.name width: Constants.sideNavBar.tabBarWidth anchors.horizontalCenter: parent.horizontalCenter + border: false icon.source: modelData.source icon.color: !enabled ? Qt.darker("white", 2) : down || checked || hovered ? Constants.swiftOrange : "white" labelColor: !enabled ? Qt.darker("white", 2) : down || checked ? Constants.swiftOrange : "white" @@ -138,6 +139,7 @@ Item { Layout.alignment: Qt.AlignBottom Layout.preferredWidth: Constants.sideNavBar.tabBarWidth + border: false icon.source: Constants.icons.lightningBoltPath icon.color: !enabled ? Constants.materialGrey : Constants.swiftOrange backgroundColor: hovered ? Qt.darker("white", 1.1) : "white" diff --git a/resources/TrackingTab.qml b/resources/TrackingTab.qml index eb4da422a..f6e558299 100644 --- a/resources/TrackingTab.qml +++ b/resources/TrackingTab.qml @@ -13,6 +13,8 @@ Item { TabBar { id: trackingBar + anchors.left: parent.left + anchors.right: parent.right z: Constants.commonChart.zAboveCharts currentIndex: Globals.initialMainTabIndex == 0 ? Globals.initialSubTabIndex : 0 diff --git a/resources/qtquickcontrols2.conf b/resources/qtquickcontrols2.conf index 2f6cccfa4..b721e116c 100644 --- a/resources/qtquickcontrols2.conf +++ b/resources/qtquickcontrols2.conf @@ -4,8 +4,8 @@ FallbackStyle=Material [Material] Variant=Dense +Accent="#FF8300" # Theme=Light -# Accent= # Primary= [Default] diff --git a/resources/styles/SwiftNav/TabBar.qml b/resources/styles/SwiftNav/TabBar.qml index 517b5d953..4a6d6c58d 100644 --- a/resources/styles/SwiftNav/TabBar.qml +++ b/resources/styles/SwiftNav/TabBar.qml @@ -11,7 +11,7 @@ T.TabBar { implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding) - spacing: 1 + spacing: -1 contentItem: ListView { model: control.contentModel @@ -33,21 +33,40 @@ T.TabBar { highlight: Item { z: 2 Rectangle { + x: 1 height: 2 - width: parent.width + width: parent.width - 2 y: control.position === T.TabBar.Footer ? 0 : parent.height - height color: control.Material.accentColor } } } - background: Rectangle { - color: control.Material.backgroundColor + background: Item { + Rectangle { + anchors.fill: parent + color: "white" - layer.enabled: control.Material.elevation > 0 - layer.effect: ElevationEffect { - elevation: control.Material.elevation - fullWidth: true + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + fullWidth: true + } + } + + Rectangle { + z: 2 + anchors.top: parent.top + width: parent.width + height: 1 + color: "#C2C2C2" + } + Rectangle { + z: 2 + anchors.bottom: parent.bottom + width: parent.width + height: 1 + color: "#C2C2C2" } } } diff --git a/resources/styles/SwiftNav/TabButton.qml b/resources/styles/SwiftNav/TabButton.qml index e3c09e122..cfd0a4b79 100644 --- a/resources/styles/SwiftNav/TabButton.qml +++ b/resources/styles/SwiftNav/TabButton.qml @@ -45,8 +45,9 @@ import "../Constants" T.TabButton { id: control - property color labelColor: !control.enabled ? control.Material.hintTextColor : control.down || control.checked ? "white" : control.Material.foreground + property color labelColor: !control.enabled ? control.Material.hintTextColor : control.down || control.checked ? "white" : "#C2C2C2" property color backgroundColor: down || checked ? Constants.swiftOrange : hovered ? Qt.darker("white", 1.1) : "white" + property bool border: true implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, @@ -55,9 +56,16 @@ T.TabButton { padding: 12 spacing: 6 + font: Qt.font({ + "family": "Roboto", + "pointSize": Constants.largePointSize, + "bold" : true, + "capitalization": Font.MixedCase + }) + icon.width: 24 icon.height: 24 - icon.color: !enabled ? Material.hintTextColor : down || checked ? Constants.swiftOrange : Material.foreground + icon.color: !enabled ? Material.hintTextColor : down || checked ? Constants.swiftOrange : "#C2C2C2" contentItem: IconLabel { spacing: control.spacing @@ -71,6 +79,8 @@ T.TabButton { } background: Rectangle { + border.width: control.border ? 1 : 0 + border.color: "#C2C2C2" implicitHeight: control.Material.touchTarget clip: true diff --git a/resources/view.qml b/resources/view.qml index 7af7fb5cf..6f146a24c 100644 --- a/resources/view.qml +++ b/resources/view.qml @@ -33,6 +33,7 @@ ApplicationWindow { property alias stackView: dialogStack.dialogStack anchors.fill: parent + spacing: 0 SideNavBar { id: sideNavBar @@ -76,8 +77,6 @@ ApplicationWindow { orientation: Qt.Vertical Layout.fillWidth: true Layout.fillHeight: true - Layout.leftMargin: Constants.margins - Layout.rightMargin: Constants.margins Layout.alignment: Qt.AlignTop MainTabs { From 399e9db82db9548e2d167495542e470af09a6c98 Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Wed, 13 Oct 2021 15:53:09 -0400 Subject: [PATCH 3/9] Remove checkbox from resources --- resources/console_resources.qrc | 1 - resources/styles/SwiftNav/CheckBox.qml | 146 ------------------------- 2 files changed, 147 deletions(-) delete mode 100644 resources/styles/SwiftNav/CheckBox.qml diff --git a/resources/console_resources.qrc b/resources/console_resources.qrc index 9c136444a..241fa287a 100644 --- a/resources/console_resources.qrc +++ b/resources/console_resources.qrc @@ -102,7 +102,6 @@ ChartLegend.qml Theme/qmldir Theme/Theme.qml - styles/SwiftNav/CheckBox.qml styles/SwiftNav/TabBar.qml styles/SwiftNav/TabButton.qml diff --git a/resources/styles/SwiftNav/CheckBox.qml b/resources/styles/SwiftNav/CheckBox.qml deleted file mode 100644 index ae819afa9..000000000 --- a/resources/styles/SwiftNav/CheckBox.qml +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.12 -import QtQuick.Templates 2.12 as T -import Theme 1.0 - -T.CheckBox { - id: control - - font: Theme.font - - implicitWidth: Math.max(background ? background.implicitWidth : 0, - contentItem.implicitWidth + leftPadding + rightPadding) - implicitHeight: Math.max(background ? background.implicitHeight : 0, - Math.max(contentItem.implicitHeight, - indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) - leftPadding: 4 - indicator: Rectangle { - id: checkboxHandle - implicitWidth: Theme.baseSize * 2.6 - implicitHeight: Theme.baseSize * 2.6 - x: control.leftPadding - anchors.verticalCenter: parent.verticalCenter - radius: 2 - border.color: Theme.mainColor - - Rectangle { - id: rectangle - width: Theme.baseSize * 1.4 - height: Theme.baseSize * 1.4 - x: Theme.baseSize * 0.6 - y: Theme.baseSize * 0.6 - radius: Theme.baseSize * 0.4 - visible: false - color: Theme.mainColor - } - - states: [ - State { - name: "unchecked" - when: !control.checked && !control.down - }, - State { - name: "checked" - when: control.checked && !control.down - - PropertyChanges { - target: rectangle - visible: true - } - }, - State { - name: "unchecked_down" - when: !control.checked && control.down - - PropertyChanges { - target: rectangle - color: Theme.mainColorDarker - } - - PropertyChanges { - target: checkboxHandle - border.color: Theme.mainColorDarker - } - }, - State { - name: "checked_down" - extend: "unchecked_down" - when: control.checked && control.down - - PropertyChanges { - target: rectangle - visible: true - } - } - ] - } - - background: Rectangle { - implicitWidth: 140 - implicitHeight: Theme.baseSize * 3.8 - color: Theme.lightGray - border.color: Theme.gray - } - - contentItem: Text { - leftPadding: control.indicator.width + 4 - - text: control.text - font: control.font - color: Theme.dark - elide: Text.ElideRight - visible: control.text - horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter - } -} - From c0c473b46ca483168f334d2d583d874fe8bdf809 Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Fri, 12 Nov 2021 00:57:31 -0500 Subject: [PATCH 4/9] Use TabBar's standard contentItem, expose orientation * Expose the orientation setting of the ListView content item of TabBar, allowing a user to specify an orientation for the TabBar. * Remove TabBar contentItem override in SideNavBar, use new orientation property of TabBar. --- resources/SideNavBar.qml | 9 ++------- resources/styles/SwiftNav/TabBar.qml | 4 +++- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/resources/SideNavBar.qml b/resources/SideNavBar.qml index 505416d32..926bcf799 100644 --- a/resources/SideNavBar.qml +++ b/resources/SideNavBar.qml @@ -81,6 +81,8 @@ Item { contentHeight: Constants.sideNavBar.tabBarHeight contentWidth: Constants.sideNavBar.tabBarWidth currentIndex: Globals.initialMainTabIndex + 1 + spacing: Constants.sideNavBar.tabBarSpacing + orientation: ListView.Vertical background: Rectangle { color: "#323F48" } @@ -125,13 +127,6 @@ Item { } - contentItem: ListView { - model: tab.contentModel - currentIndex: tab.currentIndex - spacing: Constants.sideNavBar.tabBarSpacing - orientation: ListView.Vertical - } - } TabButton { diff --git a/resources/styles/SwiftNav/TabBar.qml b/resources/styles/SwiftNav/TabBar.qml index 4a6d6c58d..260a7e2bf 100644 --- a/resources/styles/SwiftNav/TabBar.qml +++ b/resources/styles/SwiftNav/TabBar.qml @@ -6,6 +6,8 @@ import QtQuick.Controls.Material.impl 2.12 T.TabBar { id: control + property var orientation: ListView.Horizontal + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, contentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, @@ -18,7 +20,7 @@ T.TabBar { currentIndex: control.currentIndex spacing: control.spacing - orientation: ListView.Horizontal + orientation: control.orientation boundsBehavior: Flickable.StopAtBounds flickableDirection: Flickable.AutoFlickIfNeeded snapMode: ListView.SnapToItem From 462e05103bdb8fed9e3c12add659bff7d978cc26 Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Tue, 16 Nov 2021 17:50:42 -0500 Subject: [PATCH 5/9] Refactored SideBar without TabBar * Introduce a whole new SideBar implementation that does not use TabBar. * SideNavButton customized button type added, allows for much more customization to the look of the SideNavBar buttons. * ListView used to display the buttons, allows more freedom to customize look and feel over TabBar, and is designed to be used vertically. * Adopt the new design guidelines as is shown in mockups in slack: https://snav.slack.com/archives/C02DG3HAHT8/p1632876609129100 * Fix current index of MainTab corresponding to selected SideNavBar tab. (was 1s based, now 0 based) --- resources/Constants/Constants.qml | 5 +- resources/Constants/utils.js | 8 ++ resources/MainTabs.qml | 5 +- resources/SideNavBar.qml | 88 ++++++++---------- .../SideNavBarComponents/SideNavButton.qml | 93 +++++++++++++++++++ resources/console_resources.qrc | 1 + resources/view.qml | 4 +- 7 files changed, 147 insertions(+), 57 deletions(-) create mode 100644 resources/SideNavBarComponents/SideNavButton.qml diff --git a/resources/Constants/Constants.qml b/resources/Constants/Constants.qml index a2aa67dce..2581bf228 100644 --- a/resources/Constants/Constants.qml +++ b/resources/Constants/Constants.qml @@ -50,6 +50,8 @@ QtObject { readonly property real mediumPointSize: 8 readonly property real largePointSize: 9 readonly property bool debugMode: false + readonly property color swiftGrey: "#323F48" + readonly property color swiftLightGrey: "#3C464F" readonly property color materialGrey: "dimgrey" readonly property color swiftOrange: "#FF8300" @@ -92,8 +94,7 @@ QtObject { readonly property string updatePath: "qrc:///images/fontawesome/chevron-circle-up-solid.svg" readonly property string advancedPath: "qrc:///images/fontawesome/lock-solid.svg" readonly property real tabBarHeight: 45 - readonly property real tabBarWidth: 70 - readonly property int tabBarSpacing: 10 + readonly property real tabBarWidth: 50 readonly property int buttonPadding: 0 readonly property int buttonInset: 0 readonly property int separatorMargin: 10 diff --git a/resources/Constants/utils.js b/resources/Constants/utils.js index 7a3550887..2c20a23a5 100644 --- a/resources/Constants/utils.js +++ b/resources/Constants/utils.js @@ -34,3 +34,11 @@ function readTextFile(path, elem){ req.open("GET", path); req.send(); } + +// Dump all properties in a QML item (or any javascript object). +function listProperty(item) +{ + for (var p in item) + if (typeof item[p] != "function") + console.log(p + ": " + item[p]); +} diff --git a/resources/MainTabs.qml b/resources/MainTabs.qml index 1e87110fa..14b19a1fc 100644 --- a/resources/MainTabs.qml +++ b/resources/MainTabs.qml @@ -4,14 +4,11 @@ import QtQuick.Layouts 1.15 import SwiftConsole 1.0 Item { + property alias currentIndex: stackLayout.currentIndex StackLayout { id: stackLayout anchors.fill: parent - currentIndex: parent.curIndex - - Item { - } TrackingTab { } diff --git a/resources/SideNavBar.qml b/resources/SideNavBar.qml index 926bcf799..05db38458 100644 --- a/resources/SideNavBar.qml +++ b/resources/SideNavBar.qml @@ -1,11 +1,12 @@ +import "SideNavBarComponents" import "Constants" -import QtQuick 2.5 -import QtQuick.Controls 2.3 +import QtQuick 2.15 +import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import SwiftConsole 1.0 Item { - property alias curIndex: tab.currentIndex + property alias currentIndex: navButtons.currentIndex property var tabModel: [{ "name": "Tracking", "tooltip": "Tracking", @@ -51,6 +52,11 @@ Item { padding: Constants.sideNavBar.buttonPadding icon.source: Constants.icons.swiftLogoPath icon.color: "transparent" + icon.width: 32 + icon.height: 32 + checkable: false + ToolTip.delay: 1000 + ToolTip.timeout: 5000 ToolTip.visible: hovered ToolTip.text: "About this application" onClicked: { @@ -63,7 +69,7 @@ Item { } Rectangle { - color: Constants.materialGrey + color: Constants.swiftLightGrey Layout.alignment: Qt.AlignHCenter Layout.preferredHeight: Constants.sideNavBar.separatorHeight Layout.fillWidth: true @@ -71,62 +77,48 @@ Item { Layout.leftMargin: Constants.sideNavBar.separatorMargin } - TabBar { - id: tab - + Rectangle { Layout.fillWidth: true Layout.fillHeight: true - z: Constants.commonChart.zAboveCharts - height: parent.height - contentHeight: Constants.sideNavBar.tabBarHeight - contentWidth: Constants.sideNavBar.tabBarWidth - currentIndex: Globals.initialMainTabIndex + 1 - spacing: Constants.sideNavBar.tabBarSpacing - orientation: ListView.Vertical - background: Rectangle { - color: "#323F48" - } - - Component.onCompleted: { - logo.checkable = false; - } + color: Constants.swiftGrey + + ButtonGroup { + id: navButtonGroup + buttons: navButtons.children + onCheckedButtonChanged: { + for (var idx = 0; idx < buttons.length && buttons[idx] != checkedButton; idx++); + navButtons.currentIndex = idx; + } - TabButton { - enabled: false - height: 0 } - Repeater { - id: repeater + ListView { + id: navButtons + anchors.fill: parent model: tabModel + currentIndex: Globals.initialMainTabIndex + + highlightMoveDuration: 200 + highlightResizeDuration: 0 + highlightFollowsCurrentItem: true + highlight: Item { + // TODO: This is an odd z order which depends on the Z order of some things in the buttons, refactor. + z: 6 + Rectangle { + height: 2 + width: parent.width + y: parent.height - height + color: Constants.swiftOrange + } - TabButton { - text: modelData.name - width: Constants.sideNavBar.tabBarWidth - anchors.horizontalCenter: parent.horizontalCenter - border: false - icon.source: modelData.source - icon.color: !enabled ? Qt.darker("white", 2) : down || checked || hovered ? Constants.swiftOrange : "white" - labelColor: !enabled ? Qt.darker("white", 2) : down || checked ? Constants.swiftOrange : "white" - backgroundColor: hovered ? Qt.darker("#323F48", 1.1) : "#323F48" - display: AbstractButton.TextUnderIcon - font.pointSize: Constants.smallPointSize - padding: Constants.sideNavBar.buttonPadding - rightInset: Constants.sideNavBar.buttonInset - leftInset: Constants.sideNavBar.buttonInset - enabled: Globals.connected_at_least_once - ToolTip.visible: hovered - ToolTip.text: modelData.tooltip - onClicked: { - if (stack.connectionScreenVisible()) - stack.mainView(); + } - } + delegate: SideNavButton { + buttonGroup: navButtonGroup } } - } TabButton { diff --git a/resources/SideNavBarComponents/SideNavButton.qml b/resources/SideNavBarComponents/SideNavButton.qml new file mode 100644 index 000000000..c33bbc424 --- /dev/null +++ b/resources/SideNavBarComponents/SideNavButton.qml @@ -0,0 +1,93 @@ +import "../Constants" +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Controls.impl 2.15 + +// This defines a Side Navigation button as is specified in the Style mockup guidelines listed here: +// https://snav.slack.com/archives/C020JLK6PK8/p1637094700036500 +// To make the buttons within exclusive, the user needs to create a ButtonGroup, and assign +// all buttons to that buttongroup +Button { + id: control + + property QtObject buttonGroup + property QtObject view: ListView.view + ButtonGroup.group: buttonGroup + width: view.width + height: implicitHeight < width ? width : implicitHeight + z: visualFocus ? 10 : control.checked || control.highlighted ? 5 : 1 + display: AbstractButton.TextUnderIcon + checkable: true + text: modelData.name + ToolTip.text: modelData.tooltip + ToolTip.delay: 1000 + ToolTip.timeout: 5000 + ToolTip.visible: ToolTip.text.length != 0 && hovered + icon.source: modelData.source + icon.width: 22 + icon.height: 22 + icon.color: control.checked || control.highlighted ? Constants.swiftOrange : + control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : "white" + font.pointSize: Constants.smallPointSize + font.capitalization: Font.MixedCase + font.letterSpacing: -1 + + // No idea why the insets are set, but they need to be 0 so there are no gaps between buttons. + topInset: 0 + bottomInset: 0 + // Padding controls the padding around items within the button. We want to minimize it, so set + // to 0. Realistically if we weren't setting an explicit width (set by the SideBar width), we'd + // want more padding than 0. + padding: 0 + // Spacing controls the spacing between the icon and the text. Default is 6, we reduce this to + // 3 to match the new style mockups. + spacing: 3 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + icon: control.icon + text: control.text + font: control.font + color: control.checked || control.highlighted ? control.palette.dark : + control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : "white" + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: !control.flat || control.down || control.checked || control.highlighted + color: Color.blend(control.checked || control.highlighted ? "white" : Constants.swiftGrey, + control.palette.mid, control.down ? 0.5 : 0.0) + border.color: Constants.swiftOrange + border.width: control.visualFocus ? 1 : 0 + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "white" + visible: !control.visualFocus && + !(control.view.itemAtIndex(index+1) != null ? control.view.itemAtIndex(index+1).visualFocus : false) + } + + Repeater { + model: 2 + Rectangle { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: index == 0 ? parent.left : undefined + anchors.right: index == 1 ? parent.right : undefined + width: 1 + color: Constants.swiftGrey + visible: !control.visualFocus && (control.checked || control.highlighted) + } + } + } + + Component.onCompleted: { + console.assert(buttonGroup != undefined, "No buttonGroup assigned to SideNavButton! Undesired behavior will result.") + } +} \ No newline at end of file diff --git a/resources/console_resources.qrc b/resources/console_resources.qrc index 241fa287a..f503d316a 100644 --- a/resources/console_resources.qrc +++ b/resources/console_resources.qrc @@ -8,6 +8,7 @@ MainDialogView.qml MainTabs.qml SideNavBar.qml + SideNavBarComponents/SideNavButton.qml LogPanel.qml LoggingBar.qml StatusBar.qml diff --git a/resources/view.qml b/resources/view.qml index 6f146a24c..a749b68ff 100644 --- a/resources/view.qml +++ b/resources/view.qml @@ -82,13 +82,11 @@ ApplicationWindow { MainTabs { id: mainTabs - property alias curIndex: sideNavBar.curIndex - property alias logoPopup: logoPopup - SplitView.fillHeight: true SplitView.fillWidth: true Layout.leftMargin: Constants.margins Layout.rightMargin: Constants.margins + currentIndex: sideNavBar.currentIndex } ColumnLayout { From 1d8bf6ce46cb6a22576efb9473e4b2367aeec30b Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Tue, 16 Nov 2021 18:49:52 -0500 Subject: [PATCH 6/9] qmlformat formatting fixes --- resources/MainTabs.qml | 1 + resources/SideNavBar.qml | 10 +++++--- .../SideNavBarComponents/SideNavButton.qml | 25 +++++++++---------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/resources/MainTabs.qml b/resources/MainTabs.qml index 14b19a1fc..bcb9ebc44 100644 --- a/resources/MainTabs.qml +++ b/resources/MainTabs.qml @@ -5,6 +5,7 @@ import SwiftConsole 1.0 Item { property alias currentIndex: stackLayout.currentIndex + StackLayout { id: stackLayout diff --git a/resources/SideNavBar.qml b/resources/SideNavBar.qml index 05db38458..f7a1eab30 100644 --- a/resources/SideNavBar.qml +++ b/resources/SideNavBar.qml @@ -1,8 +1,8 @@ -import "SideNavBarComponents" import "Constants" import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 +import "SideNavBarComponents" import SwiftConsole 1.0 Item { @@ -84,27 +84,28 @@ Item { ButtonGroup { id: navButtonGroup + buttons: navButtons.children onCheckedButtonChanged: { for (var idx = 0; idx < buttons.length && buttons[idx] != checkedButton; idx++); navButtons.currentIndex = idx; } - } ListView { id: navButtons - anchors.fill: parent + anchors.fill: parent model: tabModel currentIndex: Globals.initialMainTabIndex - highlightMoveDuration: 200 highlightResizeDuration: 0 highlightFollowsCurrentItem: true + highlight: Item { // TODO: This is an odd z order which depends on the Z order of some things in the buttons, refactor. z: 6 + Rectangle { height: 2 width: parent.width @@ -119,6 +120,7 @@ Item { } } + } TabButton { diff --git a/resources/SideNavBarComponents/SideNavButton.qml b/resources/SideNavBarComponents/SideNavButton.qml index c33bbc424..dac574e0f 100644 --- a/resources/SideNavBarComponents/SideNavButton.qml +++ b/resources/SideNavBarComponents/SideNavButton.qml @@ -12,6 +12,7 @@ Button { property QtObject buttonGroup property QtObject view: ListView.view + ButtonGroup.group: buttonGroup width: view.width height: implicitHeight < width ? width : implicitHeight @@ -26,12 +27,10 @@ Button { icon.source: modelData.source icon.width: 22 icon.height: 22 - icon.color: control.checked || control.highlighted ? Constants.swiftOrange : - control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : "white" + icon.color: control.checked || control.highlighted ? Constants.swiftOrange : control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : "white" font.pointSize: Constants.smallPointSize font.capitalization: Font.MixedCase font.letterSpacing: -1 - // No idea why the insets are set, but they need to be 0 so there are no gaps between buttons. topInset: 0 bottomInset: 0 @@ -42,6 +41,9 @@ Button { // Spacing controls the spacing between the icon and the text. Default is 6, we reduce this to // 3 to match the new style mockups. spacing: 3 + Component.onCompleted: { + console.assert(buttonGroup != undefined, "No buttonGroup assigned to SideNavButton! Undesired behavior will result."); + } contentItem: IconLabel { spacing: control.spacing @@ -50,16 +52,14 @@ Button { icon: control.icon text: control.text font: control.font - color: control.checked || control.highlighted ? control.palette.dark : - control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : "white" + color: control.checked || control.highlighted ? control.palette.dark : control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : "white" } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: !control.flat || control.down || control.checked || control.highlighted - color: Color.blend(control.checked || control.highlighted ? "white" : Constants.swiftGrey, - control.palette.mid, control.down ? 0.5 : 0.0) + color: Color.blend(control.checked || control.highlighted ? "white" : Constants.swiftGrey, control.palette.mid, control.down ? 0.5 : 0) border.color: Constants.swiftOrange border.width: control.visualFocus ? 1 : 0 @@ -69,12 +69,12 @@ Button { anchors.bottom: parent.bottom height: 1 color: "white" - visible: !control.visualFocus && - !(control.view.itemAtIndex(index+1) != null ? control.view.itemAtIndex(index+1).visualFocus : false) + visible: !control.visualFocus && !(control.view.itemAtIndex(index + 1) != null ? control.view.itemAtIndex(index + 1).visualFocus : false) } Repeater { model: 2 + Rectangle { anchors.top: parent.top anchors.bottom: parent.bottom @@ -84,10 +84,9 @@ Button { color: Constants.swiftGrey visible: !control.visualFocus && (control.checked || control.highlighted) } + } - } - Component.onCompleted: { - console.assert(buttonGroup != undefined, "No buttonGroup assigned to SideNavButton! Undesired behavior will result.") } -} \ No newline at end of file + +} From ca4a330d1c53c054d9fc119bdd552a44ce704c00 Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Tue, 16 Nov 2021 19:00:09 -0500 Subject: [PATCH 7/9] ConnectionScreen separator and SideNavBar enable * Add boundary line between ConnectionScreen and SideNavBar * Remove the topmost swiftnav about button in SideNavBar (it is going elsewhere) * Give SideNavBar an enable property, and have it disabled when the ConnectionScreen is showing, adjust colors appropriately for enabled status. * Make the SideNavButton left and right lines extend higher so they are continuous. This makes those lines go outside the boundary of the button, but there is no clipping, so the drawing occurs as we expect. --- resources/ConnectionScreen.qml | 11 +++-- resources/SideNavBar.qml | 40 ++++--------------- .../SideNavBarComponents/SideNavButton.qml | 14 +++---- resources/view.qml | 1 + 4 files changed, 23 insertions(+), 43 deletions(-) diff --git a/resources/ConnectionScreen.qml b/resources/ConnectionScreen.qml index cab1a8d7d..a11236ac5 100644 --- a/resources/ConnectionScreen.qml +++ b/resources/ConnectionScreen.qml @@ -33,9 +33,7 @@ Item { } Rectangle { - width: parent.width - height: parent.height - anchors.centerIn: parent + anchors.fill: parent Image { width: parent.width @@ -43,6 +41,13 @@ Item { source: Constants.icons.splashScreenPath } + Rectangle { + anchors.left: parent.left + height: parent.height + width: 1 + color: "white" + } + Dialog { id: dialog diff --git a/resources/SideNavBar.qml b/resources/SideNavBar.qml index f7a1eab30..0ef266782 100644 --- a/resources/SideNavBar.qml +++ b/resources/SideNavBar.qml @@ -6,7 +6,10 @@ import "SideNavBarComponents" import SwiftConsole 1.0 Item { + id: top + property alias currentIndex: navButtons.currentIndex + property bool enabled: true property var tabModel: [{ "name": "Tracking", "tooltip": "Tracking", @@ -44,39 +47,6 @@ Item { ColumnLayout { anchors.fill: parent - Button { - id: logo - - Layout.fillWidth: true - Layout.preferredHeight: Constants.sideNavBar.tabBarHeight - padding: Constants.sideNavBar.buttonPadding - icon.source: Constants.icons.swiftLogoPath - icon.color: "transparent" - icon.width: 32 - icon.height: 32 - checkable: false - ToolTip.delay: 1000 - ToolTip.timeout: 5000 - ToolTip.visible: hovered - ToolTip.text: "About this application" - onClicked: { - logoPopup.open(); - } - - background: Item { - } - - } - - Rectangle { - color: Constants.swiftLightGrey - Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: Constants.sideNavBar.separatorHeight - Layout.fillWidth: true - Layout.rightMargin: Constants.sideNavBar.separatorMargin - Layout.leftMargin: Constants.sideNavBar.separatorMargin - } - Rectangle { Layout.fillWidth: true Layout.fillHeight: true @@ -98,9 +68,13 @@ Item { anchors.fill: parent model: tabModel currentIndex: Globals.initialMainTabIndex + enabled: top.enabled highlightMoveDuration: 200 highlightResizeDuration: 0 highlightFollowsCurrentItem: true + Component.onCompleted: { + currentItem.checked = true; + } highlight: Item { // TODO: This is an odd z order which depends on the Z order of some things in the buttons, refactor. diff --git a/resources/SideNavBarComponents/SideNavButton.qml b/resources/SideNavBarComponents/SideNavButton.qml index dac574e0f..96dd5f086 100644 --- a/resources/SideNavBarComponents/SideNavButton.qml +++ b/resources/SideNavBarComponents/SideNavButton.qml @@ -27,7 +27,7 @@ Button { icon.source: modelData.source icon.width: 22 icon.height: 22 - icon.color: control.checked || control.highlighted ? Constants.swiftOrange : control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : "white" + icon.color: control.checked || control.highlighted ? Qt.darker(Constants.swiftOrange, control.enabled ? 1 : 1.5) : control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : Qt.darker("white", control.enabled ? 1 : 1.5) font.pointSize: Constants.smallPointSize font.capitalization: Font.MixedCase font.letterSpacing: -1 @@ -52,14 +52,14 @@ Button { icon: control.icon text: control.text font: control.font - color: control.checked || control.highlighted ? control.palette.dark : control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : "white" + color: control.checked || control.highlighted ? Qt.darker(control.palette.dark, control.enabled ? 1 : 1.5) : control.flat && !control.down ? (control.visualFocus ? Constants.swiftOrange : control.palette.windowText) : Qt.darker("white", control.enabled ? 1 : 1.5) } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: !control.flat || control.down || control.checked || control.highlighted - color: Color.blend(control.checked || control.highlighted ? "white" : Constants.swiftGrey, control.palette.mid, control.down ? 0.5 : 0) + color: Color.blend(control.checked || control.highlighted ? Qt.darker("white", control.enabled ? 1 : 1.5) : Constants.swiftGrey, control.palette.mid, control.down ? 0.5 : 0) border.color: Constants.swiftOrange border.width: control.visualFocus ? 1 : 0 @@ -68,7 +68,7 @@ Button { anchors.right: parent.right anchors.bottom: parent.bottom height: 1 - color: "white" + color: Qt.darker("white", control.enabled ? 1 : 1.5) visible: !control.visualFocus && !(control.view.itemAtIndex(index + 1) != null ? control.view.itemAtIndex(index + 1).visualFocus : false) } @@ -76,13 +76,13 @@ Button { model: 2 Rectangle { - anchors.top: parent.top - anchors.bottom: parent.bottom anchors.left: index == 0 ? parent.left : undefined anchors.right: index == 1 ? parent.right : undefined + y: -1 + height: parent.height + 1 width: 1 color: Constants.swiftGrey - visible: !control.visualFocus && (control.checked || control.highlighted) + visible: !control.visualFocus && (control.checked || control.highlighted) && control.enabled } } diff --git a/resources/view.qml b/resources/view.qml index a749b68ff..4ab5237f8 100644 --- a/resources/view.qml +++ b/resources/view.qml @@ -40,6 +40,7 @@ ApplicationWindow { Layout.fillHeight: true Layout.minimumWidth: Constants.sideNavBar.tabBarWidth + enabled: stack.currentIndex != 0 } StackLayout { From 4d78d28c9586ac4f2be1b80c18a25d7bdf4deab7 Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Tue, 16 Nov 2021 19:21:41 -0500 Subject: [PATCH 8/9] New TabButton coloring based on new design spec * TabButtons are now different colors per new design guidelines shared in https://snav.slack.com/archives/C020JLK6PK8/p1637094700036500 --- resources/Constants/Constants.qml | 2 ++ resources/styles/SwiftNav/TabButton.qml | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/resources/Constants/Constants.qml b/resources/Constants/Constants.qml index 2581bf228..84381e6ea 100644 --- a/resources/Constants/Constants.qml +++ b/resources/Constants/Constants.qml @@ -52,6 +52,8 @@ QtObject { readonly property bool debugMode: false readonly property color swiftGrey: "#323F48" readonly property color swiftLightGrey: "#3C464F" + readonly property color swiftControlBackground: "#ECECEC" + readonly property color tabButtonUnselectedTextColor: "#767676" readonly property color materialGrey: "dimgrey" readonly property color swiftOrange: "#FF8300" diff --git a/resources/styles/SwiftNav/TabButton.qml b/resources/styles/SwiftNav/TabButton.qml index cfd0a4b79..ea6763154 100644 --- a/resources/styles/SwiftNav/TabButton.qml +++ b/resources/styles/SwiftNav/TabButton.qml @@ -45,8 +45,8 @@ import "../Constants" T.TabButton { id: control - property color labelColor: !control.enabled ? control.Material.hintTextColor : control.down || control.checked ? "white" : "#C2C2C2" - property color backgroundColor: down || checked ? Constants.swiftOrange : hovered ? Qt.darker("white", 1.1) : "white" + property color labelColor: !control.enabled ? control.Material.hintTextColor : control.down || control.checked ? "white" : Constants.tabButtonUnselectedTextColor + property color backgroundColor: down || checked ? Constants.swiftGrey : hovered ? Qt.darker(Constants.swiftControlBackground, 1.1) : Constants.swiftControlBackground property bool border: true implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) @@ -65,7 +65,7 @@ T.TabButton { icon.width: 24 icon.height: 24 - icon.color: !enabled ? Material.hintTextColor : down || checked ? Constants.swiftOrange : "#C2C2C2" + icon.color: !enabled ? Material.hintTextColor : down || checked ? "white" : Constants.tabButtonUnselectedTextColor contentItem: IconLabel { spacing: control.spacing From beb2433c95e8ab2a06989e33bed5bb28161c3f70 Mon Sep 17 00:00:00 2001 From: Keith Kyzivat Date: Tue, 16 Nov 2021 19:32:39 -0500 Subject: [PATCH 9/9] qmlformat fixes for all other files in this branch --- resources/Theme/Theme.qml | 7 ++----- resources/TrackingTab.qml | 2 +- resources/styles/SwiftNav/TabBar.qml | 20 ++++++++++--------- resources/styles/SwiftNav/TabButton.qml | 26 ++++++------------------- 4 files changed, 20 insertions(+), 35 deletions(-) diff --git a/resources/Theme/Theme.qml b/resources/Theme/Theme.qml index 9018ece5f..4ccd822d5 100644 --- a/resources/Theme/Theme.qml +++ b/resources/Theme/Theme.qml @@ -48,9 +48,8 @@ ** ****************************************************************************/ -pragma Singleton - import QtQuick 2.12 +pragma Singleton QtObject { readonly property color gray: "#b2b1b1" @@ -60,13 +59,11 @@ QtObject { property color mainColor: "#17a81a" readonly property color dark: "#222222" readonly property color mainColorDarker: Qt.darker(mainColor, 1.5) - property int baseSize: 10 - readonly property int smallSize: 10 readonly property int largeSize: 16 - property font font + font.bold: true font.underline: false font.pixelSize: 14 diff --git a/resources/TrackingTab.qml b/resources/TrackingTab.qml index f6e558299..fb851c119 100644 --- a/resources/TrackingTab.qml +++ b/resources/TrackingTab.qml @@ -13,9 +13,9 @@ Item { TabBar { id: trackingBar + anchors.left: parent.left anchors.right: parent.right - z: Constants.commonChart.zAboveCharts currentIndex: Globals.initialMainTabIndex == 0 ? Globals.initialSubTabIndex : 0 contentHeight: Constants.tabBarHeight diff --git a/resources/styles/SwiftNav/TabBar.qml b/resources/styles/SwiftNav/TabBar.qml index 260a7e2bf..cb258f4c2 100644 --- a/resources/styles/SwiftNav/TabBar.qml +++ b/resources/styles/SwiftNav/TabBar.qml @@ -1,30 +1,25 @@ import QtQuick 2.12 -import QtQuick.Templates 2.12 as T import QtQuick.Controls.Material 2.12 import QtQuick.Controls.Material.impl 2.12 +import QtQuick.Templates 2.12 as T T.TabBar { id: control property var orientation: ListView.Horizontal - implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, - contentWidth + leftPadding + rightPadding) - implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, - contentHeight + topPadding + bottomPadding) - + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding) spacing: -1 contentItem: ListView { model: control.contentModel currentIndex: control.currentIndex - spacing: control.spacing orientation: control.orientation boundsBehavior: Flickable.StopAtBounds flickableDirection: Flickable.AutoFlickIfNeeded snapMode: ListView.SnapToItem - highlightMoveDuration: 250 highlightResizeDuration: 0 highlightFollowsCurrentItem: true @@ -34,6 +29,7 @@ T.TabBar { highlight: Item { z: 2 + Rectangle { x: 1 height: 2 @@ -41,19 +37,22 @@ T.TabBar { y: control.position === T.TabBar.Footer ? 0 : parent.height - height color: control.Material.accentColor } + } + } background: Item { Rectangle { anchors.fill: parent color: "white" - layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { elevation: control.Material.elevation fullWidth: true } + } Rectangle { @@ -63,6 +62,7 @@ T.TabBar { height: 1 color: "#C2C2C2" } + Rectangle { z: 2 anchors.bottom: parent.bottom @@ -70,5 +70,7 @@ T.TabBar { height: 1 color: "#C2C2C2" } + } + } diff --git a/resources/styles/SwiftNav/TabButton.qml b/resources/styles/SwiftNav/TabButton.qml index ea6763154..2d242f3fd 100644 --- a/resources/styles/SwiftNav/TabButton.qml +++ b/resources/styles/SwiftNav/TabButton.qml @@ -34,13 +34,13 @@ ** ****************************************************************************/ +import "../Constants" import QtQuick 2.12 -import QtQuick.Templates 2.12 as T import QtQuick.Controls 2.12 -import QtQuick.Controls.impl 2.12 import QtQuick.Controls.Material 2.12 import QtQuick.Controls.Material.impl 2.12 -import "../Constants" +import QtQuick.Controls.impl 2.12 +import QtQuick.Templates 2.12 as T T.TabButton { id: control @@ -48,21 +48,17 @@ T.TabButton { property color labelColor: !control.enabled ? control.Material.hintTextColor : control.down || control.checked ? "white" : Constants.tabButtonUnselectedTextColor property color backgroundColor: down || checked ? Constants.swiftGrey : hovered ? Qt.darker(Constants.swiftControlBackground, 1.1) : Constants.swiftControlBackground property bool border: true - implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, - implicitContentWidth + leftPadding + rightPadding) - implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, - implicitContentHeight + topPadding + bottomPadding) + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding) padding: 12 spacing: 6 - font: Qt.font({ "family": "Roboto", "pointSize": Constants.largePointSize, - "bold" : true, + "bold": true, "capitalization": Font.MixedCase }) - icon.width: 24 icon.height: 24 icon.color: !enabled ? Material.hintTextColor : down || checked ? "white" : Constants.tabButtonUnselectedTextColor @@ -71,7 +67,6 @@ T.TabButton { spacing: control.spacing mirrored: control.mirrored display: control.display - icon: control.icon text: control.text font: control.font @@ -82,17 +77,8 @@ T.TabButton { border.width: control.border ? 1 : 0 border.color: "#C2C2C2" implicitHeight: control.Material.touchTarget - clip: true color: backgroundColor } - // background: Ripple { - // implicitHeight: control.Material.touchTarget - // clip: true - // pressed: control.pressed - // anchor: control - // active: control.down || control.checked || control.visualFocus || control.hovered - // color: backgroundColor - // } }