clear and exit buttons on drawing popout + pin button
Lint & Format (JS/TS) / lint-format (pull_request) Successful in 11s
Python / lint-format (pull_request) Successful in 19s
Python / test (pull_request) Successful in 29s
Lint & Format (Rust) / lint-format (pull_request) Successful in 1m11s

This commit is contained in:
2026-06-21 16:14:36 +02:00
parent 91b4466773
commit e55d4aa36b
8 changed files with 169 additions and 9 deletions
+5
View File
@@ -18,6 +18,11 @@ CustomRect {
property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1)
property color disabledOnColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) property color disabledOnColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38)
property bool fillWidth property bool fillWidth
property font font: ({
family: Appearance.font.family.sans,
pointSize: Appearance.font.size.larger,
bold: false
})
property real horizontalPadding: padding property real horizontalPadding: padding
readonly property alias hovered: stateLayer.containsMouse readonly property alias hovered: stateLayer.containsMouse
required implicitHeight required implicitHeight
+1 -1
View File
@@ -4,7 +4,6 @@ import qs.Config
ButtonBase { ButtonBase {
id: root id: root
property alias font: label.font
property alias icon: label.text property alias icon: label.text
readonly property alias label: label readonly property alias label: label
@@ -36,6 +35,7 @@ ButtonBase {
anchors.verticalCenterOffset: 1 anchors.verticalCenterOffset: 1
color: root.onColor color: root.onColor
fill: !root.isToggle || root.internalChecked ? 1 : 0 fill: !root.isToggle || root.internalChecked ? 1 : 0
font.pointSize: root.font.pointSize
Behavior on fill { Behavior on fill {
Anim { Anim {
+70
View File
@@ -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
}
}
}
+1
View File
@@ -35,5 +35,6 @@ ButtonBase {
anchors.centerIn: parent anchors.centerIn: parent
color: root.onColor color: root.onColor
font: root.font
} }
} }
+7 -4
View File
@@ -94,7 +94,7 @@ Item {
if (centroid.pressPosition.y > root.screen.height - Config.barConfig.border && centroid.pressPosition.x < root.screen.width / 5 && dragY < -50) if (centroid.pressPosition.y > root.screen.height - Config.barConfig.border && centroid.pressPosition.x < root.screen.width / 5 && dragY < -50)
root.visibilities.clipboard = true; 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) { if (dragY < -10) {
root.visibilities.dock = true; root.visibilities.dock = true;
root.singleGestureTriggered = true; root.singleGestureTriggered = true;
@@ -123,6 +123,7 @@ Item {
property bool setInitialPoint: false property bool setInitialPoint: false
acceptedButtons: Qt.LeftButton | Qt.RightButton 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) enabled: root.visibilities.isDrawing && (!root.inLeftPanel(root.panels.drawing, hoverHandler.point.position.x, hoverHandler.point.position.y) || !root.panels.drawing.expanded)
onActiveChanged: { onActiveChanged: {
@@ -130,10 +131,12 @@ Item {
setInitialPoint = false; setInitialPoint = false;
root.drawing.content.endStroke(); root.drawing.content.endStroke();
} else { } else {
root.panels.drawing.expanded = false; root.panels.drawing.collapse();
} }
} }
onPointChanged: { onPointChanged: {
if (!active)
return;
const x = point.position.x; const x = point.position.x;
const y = point.position.y; const y = point.position.y;
const origX = point.pressPosition.x; const origX = point.pressPosition.x;
@@ -159,7 +162,7 @@ Item {
HoverHandler { HoverHandler {
id: 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: { onHoveredChanged: {
if (!hovered) { if (!hovered) {
@@ -182,7 +185,7 @@ Item {
if (root.visibilities.isDrawing) { if (root.visibilities.isDrawing) {
if (root.inLeftPanel(root.panels.drawing, x, y) && !(drawingHandler.point.pressedButtons & Qt.LeftButton)) { 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(); root.drawing.content.hideHover();
return; return;
} }
+58 -2
View File
@@ -1,7 +1,6 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Layouts
import ZShell.Components import ZShell.Components
import qs.Config import qs.Config
import qs.Components import qs.Components
@@ -13,6 +12,7 @@ Item {
readonly property var colors2: ["#3b82f6", "#a855f7", "#ec4899", "#ffffff", "#000000"] readonly property var colors2: ["#3b82f6", "#a855f7", "#ec4899", "#ffffff", "#000000"]
required property var drawing required property var drawing
required property var visibilities required property var visibilities
required property Wrapper wrapper
function syncFromPenColor() { function syncFromPenColor() {
if (!drawing) if (!drawing)
@@ -92,6 +92,8 @@ Item {
} }
ButtonRow { ButtonRow {
id: row1
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
spacing: Appearance.spacing.normal spacing: Appearance.spacing.normal
@@ -100,11 +102,14 @@ Item {
model: root.colors1 model: root.colors1
delegate: ColorButton { delegate: ColorButton {
row: row1
} }
} }
} }
ButtonRow { ButtonRow {
id: row2
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
spacing: Appearance.spacing.normal spacing: Appearance.spacing.normal
@@ -113,6 +118,7 @@ Item {
model: root.colors2 model: root.colors2
delegate: ColorButton { delegate: ColorButton {
row: row2
} }
} }
} }
@@ -130,19 +136,69 @@ Item {
onMoved: root.drawing.drawingState.penWidth = value 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 { component ColorButton: IconButton {
id: colorButton id: colorButton
readonly property real buttonSize: (row.width - row.spacing * 4) / 5
required property color modelData required property color modelData
required property ButtonRow row
fillWidth: false fillWidth: false
font.pointSize: Appearance.font.size.normal
icon: "" icon: ""
implicitHeight: buttonSize
implicitWidth: buttonSize
inactiveColor: modelData inactiveColor: modelData
inactiveOnColor: DynamicColors.on(modelData) inactiveOnColor: DynamicColors.on(modelData)
isRound: true isRound: true
padding: Appearance.padding.extraSmall
shapeMorph: true shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0 shapeMorphExpansion: pressed ? 12 : 0
+24
View File
@@ -13,10 +13,33 @@ Item {
required property var drawing required property var drawing
property bool expanded: true property bool expanded: true
property real offsetScale: shouldBeActive ? 0 : 1 property real offsetScale: shouldBeActive ? 0 : 1
property bool pinned: false
required property ShellScreen screen required property ShellScreen screen
readonly property bool shouldBeActive: visibilities.isDrawing readonly property bool shouldBeActive: visibilities.isDrawing
required property var visibilities 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 anchors.leftMargin: (-implicitWidth - 5) * offsetScale
implicitHeight: content.implicitHeight implicitHeight: content.implicitHeight
implicitWidth: root.expanded ? content.implicitWidth : icon.implicitWidth implicitWidth: root.expanded ? content.implicitWidth : icon.implicitWidth
@@ -76,6 +99,7 @@ Item {
sourceComponent: Content { sourceComponent: Content {
drawing: root.drawing drawing: root.drawing
visibilities: root.visibilities visibilities: root.visibilities
wrapper: root
} }
} }
} }
+3 -2
View File
@@ -427,8 +427,8 @@ CustomRect {
ButtonRow { ButtonRow {
id: actions id: actions
anchors.left: body.left anchors.left: parent.left
anchors.right: body.right anchors.right: parent.right
anchors.top: body.bottom anchors.top: body.bottom
anchors.topMargin: Appearance.spacing.small anchors.topMargin: Appearance.spacing.small
opacity: root.expanded ? 1 : 0 opacity: root.expanded ? 1 : 0
@@ -459,6 +459,7 @@ CustomRect {
required property var modelData required property var modelData
fillWidth: true fillWidth: true
implicitWidth: label.implicitWidth
inactiveColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3secondary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, 2) 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 inactiveOnColor: root.modelData.urgency === NotificationUrgency.Critical ? DynamicColors.palette.m3onSecondary : DynamicColors.palette.m3onSurfaceVariant
isRound: true isRound: true