Files
DankMaterialShell/quickshell/Modules/ControlCenter/Components/WidgetConfigOverlay.qml
T

150 lines
5.5 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import qs.Common
import qs.Modules.ControlCenter
import qs.Modules.ControlCenter.Widgets
import qs.Modules.DankBar.Widgets
import qs.Modules.DankDash
import "../utils/widgets.js" as WidgetUtils
import qs.Services
import qs.Widgets
Item {
id: root
property int widgetIndex: -1
property var transientSurfaceTracker: null
property Item _anchor: null
readonly property var widgetData: {
if (widgetIndex < 0)
return null;
const widgets = SettingsData.controlCenterWidgets || [];
return widgets[widgetIndex] || null;
}
readonly property string widgetId: String(widgetData?.id ?? "")
readonly property bool isPlugin: widgetId.startsWith("plugin_")
readonly property bool isDisk: widgetId === "diskUsage"
readonly property bool isIdleInhibitor: widgetId === "idleInhibitor"
readonly property bool isUser: widgetId === "user"
visible: widgetIndex >= 0 || contextMenu.renderActive
function open(index, data, anchorItem) {
widgetIndex = index;
_anchor = anchorItem;
// Placement needs the final menu height, which settles after widgetIndex propagates.
Qt.callLater(() => {
const window = root.QsWindow.window;
const screen = window?.screen;
if (root.widgetIndex !== index || !anchorItem || !screen)
return;
const pos = anchorItem.mapToGlobal(0, 0);
const x = pos.x - screen.x;
const y = pos.y - screen.y;
const menuX = I18n.isRtl ? x : x + anchorItem.width - contextMenu.effectiveMenuWidth;
const aboveY = () => y - contextMenu.effectiveMenuHeight - Theme.spacingS;
if (aboveY() < Theme.spacingS) {
contextMenu.open(screen, menuX, y + anchorItem.height + Theme.spacingS, false);
return;
}
contextMenu.open(screen, menuX, aboveY(), false);
contextMenu.anchorY = Qt.binding(aboveY);
});
}
function close() {
if (!contextMenu.renderActive) {
widgetIndex = -1;
_anchor = null;
return;
}
contextMenu.hide();
}
function persistOption(key, value) {
WidgetUtils.setOption(widgetIndex, key, value);
}
DankContextMenu {
id: contextMenu
layerNamespace: "dms:control-center-widget-options"
minMenuWidth: CcMetrics.configMenuWidth
customContentWidth: CcMetrics.configMenuWidth
keyboardNavigable: true
transientSurfaceTracker: root.transientSurfaceTracker
onOpenStateChanged: {
if (openState)
return;
root.widgetIndex = -1;
if (root._anchor?.visible && root._anchor.enabled)
root._anchor.forceActiveFocus();
root._anchor = null;
}
customContent: Component {
CcGroup {
CcListRow {
visible: root.isPlugin
iconName: "settings"
title: I18n.tr("Plugin settings")
clickable: true
onClicked: {
PopoutService.openSettingsWithTab(SettingsTabs.pluginPrefix + root.widgetId.replace("plugin_", ""));
root.close();
}
}
CcToggleRow {
visible: root.isUser
text: I18n.tr("Background")
checked: root.widgetData?.background === true
onToggled: checked => root.persistOption("background", checked)
}
Repeater {
model: root.isUser ? DashRegistry.sheetOptionSpecs("user") : []
CcToggleRow {
required property var modelData
text: modelData.text
checked: DashRegistry.optionValue(modelData, root.widgetData?.[modelData.key])
onToggled: checked => root.persistOption(modelData.key, checked)
}
}
CcToggleRow {
visible: root.isDisk
text: I18n.tr("Show mount path", "toggle in control center disk usage widget to turn mount path display on or off")
checked: root.widgetData?.showMountPath !== false
onToggled: checked => root.persistOption("showMountPath", checked)
}
CcListRow {
visible: root.isIdleInhibitor
iconName: "timer"
title: I18n.tr("Duration")
body: DankDropdown {
readonly property var presets: IdleInhibitPresets.presetOptions
compactMode: true
dropdownWidth: parent.width
transientSurfaceTracker: contextMenu.transientSurfaceTracker
currentValue: presets.find(p => p.minutes === (root.widgetData?.durationMinutes ?? 0))?.label ?? ""
options: presets.map(p => p.label)
onValueChanged: value => {
const preset = presets.find(p => p.label === value);
if (preset)
root.persistOption("durationMinutes", preset.minutes);
}
}
}
}
}
}
}