From e55d4aa36bc035271a33e4654b25f9f8b3a48ed7 Mon Sep 17 00:00:00 2001 From: zach Date: Sun, 21 Jun 2026 16:14:36 +0200 Subject: [PATCH] clear and exit buttons on drawing popout + pin button --- Components/ButtonBase.qml | 5 ++ Components/IconButton.qml | 2 +- Components/IconTextButton.qml | 70 ++++++++++++++++++++++++++ Components/TextButton.qml | 1 + Drawers/Interactions.qml | 11 ++-- Modules/Drawing/Content.qml | 60 +++++++++++++++++++++- Modules/Drawing/Wrapper.qml | 24 +++++++++ Modules/Notifications/Notification.qml | 5 +- 8 files changed, 169 insertions(+), 9 deletions(-) create mode 100644 Components/IconTextButton.qml diff --git a/Components/ButtonBase.qml b/Components/ButtonBase.qml index 9dcf2ab..5eb4bb7 100644 --- a/Components/ButtonBase.qml +++ b/Components/ButtonBase.qml @@ -18,6 +18,11 @@ CustomRect { property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) property color disabledOnColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) property bool fillWidth + property font font: ({ + family: Appearance.font.family.sans, + pointSize: Appearance.font.size.larger, + bold: false + }) property real horizontalPadding: padding readonly property alias hovered: stateLayer.containsMouse required implicitHeight diff --git a/Components/IconButton.qml b/Components/IconButton.qml index 2727b8f..eef84fd 100644 --- a/Components/IconButton.qml +++ b/Components/IconButton.qml @@ -4,7 +4,6 @@ import qs.Config ButtonBase { id: root - property alias font: label.font property alias icon: label.text readonly property alias label: label @@ -36,6 +35,7 @@ ButtonBase { anchors.verticalCenterOffset: 1 color: root.onColor fill: !root.isToggle || root.internalChecked ? 1 : 0 + font.pointSize: root.font.pointSize Behavior on fill { Anim { diff --git a/Components/IconTextButton.qml b/Components/IconTextButton.qml new file mode 100644 index 0000000..dc20535 --- /dev/null +++ b/Components/IconTextButton.qml @@ -0,0 +1,70 @@ +import QtQuick +import QtQuick.Layouts +import qs.Config + +ButtonBase { + id: root + + property alias icon: iconLabel.text + readonly property alias iconLabel: iconLabel + readonly property alias label: label + property alias text: label.text + + activeColor: type === TextButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondary + activeOnColor: { + if (type === TextButton.Text) + return DynamicColors.palette.m3primary; + return type === TextButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondary; + } + horizontalPadding: Appearance.padding.larger + implicitHeight: row.implicitHeight + verticalPadding * 2 + implicitWidth: row.implicitWidth + horizontalPadding * 2 + inactiveColor: { + if (!isToggle && type === TextButton.Filled) + return DynamicColors.palette.m3primary; + return type === TextButton.Filled ? DynamicColors.tPalette.m3surfaceContainer : DynamicColors.palette.m3secondaryContainer; + } + inactiveOnColor: { + if (!isToggle && type === TextButton.Filled) + return DynamicColors.palette.m3onPrimary; + if (type === TextButton.Text) + return DynamicColors.palette.m3primary; + return type === TextButton.Filled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSecondaryContainer; + } + verticalPadding: Appearance.padding.small + + RowLayout { + id: row + + anchors.centerIn: parent + spacing: Appearance.spacing.small + + MaterialIcon { + id: iconLabel + + Layout.alignment: Qt.AlignVCenter + color: root.onColor + fill: root.internalChecked ? 1 : 0 + font: { + const f = Qt.font(root.font); + f.pointSize = Math.round(root.font.pointSize * 1.2); + f.family = "Material Symbols Rounded"; + return f; + } + + Behavior on fill { + Anim { + type: Anim.DefaultEffects + } + } + } + + CustomText { + id: label + + Layout.alignment: Qt.AlignVCenter + color: root.onColor + font: root.font + } + } +} diff --git a/Components/TextButton.qml b/Components/TextButton.qml index 78e3f08..c016bf1 100644 --- a/Components/TextButton.qml +++ b/Components/TextButton.qml @@ -35,5 +35,6 @@ ButtonBase { anchors.centerIn: parent color: root.onColor + font: root.font } } diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index 6446020..b9d79ec 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -94,7 +94,7 @@ Item { if (centroid.pressPosition.y > root.screen.height - Config.barConfig.border && centroid.pressPosition.x < root.screen.width / 5 && dragY < -50) root.visibilities.clipboard = true; - if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.bar.implicitHeight && centroid.pressPosition.x > root.screen.width / 5) + if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.bar.implicitHeight && centroid.pressPosition.x > root.screen.width / 5 && !root.visibilities.launcher) if (dragY < -10) { root.visibilities.dock = true; root.singleGestureTriggered = true; @@ -123,6 +123,7 @@ Item { property bool setInitialPoint: false acceptedButtons: Qt.LeftButton | Qt.RightButton + cursorShape: Qt.BlankCursor enabled: root.visibilities.isDrawing && (!root.inLeftPanel(root.panels.drawing, hoverHandler.point.position.x, hoverHandler.point.position.y) || !root.panels.drawing.expanded) onActiveChanged: { @@ -130,10 +131,12 @@ Item { setInitialPoint = false; root.drawing.content.endStroke(); } else { - root.panels.drawing.expanded = false; + root.panels.drawing.collapse(); } } onPointChanged: { + if (!active) + return; const x = point.position.x; const y = point.position.y; const origX = point.pressPosition.x; @@ -159,7 +162,7 @@ Item { HoverHandler { id: hoverHandler - cursorShape: root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, point.position.x, point.position.y) ? Qt.BlankCursor : undefined + cursorShape: root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, point.position.x, point.position.y) ? Qt.CrossCursor : undefined onHoveredChanged: { if (!hovered) { @@ -182,7 +185,7 @@ Item { if (root.visibilities.isDrawing) { if (root.inLeftPanel(root.panels.drawing, x, y) && !(drawingHandler.point.pressedButtons & Qt.LeftButton)) { - root.panels.drawing.expanded = true; + root.panels.drawing.expand(); root.drawing.content.hideHover(); return; } diff --git a/Modules/Drawing/Content.qml b/Modules/Drawing/Content.qml index 201acaa..6ed0190 100644 --- a/Modules/Drawing/Content.qml +++ b/Modules/Drawing/Content.qml @@ -1,7 +1,6 @@ pragma ComponentBehavior: Bound import QtQuick -import QtQuick.Layouts import ZShell.Components import qs.Config import qs.Components @@ -13,6 +12,7 @@ Item { readonly property var colors2: ["#3b82f6", "#a855f7", "#ec4899", "#ffffff", "#000000"] required property var drawing required property var visibilities + required property Wrapper wrapper function syncFromPenColor() { if (!drawing) @@ -92,6 +92,8 @@ Item { } ButtonRow { + id: row1 + anchors.left: parent.left anchors.right: parent.right spacing: Appearance.spacing.normal @@ -100,11 +102,14 @@ Item { model: root.colors1 delegate: ColorButton { + row: row1 } } } ButtonRow { + id: row2 + anchors.left: parent.left anchors.right: parent.right spacing: Appearance.spacing.normal @@ -113,6 +118,7 @@ Item { model: root.colors2 delegate: ColorButton { + row: row2 } } } @@ -130,19 +136,69 @@ Item { onMoved: root.drawing.drawingState.penWidth = value } + + ButtonRow { + anchors.left: parent.left + anchors.right: parent.right + spacing: Appearance.spacing.small + + IconTextButton { + fillWidth: true + font.pointSize: Appearance.font.size.normal + icon: "close" + inactiveColor: DynamicColors.palette.m3error + inactiveOnColor: DynamicColors.palette.m3onError + isRound: true + shapeMorph: true + text: "Exit" + + onClicked: root.visibilities.isDrawing = false + } + + IconTextButton { + fillWidth: true + font.pointSize: Appearance.font.size.normal + icon: "ink_eraser" + inactiveColor: DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) + inactiveOnColor: DynamicColors.palette.m3onSurfaceVariant + isRound: true + shapeMorph: true + text: "Clear" + + onClicked: root.drawing.content.clear() + } + } + } + + IconButton { + anchors.margins: Appearance.padding.normal + anchors.right: parent.right + anchors.top: parent.top + checked: root.wrapper.pinned + icon: "keep" + isToggle: true + shapeMorph: true + + onClicked: { + root.wrapper.togglePinned(); + } } component ColorButton: IconButton { id: colorButton + readonly property real buttonSize: (row.width - row.spacing * 4) / 5 required property color modelData + required property ButtonRow row fillWidth: false + font.pointSize: Appearance.font.size.normal icon: "" + implicitHeight: buttonSize + implicitWidth: buttonSize inactiveColor: modelData inactiveOnColor: DynamicColors.on(modelData) isRound: true - padding: Appearance.padding.extraSmall shapeMorph: true shapeMorphExpansion: pressed ? 12 : 0 diff --git a/Modules/Drawing/Wrapper.qml b/Modules/Drawing/Wrapper.qml index 76512ad..cbc56ae 100644 --- a/Modules/Drawing/Wrapper.qml +++ b/Modules/Drawing/Wrapper.qml @@ -13,10 +13,33 @@ Item { required property var drawing property bool expanded: true property real offsetScale: shouldBeActive ? 0 : 1 + property bool pinned: false required property ShellScreen screen readonly property bool shouldBeActive: visibilities.isDrawing required property var visibilities + function collapse(): void { + if (pinned) + return; + + expanded = false; + } + + function expand(): void { + expanded = true; + } + + function toggleExpanded(): void { + if (pinned) + return; + + expanded = !expanded; + } + + function togglePinned(): void { + pinned = !pinned; + } + anchors.leftMargin: (-implicitWidth - 5) * offsetScale implicitHeight: content.implicitHeight implicitWidth: root.expanded ? content.implicitWidth : icon.implicitWidth @@ -76,6 +99,7 @@ Item { sourceComponent: Content { drawing: root.drawing visibilities: root.visibilities + wrapper: root } } } diff --git a/Modules/Notifications/Notification.qml b/Modules/Notifications/Notification.qml index 3667947..7abb578 100644 --- a/Modules/Notifications/Notification.qml +++ b/Modules/Notifications/Notification.qml @@ -427,8 +427,8 @@ CustomRect { ButtonRow { id: actions - anchors.left: body.left - anchors.right: body.right + anchors.left: parent.left + anchors.right: parent.right anchors.top: body.bottom anchors.topMargin: Appearance.spacing.small opacity: root.expanded ? 1 : 0 @@ -459,6 +459,7 @@ CustomRect { required property var modelData fillWidth: true + implicitWidth: label.implicitWidth inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3secondary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3onSurfaceVariant isRound: true