mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
desktop widgets: add grid/grid size hints
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@@ -86,6 +88,20 @@ Item {
|
||||
property bool forceSquare: contentLoader.item?.forceSquare ?? false
|
||||
property bool isInteracting: dragArea.pressed || resizeArea.pressed
|
||||
|
||||
property var _gridSettingsTrigger: SettingsData.desktopWidgetGridSettings
|
||||
readonly property int gridSize: {
|
||||
void _gridSettingsTrigger;
|
||||
return SettingsData.getDesktopWidgetGridSetting(screenKey, "size", 40);
|
||||
}
|
||||
readonly property bool gridEnabled: {
|
||||
void _gridSettingsTrigger;
|
||||
return SettingsData.getDesktopWidgetGridSetting(screenKey, "enabled", false);
|
||||
}
|
||||
|
||||
function snapToGrid(value) {
|
||||
return Math.round(value / gridSize) * gridSize;
|
||||
}
|
||||
|
||||
function updateVariantPositions(updates) {
|
||||
const positions = JSON.parse(JSON.stringify(variantData?.positions || {}));
|
||||
positions[screenKey] = Object.assign({}, positions[screenKey] || {}, updates);
|
||||
@@ -141,7 +157,13 @@ Item {
|
||||
WlrLayershell.namespace: "quickshell:desktop-widget:" + root.pluginId + (root.variantId ? ":" + root.variantId : "")
|
||||
WlrLayershell.layer: WlrLayer.Bottom
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.keyboardFocus: (CompositorService.useHyprlandFocusGrab && root.isInteracting) ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||
WlrLayershell.keyboardFocus: {
|
||||
if (!root.isInteracting)
|
||||
return WlrKeyboardFocus.None;
|
||||
if (CompositorService.useHyprlandFocusGrab)
|
||||
return WlrKeyboardFocus.OnDemand;
|
||||
return WlrKeyboardFocus.Exclusive;
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
active: CompositorService.isHyprland && root.isInteracting
|
||||
@@ -238,8 +260,12 @@ Item {
|
||||
if (!pressed)
|
||||
return;
|
||||
const currentPos = root.useGhostPreview ? Qt.point(mouse.x, mouse.y) : mapToGlobal(mouse.x, mouse.y);
|
||||
const newX = Math.max(0, Math.min(startX + currentPos.x - startPos.x, root.screenWidth - root.widgetWidth));
|
||||
const newY = Math.max(0, Math.min(startY + currentPos.y - startPos.y, root.screenHeight - root.widgetHeight));
|
||||
let newX = Math.max(0, Math.min(startX + currentPos.x - startPos.x, root.screenWidth - root.widgetWidth));
|
||||
let newY = Math.max(0, Math.min(startY + currentPos.y - startPos.y, root.screenHeight - root.widgetHeight));
|
||||
if (root.gridEnabled) {
|
||||
newX = Math.max(0, Math.min(root.snapToGrid(newX), root.screenWidth - root.widgetWidth));
|
||||
newY = Math.max(0, Math.min(root.snapToGrid(newY), root.screenHeight - root.widgetHeight));
|
||||
}
|
||||
if (root.useGhostPreview) {
|
||||
root.previewX = newX;
|
||||
root.previewY = newY;
|
||||
@@ -285,6 +311,10 @@ Item {
|
||||
const currentPos = root.useGhostPreview ? Qt.point(mouse.x, mouse.y) : mapToGlobal(mouse.x, mouse.y);
|
||||
let newW = Math.max(root.minWidth, Math.min(startWidth + currentPos.x - startPos.x, root.screenWidth - root.widgetX));
|
||||
let newH = Math.max(root.minHeight, Math.min(startHeight + currentPos.y - startPos.y, root.screenHeight - root.widgetY));
|
||||
if (root.gridEnabled) {
|
||||
newW = Math.max(root.minWidth, root.snapToGrid(newW));
|
||||
newH = Math.max(root.minHeight, root.snapToGrid(newH));
|
||||
}
|
||||
if (root.forceSquare) {
|
||||
const size = Math.max(newW, newH);
|
||||
newW = Math.min(size, root.screenWidth - root.widgetX);
|
||||
@@ -330,6 +360,39 @@ Item {
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
|
||||
Item {
|
||||
id: gridOverlay
|
||||
anchors.fill: parent
|
||||
visible: root.gridEnabled
|
||||
opacity: 0.3
|
||||
|
||||
Repeater {
|
||||
model: Math.ceil(root.screenWidth / root.gridSize)
|
||||
|
||||
Rectangle {
|
||||
required property int index
|
||||
x: index * root.gridSize
|
||||
y: 0
|
||||
width: 1
|
||||
height: root.screenHeight
|
||||
color: Theme.primary
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Math.ceil(root.screenHeight / root.gridSize)
|
||||
|
||||
Rectangle {
|
||||
required property int index
|
||||
x: 0
|
||||
y: index * root.gridSize
|
||||
width: root.screenWidth
|
||||
height: 1
|
||||
color: Theme.primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
x: root.previewX
|
||||
y: root.previewY
|
||||
@@ -355,4 +418,177 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: root.isInteracting && root.gridEnabled && !root.useGhostPreview
|
||||
|
||||
sourceComponent: PanelWindow {
|
||||
screen: root.screen
|
||||
color: "transparent"
|
||||
|
||||
anchors {
|
||||
left: true
|
||||
right: true
|
||||
top: true
|
||||
bottom: true
|
||||
}
|
||||
|
||||
mask: Region {}
|
||||
|
||||
WlrLayershell.namespace: "quickshell:desktop-widget-grid"
|
||||
WlrLayershell.layer: WlrLayer.Background
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
opacity: 0.3
|
||||
|
||||
Repeater {
|
||||
model: Math.ceil(root.screenWidth / root.gridSize)
|
||||
|
||||
Rectangle {
|
||||
required property int index
|
||||
x: index * root.gridSize
|
||||
y: 0
|
||||
width: 1
|
||||
height: root.screenHeight
|
||||
color: Theme.primary
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Math.ceil(root.screenHeight / root.gridSize)
|
||||
|
||||
Rectangle {
|
||||
required property int index
|
||||
x: 0
|
||||
y: index * root.gridSize
|
||||
width: root.screenWidth
|
||||
height: 1
|
||||
color: Theme.primary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: root.isInteracting
|
||||
|
||||
sourceComponent: PanelWindow {
|
||||
id: helperWindow
|
||||
screen: root.screen
|
||||
color: "transparent"
|
||||
|
||||
WlrLayershell.namespace: "quickshell:desktop-widget-helper"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.keyboardFocus: {
|
||||
if (CompositorService.useHyprlandFocusGrab)
|
||||
return WlrKeyboardFocus.OnDemand;
|
||||
return WlrKeyboardFocus.Exclusive;
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
active: CompositorService.isHyprland
|
||||
windows: [helperWindow]
|
||||
}
|
||||
|
||||
anchors {
|
||||
bottom: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
implicitHeight: 60
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
focus: true
|
||||
|
||||
Keys.onPressed: event => {
|
||||
switch (event.key) {
|
||||
case Qt.Key_G:
|
||||
SettingsData.setDesktopWidgetGridSetting(root.screenKey, "enabled", !root.gridEnabled);
|
||||
event.accepted = true;
|
||||
break;
|
||||
case Qt.Key_Z:
|
||||
SettingsData.setDesktopWidgetGridSetting(root.screenKey, "size", Math.max(10, root.gridSize - 10));
|
||||
event.accepted = true;
|
||||
break;
|
||||
case Qt.Key_X:
|
||||
SettingsData.setDesktopWidgetGridSetting(root.screenKey, "size", Math.min(200, root.gridSize + 10));
|
||||
event.accepted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: helperContent
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Theme.spacingL
|
||||
width: helperRow.implicitWidth + Theme.spacingM * 2
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surface
|
||||
|
||||
Row {
|
||||
id: helperRow
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingM
|
||||
height: parent.height
|
||||
|
||||
DankIcon {
|
||||
name: "grid_on"
|
||||
size: 16
|
||||
color: root.gridEnabled ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: root.gridEnabled ? I18n.tr("Grid: ON", "Widget grid snap status") : I18n.tr("Grid: OFF", "Widget grid snap status")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.family: Theme.fontFamily
|
||||
color: root.gridEnabled ? Theme.primary : Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 1
|
||||
height: 16
|
||||
color: Theme.outline
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: root.gridSize + "px"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.family: Theme.fontFamily
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 1
|
||||
height: 16
|
||||
color: Theme.outline
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
text: I18n.tr("G: grid • Z/X: size", "Widget grid keyboard hints")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.family: Theme.fontFamily
|
||||
font.italic: true
|
||||
color: Theme.surfaceText
|
||||
opacity: 0.7
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user