diff options
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DisplayConfig/NiriOutputSettings.qml')
| -rw-r--r-- | raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DisplayConfig/NiriOutputSettings.qml | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DisplayConfig/NiriOutputSettings.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DisplayConfig/NiriOutputSettings.qml new file mode 100644 index 0000000..da9a4a7 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/DisplayConfig/NiriOutputSettings.qml @@ -0,0 +1,368 @@ +import QtQuick +import qs.Common +import qs.Widgets + +Column { + id: root + + property string outputName: "" + property var outputData: null + property bool expanded: false + + width: parent.width + spacing: 0 + + Rectangle { + width: parent.width + height: headerRow.implicitHeight + Theme.spacingS * 2 + color: headerMouse.containsMouse ? Theme.withAlpha(Theme.primary, 0.1) : "transparent" + radius: Theme.cornerRadius / 2 + + Row { + id: headerRow + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: Theme.spacingS + anchors.rightMargin: Theme.spacingS + spacing: Theme.spacingS + + DankIcon { + name: root.expanded ? "expand_more" : "chevron_right" + size: Theme.iconSize + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: I18n.tr("Compositor Settings") + font.pixelSize: Theme.fontSizeMedium + font.weight: Font.Medium + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + } + + MouseArea { + id: headerMouse + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: root.expanded = !root.expanded + } + } + + Column { + width: parent.width + spacing: Theme.spacingS + visible: root.expanded + topPadding: Theme.spacingS + + DankToggle { + width: parent.width + text: I18n.tr("Disable Output") + checked: DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "disabled", false) + onToggled: checked => DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "disabled", checked) + } + + DankToggle { + width: parent.width + text: I18n.tr("Focus at Startup") + checked: DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "focusAtStartup", false) + onToggled: checked => DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "focusAtStartup", checked) + } + + DankDropdown { + width: parent.width + text: I18n.tr("Hot Corners") + addHorizontalPadding: true + + property var hotCornersData: { + void (DisplayConfigState.pendingNiriChanges); + return DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "hotCorners", null); + } + + currentValue: { + if (!hotCornersData) + return I18n.tr("Inherit"); + if (hotCornersData.off) + return I18n.tr("Off"); + const corners = hotCornersData.corners || []; + if (corners.length === 0) + return I18n.tr("Inherit"); + if (corners.length === 4) + return I18n.tr("All"); + return I18n.tr("Select..."); + } + options: [I18n.tr("Inherit"), I18n.tr("Off"), I18n.tr("All"), I18n.tr("Select...")] + + onValueChanged: value => { + switch (value) { + case I18n.tr("Inherit"): + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "hotCorners", null); + break; + case I18n.tr("Off"): + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "hotCorners", { + "off": true + }); + break; + case I18n.tr("All"): + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "hotCorners", { + "corners": ["top-left", "top-right", "bottom-left", "bottom-right"] + }); + break; + case I18n.tr("Select..."): + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "hotCorners", { + "corners": [] + }); + break; + } + } + } + + Item { + width: parent.width + height: hotCornersGroup.implicitHeight + clip: true + + property var hotCornersData: { + void (DisplayConfigState.pendingNiriChanges); + return DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "hotCorners", null); + } + + visible: hotCornersData && !hotCornersData.off && hotCornersData.corners !== undefined + + DankButtonGroup { + id: hotCornersGroup + anchors.horizontalCenter: parent.horizontalCenter + selectionMode: "multi" + checkEnabled: false + buttonHeight: 32 + buttonPadding: parent.width < 400 ? Theme.spacingXS : Theme.spacingM + minButtonWidth: parent.width < 400 ? 28 : 56 + textSize: parent.width < 400 ? 11 : Theme.fontSizeMedium + model: [I18n.tr("Top Left"), I18n.tr("Top Right"), I18n.tr("Bottom Left"), I18n.tr("Bottom Right")] + + property var cornerKeys: ["top-left", "top-right", "bottom-left", "bottom-right"] + + currentSelection: { + const hcData = parent.hotCornersData; + if (!hcData?.corners) + return []; + return hcData.corners.map(key => { + const idx = cornerKeys.indexOf(key); + return idx >= 0 ? model[idx] : null; + }).filter(v => v !== null); + } + + onSelectionChanged: (index, selected) => { + const corners = currentSelection.map(label => { + const idx = model.indexOf(label); + return idx >= 0 ? cornerKeys[idx] : null; + }).filter(v => v !== null); + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "hotCorners", { + "corners": corners + }); + } + } + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.withAlpha(Theme.outline, 0.15) + } + + Item { + width: parent.width + height: layoutColumn.implicitHeight + + Column { + id: layoutColumn + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: Theme.spacingM + anchors.rightMargin: Theme.spacingM + spacing: Theme.spacingS + + Column { + width: parent.width + spacing: Theme.spacingXS + + StyledText { + text: I18n.tr("Layout Overrides") + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: Theme.surfaceVariantText + } + + StyledText { + text: I18n.tr("Override global layout settings for this output") + font.pixelSize: Theme.fontSizeSmall + color: Theme.withAlpha(Theme.surfaceVariantText, 0.7) + wrapMode: Text.WordWrap + width: parent.width + } + } + + Row { + width: parent.width + spacing: Theme.spacingM + + Column { + width: (parent.width - Theme.spacingM) / 2 + spacing: Theme.spacingXS + + StyledText { + text: I18n.tr("Window Gaps (px)") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + } + + DankTextField { + width: parent.width + height: 40 + placeholderText: I18n.tr("Inherit") + text: { + const layout = DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "layout", null); + if (layout?.gaps === undefined) + return ""; + return layout.gaps.toString(); + } + onEditingFinished: { + const layout = DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "layout", {}) || {}; + const trimmed = text.trim(); + if (!trimmed) { + delete layout.gaps; + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "layout", Object.keys(layout).length > 0 ? layout : null); + return; + } + const val = parseInt(trimmed); + if (isNaN(val) || val < 0) + return; + layout.gaps = val; + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "layout", layout); + } + } + } + + Column { + width: (parent.width - Theme.spacingM) / 2 + spacing: Theme.spacingXS + + StyledText { + text: I18n.tr("Default Width (%)") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + } + + DankTextField { + width: parent.width + height: 40 + placeholderText: I18n.tr("Inherit") + text: { + const layout = DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "layout", null); + if (!layout?.defaultColumnWidth) + return ""; + if (layout.defaultColumnWidth.type !== "proportion") + return ""; + const percent = layout.defaultColumnWidth.value * 100; + return parseFloat(percent.toFixed(4)).toString(); + } + onEditingFinished: { + const layout = DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "layout", {}) || {}; + const trimmed = text.trim().replace("%", ""); + if (!trimmed) { + delete layout.defaultColumnWidth; + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "layout", Object.keys(layout).length > 0 ? layout : null); + return; + } + const val = parseFloat(trimmed); + if (isNaN(val) || val <= 0 || val > 100) + return; + layout.defaultColumnWidth = { + "type": "proportion", + "value": parseFloat((val / 100).toFixed(6)) + }; + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "layout", layout); + } + } + } + } + + Column { + width: parent.width + spacing: Theme.spacingXS + + StyledText { + text: I18n.tr("Preset Widths (%)") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + } + + StyledText { + text: "e.g. 33.33, 50, 66.67" + font.pixelSize: Theme.fontSizeSmall + color: Theme.withAlpha(Theme.surfaceVariantText, 0.7) + } + + DankTextField { + width: parent.width + height: 40 + placeholderText: I18n.tr("Inherit") + text: { + const layout = DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "layout", null); + const presets = layout?.presetColumnWidths || []; + if (presets.length === 0) + return ""; + return presets.filter(p => p.type === "proportion").map(p => parseFloat((p.value * 100).toFixed(4))).join(", "); + } + onEditingFinished: { + const layout = DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "layout", {}) || {}; + const trimmed = text.trim(); + if (!trimmed) { + delete layout.presetColumnWidths; + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "layout", Object.keys(layout).length > 0 ? layout : null); + return; + } + const parts = trimmed.split(/[,\s]+/).filter(s => s); + const presets = []; + for (const part of parts) { + const val = parseFloat(part.replace("%", "")); + if (!isNaN(val) && val > 0 && val <= 100) + presets.push({ + "type": "proportion", + "value": parseFloat((val / 100).toFixed(6)) + }); + } + if (presets.length === 0) { + delete layout.presetColumnWidths; + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "layout", Object.keys(layout).length > 0 ? layout : null); + return; + } + presets.sort((a, b) => a.value - b.value); + layout.presetColumnWidths = presets; + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "layout", layout); + } + } + } + } + } + + DankToggle { + width: parent.width + text: I18n.tr("Center Single Column") + property var layoutData: DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "layout", null) + checked: layoutData?.alwaysCenterSingleColumn ?? false + onToggled: checked => { + const layout = DisplayConfigState.getNiriSetting(root.outputData, root.outputName, "layout", {}) || {}; + if (checked) { + layout.alwaysCenterSingleColumn = true; + } else { + delete layout.alwaysCenterSingleColumn; + } + DisplayConfigState.setNiriSetting(root.outputData, root.outputName, "layout", Object.keys(layout).length > 0 ? layout : null); + } + } + } +} |