mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-25 05:52:50 -05:00
369 lines
16 KiB
QML
369 lines
16 KiB
QML
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);
|
|
}
|
|
}
|
|
}
|
|
}
|