diff options
author | kali kaneko (leap communications) <kali@leap.se> | 2021-12-08 22:23:46 +0100 |
---|---|---|
committer | kali kaneko (leap communications) <kali@leap.se> | 2021-12-08 22:24:02 +0100 |
commit | b8d7f667782c66eb051104ca2fecb6442a84649c (patch) | |
tree | 38e57df9b88d79a6a234db870eab1bffb69b3ff7 | |
parent | ca3f128194888e30aadc149eb40a1370931eb2eb (diff) |
[bug] alternative drawer implementation
this is an attempt to solve the problem we're having with snaps, in
which Overlays are not correctly displayed.
-rw-r--r-- | gui/components/Footer.qml | 3 | ||||
-rw-r--r-- | gui/components/Header.qml | 2 | ||||
-rw-r--r-- | gui/components/MainView.qml | 126 | ||||
-rw-r--r-- | gui/components/NavigationDrawer.qml | 170 | ||||
-rw-r--r-- | gui/components/StatusBox.qml | 8 | ||||
-rw-r--r-- | gui/gui.qrc | 1 | ||||
-rw-r--r-- | gui/main.qml | 1 |
7 files changed, 244 insertions, 67 deletions
diff --git a/gui/components/Footer.qml b/gui/components/Footer.qml index e6eb264..5e8335e 100644 --- a/gui/components/Footer.qml +++ b/gui/components/Footer.qml @@ -221,6 +221,9 @@ ToolBar { } function isFooterVisible() { + if (drawerOn) { + return false + } if (stackView.depth > 1) { return false } diff --git a/gui/components/Header.qml b/gui/components/Header.qml index ee2d886..6a1f6aa 100644 --- a/gui/components/Header.qml +++ b/gui/components/Header.qml @@ -29,7 +29,7 @@ ToolBar { if (stackView.depth > 1) { stackView.pop() } else { - settingsDrawer.open() + settingsDrawer.toggle() } } } diff --git a/gui/components/MainView.qml b/gui/components/MainView.qml index 0f5fb58..886e896 100644 --- a/gui/components/MainView.qml +++ b/gui/components/MainView.qml @@ -7,83 +7,80 @@ import QtQuick.Layouts 1.14 import "../themes/themes.js" as Theme Page { - StackView { id: stackView anchors.fill: parent initialItem: Home {} } - Drawer { + NavigationDrawer { id: settingsDrawer - - width: Math.min(root.width, root.height) / 3 * 2 - height: root.height - - ListView { - focus: true - currentIndex: -1 + Rectangle { anchors.fill: parent - - delegate: ItemDelegate { - width: parent.width - text: model.text - visible: { - if (isDonationService) {return true} - return model.text != qsTr("Donate") - } - highlighted: ListView.isCurrentItem - icon.color: "transparent" - icon.source: model.icon - onClicked: { - settingsDrawer.close() - model.triggered() - } - } - - model: ListModel { - ListElement { - text: qsTr("Preferences") - icon: "../resources/tools.svg" - triggered: function () { - stackView.push("Preferences.qml") - } - } - ListElement { - text: qsTr("Donate") - icon: "../resources/donate.svg" - triggered: function () { - Qt.openUrlExternally(ctx.donateURL) - } - } - ListElement { - text: qsTr("Help") - icon: "../resources/help.svg" - triggered: function () { - stackView.push("Help.qml") - settingsDrawer.close() - } - } // -> can link to another dialog with report bug / support / contribute / FAQ - ListElement { - text: qsTr("About") - icon: "../resources/about.svg" - triggered: function () { - stackView.push("About.qml") - settingsDrawer.close() + color: "white" + ListView { + focus: true + currentIndex: -1 + anchors.fill: parent + + model: navModel + delegate: ItemDelegate { + width: parent.width + text: model.text + visible: { + if (isDonationService) {return true} + return model.text != qsTr("Donate") } - } - ListElement { - text: qsTr("Quit") - icon: "../resources/quit.svg" - triggered: function () { - backend.quit() + highlighted: ListView.isCurrentItem + icon.color: "transparent" + icon.source: model.icon + onClicked: { + settingsDrawer.toggle() + model.triggered() } } } - - ScrollIndicator.vertical: ScrollIndicator {} } - } + } + + ListModel { + id: navModel + ListElement { + text: qsTr("Preferences") + icon: "../resources/tools.svg" + triggered: function () { + stackView.push("Preferences.qml") + } + } + ListElement { + text: qsTr("Donate") + icon: "../resources/donate.svg" + triggered: function () { + Qt.openUrlExternally(ctx.donateURL) + } + } + ListElement { + text: qsTr("Help") + icon: "../resources/help.svg" + triggered: function () { + stackView.push("Help.qml") + } + } // -> can link to another dialog with report bug / support / contribute / FAQ + ListElement { + text: qsTr("About") + icon: "../resources/about.svg" + triggered: function () { + stackView.push("About.qml") + } + } + ListElement { + text: qsTr("Quit") + icon: "../resources/quit.svg" + triggered: function () { + backend.quit() + } + } + } // end listmodel header: Header { id: header @@ -146,7 +143,6 @@ Page { horizontalCenter: parent.horizontalCenter } } - onYes: Qt.openUrlExternally(ctx.donateURL) } diff --git a/gui/components/NavigationDrawer.qml b/gui/components/NavigationDrawer.qml new file mode 100644 index 0000000..c0e467c --- /dev/null +++ b/gui/components/NavigationDrawer.qml @@ -0,0 +1,170 @@ +// (c) Evgenij Legotskoj https://evileg.com/en/post/192/
+// a reimplementation of Drawer to workaround a problem with overlays
+// in the Qt version packaged with the snaps.
+import QtQuick 2.5
+import QtQuick.Window 2.0
+
+Rectangle {
+ id: panel
+
+ function show() { open = true; }
+ function hide() { open = false; }
+ function toggle() {
+ open = open ? false : true;
+ drawerOn = open;
+ }
+
+ property bool open: false
+ property int position: Qt.LeftEdge
+
+ readonly property bool _rightEdge: position === Qt.RightEdge
+ readonly property int _closeX: _rightEdge ? _rootItem.width : - panel.width
+ readonly property int _openX: _rightEdge ? _rootItem.width - width : 0
+ readonly property int _minimumX: _rightEdge ? _rootItem.width - panel.width : -panel.width
+ readonly property int _maximumX: _rightEdge ? _rootItem.width : 0
+ readonly property int _pullThreshold: panel.width/2
+ readonly property int _slideDuration: 260
+ readonly property int _openMarginSize: 20
+
+ property real _velocity: 0
+ property real _oldMouseX: -1
+
+ property Item _rootItem: parent
+
+ on_RightEdgeChanged: _setupAnchors()
+ onOpenChanged: completeSlideDirection()
+
+ width: Math.min(root.width, root.height) / 3 * 2
+ height: root.height
+ x: _closeX
+ z: 10
+
+ function _setupAnchors() {
+ _rootItem = parent;
+
+ shadow.anchors.right = undefined;
+ shadow.anchors.left = undefined;
+
+ mouse.anchors.left = undefined;
+ mouse.anchors.right = undefined;
+
+ if (_rightEdge) {
+ mouse.anchors.right = mouse.parent.right;
+ shadow.anchors.right = panel.left;
+ } else {
+ mouse.anchors.left = mouse.parent.left;
+ shadow.anchors.left = panel.right;
+ }
+
+ slideAnimation.enabled = false;
+ panel.x = _rightEdge ? _rootItem.width : - panel.width;
+ slideAnimation.enabled = true;
+ }
+
+ function completeSlideDirection() {
+ if (open) {
+ panel.x = _openX;
+ } else {
+ panel.x = _closeX;
+ Qt.inputMethod.hide();
+ }
+ }
+
+ function handleRelease() {
+ var velocityThreshold = 5
+ if ((_rightEdge && _velocity > velocityThreshold) ||
+ (!_rightEdge && _velocity < -velocityThreshold)) {
+ panel.open = false;
+ completeSlideDirection()
+ } else if ((_rightEdge && _velocity < -velocityThreshold) ||
+ (!_rightEdge && _velocity > velocityThreshold)) {
+ panel.open = true;
+ completeSlideDirection()
+ } else if ((_rightEdge && panel.x < _openX + _pullThreshold) ||
+ (!_rightEdge && panel.x > _openX - _pullThreshold) ) {
+ panel.open = true;
+ panel.x = _openX;
+ } else {
+ panel.open = false;
+ panel.x = _closeX;
+ }
+ }
+
+ function handleClick(mouse) {
+ if ((_rightEdge && mouse.x < panel.x ) || mouse.x > panel.width) {
+ open = false;
+ }
+ }
+
+ onPositionChanged: {
+ if (!(position === Qt.RightEdge || position === Qt.LeftEdge )) {
+ console.warn("SlidePanel: Unsupported position.")
+ }
+ }
+
+ Behavior on x {
+ id: slideAnimation
+ enabled: !mouse.drag.active
+ NumberAnimation {
+ duration: _slideDuration
+ easing.type: Easing.OutCubic
+ }
+ }
+
+ NumberAnimation on x {
+ id: holdAnimation
+ to: _closeX + (_openMarginSize * (_rightEdge ? -1 : 1))
+ running : false
+ easing.type: Easing.OutCubic
+ duration: 200
+ }
+
+ MouseArea {
+ id: mouse
+ parent: _rootItem
+
+ y: _rootItem.y
+ width: open ? _rootItem.width : _openMarginSize
+ height: _rootItem.height
+ onPressed: if (!open) holdAnimation.restart();
+ onClicked: handleClick(mouse)
+ drag.target: panel
+ drag.minimumX: _minimumX
+ drag.maximumX: _maximumX
+ drag.axis: Qt.Horizontal
+ drag.onActiveChanged: if (active) holdAnimation.stop()
+ onReleased: handleRelease()
+ z: open ? 1 : 0
+ onMouseXChanged: {
+ _velocity = (mouse.x - _oldMouseX);
+ _oldMouseX = mouse.x;
+ }
+ }
+
+ Rectangle {
+ id: backgroundBlackout
+ parent: _rootItem
+ anchors.fill: parent
+ opacity: 0.5 * Math.min(1, Math.abs(panel.x - _closeX) / _rootItem.width/2)
+ color: "black"
+ }
+
+ Item {
+ id: shadow
+ anchors.left: panel.right
+ anchors.leftMargin: _rightEdge ? 0 : 10
+ height: parent.height
+
+ Rectangle {
+ height: 10
+ width: panel.height
+ rotation: 90
+ opacity: Math.min(1, Math.abs(panel.x - _closeX)/ _openMarginSize)
+ transformOrigin: Item.TopLeft
+ gradient: Gradient{
+ GradientStop { position: _rightEdge ? 1 : 0 ; color: "#00000000"}
+ GradientStop { position: _rightEdge ? 0 : 1 ; color: "#2c000000"}
+ }
+ }
+ }
+}
diff --git a/gui/components/StatusBox.qml b/gui/components/StatusBox.qml index 23fc271..bfcc175 100644 --- a/gui/components/StatusBox.qml +++ b/gui/components/StatusBox.qml @@ -55,11 +55,14 @@ Item { cursorShape: Qt.PointingHandCursor } onClicked: { + settingsDrawer.toggle() + /* if (stackView.depth > 1) { stackView.pop() } else { - settingsDrawer.open() + settingsDrawer.toggle() } + */ } Icon { @@ -67,8 +70,11 @@ Item { width: 16 height: 16 anchors.centerIn: settingsButton + source: "../resources/gear-fill.svg" + /* source: stackView.depth > 1 ? "../resources/arrow-left.svg" : "../resources/gear-fill.svg" + */ } } diff --git a/gui/gui.qrc b/gui/gui.qrc index 71a4422..9e357bf 100644 --- a/gui/gui.qrc +++ b/gui/gui.qrc @@ -41,6 +41,7 @@ <file>components/InitErrors.qml</file> <file>components/ErrorBox.qml</file> <file>components/MotdBox.qml</file> + <file>components/NavigationDrawer.qml</file> <!-- resources, assets --> <file>resources/icon-noshield.svg</file> diff --git a/gui/main.qml b/gui/main.qml index 00a84fc..56220f5 100644 --- a/gui/main.qml +++ b/gui/main.qml @@ -14,6 +14,7 @@ ApplicationWindow { property int appHeight: 460 property int appWidth: 280 property alias customTheme: themeLoader.item + property bool drawerOn: false width: appWidth minimumWidth: appWidth |