forked from Shinonome/dots-hyprland
region selector: dashed border, move action indicator to cursor
This commit is contained in:
@@ -0,0 +1,112 @@
|
|||||||
|
import qs.services
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
property var action
|
||||||
|
property var selectionMode
|
||||||
|
|
||||||
|
property string description: switch (root.action) {
|
||||||
|
case RegionSelection.SnipAction.Copy:
|
||||||
|
case RegionSelection.SnipAction.Edit:
|
||||||
|
return Translation.tr("Copy region (LMB) or annotate (RMB)");
|
||||||
|
case RegionSelection.SnipAction.Search:
|
||||||
|
return Translation.tr("Search with Google Lens");
|
||||||
|
case RegionSelection.SnipAction.CharRecognition:
|
||||||
|
return Translation.tr("Recognize text");
|
||||||
|
case RegionSelection.SnipAction.Record:
|
||||||
|
case RegionSelection.SnipAction.RecordWithSound:
|
||||||
|
return Translation.tr("Record region");
|
||||||
|
}
|
||||||
|
property string materialSymbol: switch (root.action) {
|
||||||
|
case RegionSelection.SnipAction.Copy:
|
||||||
|
case RegionSelection.SnipAction.Edit:
|
||||||
|
return "content_cut";
|
||||||
|
case RegionSelection.SnipAction.Search:
|
||||||
|
return "image_search";
|
||||||
|
case RegionSelection.SnipAction.CharRecognition:
|
||||||
|
return "document_scanner";
|
||||||
|
case RegionSelection.SnipAction.Record:
|
||||||
|
case RegionSelection.SnipAction.RecordWithSound:
|
||||||
|
return "videocam";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool showDescription: true
|
||||||
|
function hideDescription() {
|
||||||
|
root.showDescription = false
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: descTimeout
|
||||||
|
interval: 1000
|
||||||
|
running: true
|
||||||
|
onTriggered: {
|
||||||
|
root.hideDescription()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onActionChanged: {
|
||||||
|
root.showDescription = true
|
||||||
|
descTimeout.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
property int margins: 8
|
||||||
|
implicitWidth: content.implicitWidth + margins * 2
|
||||||
|
implicitHeight: content.implicitHeight + margins * 2
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: content
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
property real padding: 8
|
||||||
|
implicitHeight: 38
|
||||||
|
implicitWidth: root.showDescription ? contentRow.implicitWidth + padding * 2 : implicitHeight
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
topLeftRadius: root.showDescription ? implicitHeight / 2 : 6
|
||||||
|
bottomLeftRadius: implicitHeight - topLeftRadius
|
||||||
|
bottomRightRadius: bottomLeftRadius
|
||||||
|
topRightRadius: bottomLeftRadius
|
||||||
|
|
||||||
|
color: Appearance.colors.colPrimary
|
||||||
|
|
||||||
|
Behavior on topLeftRadius {
|
||||||
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: contentRow
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: content.padding
|
||||||
|
}
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
MaterialSymbol {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
iconSize: 22
|
||||||
|
color: Appearance.colors.colOnPrimary
|
||||||
|
animateChange: true
|
||||||
|
text: root.materialSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
FadeLoader {
|
||||||
|
id: descriptionLoader
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
shown: root.showDescription
|
||||||
|
sourceComponent: StyledText {
|
||||||
|
color: Appearance.colors.colOnPrimary
|
||||||
|
text: root.description
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,48 +23,6 @@ Toolbar {
|
|||||||
// Signals
|
// Signals
|
||||||
signal dismiss()
|
signal dismiss()
|
||||||
|
|
||||||
MaterialShape {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.leftMargin: 2
|
|
||||||
Layout.rightMargin: 2
|
|
||||||
implicitSize: 36 // Intentionally smaller because this one is brighter than others
|
|
||||||
shape: switch (root.action) {
|
|
||||||
case RegionSelection.SnipAction.Copy:
|
|
||||||
case RegionSelection.SnipAction.Edit:
|
|
||||||
return MaterialShape.Shape.Cookie4Sided;
|
|
||||||
case RegionSelection.SnipAction.Search:
|
|
||||||
return MaterialShape.Shape.Pentagon;
|
|
||||||
case RegionSelection.SnipAction.CharRecognition:
|
|
||||||
return MaterialShape.Shape.Sunny;
|
|
||||||
case RegionSelection.SnipAction.Record:
|
|
||||||
case RegionSelection.SnipAction.RecordWithSound:
|
|
||||||
return MaterialShape.Shape.Gem;
|
|
||||||
default:
|
|
||||||
return MaterialShape.Shape.Cookie12Sided;
|
|
||||||
}
|
|
||||||
color: Appearance.colors.colPrimary
|
|
||||||
MaterialSymbol {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
iconSize: 22
|
|
||||||
color: Appearance.colors.colOnPrimary
|
|
||||||
animateChange: true
|
|
||||||
text: switch (root.action) {
|
|
||||||
case RegionSelection.SnipAction.Copy:
|
|
||||||
case RegionSelection.SnipAction.Edit:
|
|
||||||
return "content_cut";
|
|
||||||
case RegionSelection.SnipAction.Search:
|
|
||||||
return "image_search";
|
|
||||||
case RegionSelection.SnipAction.CharRecognition:
|
|
||||||
return "document_scanner";
|
|
||||||
case RegionSelection.SnipAction.Record:
|
|
||||||
case RegionSelection.SnipAction.RecordWithSound:
|
|
||||||
return "videocam";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolbarTabBar {
|
ToolbarTabBar {
|
||||||
id: tabBar
|
id: tabBar
|
||||||
tabButtonList: [
|
tabButtonList: [
|
||||||
@@ -76,5 +34,4 @@ Toolbar {
|
|||||||
root.selectionMode = currentIndex === 0 ? RegionSelection.SelectionMode.RectCorners : RegionSelection.SelectionMode.Circle;
|
root.selectionMode = currentIndex === 0 ? RegionSelection.SelectionMode.RectCorners : RegionSelection.SelectionMode.Circle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-11
@@ -33,22 +33,40 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Selection border
|
// Selection border
|
||||||
Rectangle {
|
// Rectangle {
|
||||||
|
// id: selectionBorder
|
||||||
|
// z: 1
|
||||||
|
// anchors {
|
||||||
|
// left: parent.left
|
||||||
|
// top: parent.top
|
||||||
|
// leftMargin: root.regionX
|
||||||
|
// topMargin: root.regionY
|
||||||
|
// }
|
||||||
|
// width: root.regionWidth
|
||||||
|
// height: root.regionHeight
|
||||||
|
// color: "transparent"
|
||||||
|
// border.color: root.color
|
||||||
|
// border.width: 2
|
||||||
|
// // radius: root.standardRounding
|
||||||
|
// radius: 0 // TODO: figure out how to make the overlay thing work with rounding
|
||||||
|
// }
|
||||||
|
|
||||||
|
DashedBorder {
|
||||||
id: selectionBorder
|
id: selectionBorder
|
||||||
z: 1
|
z: 9
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
top: parent.top
|
top: parent.top
|
||||||
leftMargin: root.regionX
|
leftMargin: Math.round(root.regionX) - borderWidth
|
||||||
topMargin: root.regionY
|
topMargin: Math.round(root.regionY) - borderWidth
|
||||||
}
|
}
|
||||||
width: root.regionWidth
|
width: Math.round(root.regionWidth) + borderWidth * 2
|
||||||
height: root.regionHeight
|
height: Math.round(root.regionHeight) + borderWidth * 2
|
||||||
color: "transparent"
|
|
||||||
border.color: root.color
|
color: root.color
|
||||||
border.width: 2
|
dashLength: 6
|
||||||
// radius: root.standardRounding
|
gapLength: 3
|
||||||
radius: 0 // TODO: figure out how to make the overlay thing work with rounding
|
borderWidth: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ PanelWindow {
|
|||||||
signal dismiss()
|
signal dismiss()
|
||||||
|
|
||||||
property string screenshotDir: Directories.screenshotTemp
|
property string screenshotDir: Directories.screenshotTemp
|
||||||
property color overlayColor: "#88111111"
|
property color overlayColor: ColorUtils.transparentize("#000000", 0.4)
|
||||||
property color brightText: Appearance.m3colors.darkmode ? Appearance.colors.colOnLayer0 : Appearance.colors.colLayer0
|
property color brightText: Appearance.m3colors.darkmode ? Appearance.colors.colOnLayer0 : Appearance.colors.colLayer0
|
||||||
property color brightSecondary: Appearance.m3colors.darkmode ? Appearance.colors.colSecondary : Appearance.colors.colOnSecondary
|
property color brightSecondary: Appearance.m3colors.darkmode ? Appearance.colors.colSecondary : Appearance.colors.colOnSecondary
|
||||||
property color brightTertiary: Appearance.m3colors.darkmode ? Appearance.colors.colTertiary : Qt.lighter(Appearance.colors.colPrimary)
|
property color brightTertiary: Appearance.m3colors.darkmode ? Appearance.colors.colTertiary : Qt.lighter(Appearance.colors.colPrimary)
|
||||||
@@ -375,6 +375,14 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CursorGuide {
|
||||||
|
z: 9999
|
||||||
|
x: root.dragging ? root.regionX + root.regionWidth : mouseArea.mouseX
|
||||||
|
y: root.dragging ? root.regionY + root.regionHeight : mouseArea.mouseY
|
||||||
|
action: root.action
|
||||||
|
selectionMode: root.selectionMode
|
||||||
|
}
|
||||||
|
|
||||||
// Window regions
|
// Window regions
|
||||||
Repeater {
|
Repeater {
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
@@ -447,7 +455,7 @@ PanelWindow {
|
|||||||
// Controls
|
// Controls
|
||||||
Row {
|
Row {
|
||||||
id: regionSelectionControls
|
id: regionSelectionControls
|
||||||
z: 9999
|
z: 10
|
||||||
anchors {
|
anchors {
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
|
|||||||
Reference in New Issue
Block a user