mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
265 lines
9.2 KiB
QML
265 lines
9.2 KiB
QML
import QtQuick
|
|
import Quickshell.Wayland
|
|
import qs.Common
|
|
import qs.Modules.ControlCenter.Details
|
|
import qs.Services
|
|
import qs.Widgets
|
|
import qs.Modules.ControlCenter.Components
|
|
import qs.Modules.ControlCenter.Models
|
|
import "./utils/state.js" as StateUtils
|
|
|
|
DankPopout {
|
|
id: root
|
|
|
|
layerNamespace: "dms:control-center"
|
|
|
|
property string expandedSection: ""
|
|
property var triggerScreen: null
|
|
property bool editMode: false
|
|
property int expandedWidgetIndex: -1
|
|
property var expandedWidgetData: null
|
|
property bool powerMenuOpen: powerMenuModalLoader?.item?.shouldBeVisible ?? false
|
|
|
|
signal lockRequested
|
|
|
|
function collapseAll() {
|
|
expandedSection = "";
|
|
expandedWidgetIndex = -1;
|
|
expandedWidgetData = null;
|
|
}
|
|
|
|
onEditModeChanged: {
|
|
if (editMode) {
|
|
collapseAll();
|
|
}
|
|
}
|
|
|
|
onVisibleChanged: {
|
|
if (!visible) {
|
|
collapseAll();
|
|
}
|
|
}
|
|
|
|
readonly property color _containerBg: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
|
|
|
function openWithSection(section) {
|
|
StateUtils.openWithSection(root, section);
|
|
}
|
|
|
|
function toggleSection(section) {
|
|
StateUtils.toggleSection(root, section);
|
|
}
|
|
|
|
popupWidth: 550
|
|
popupHeight: {
|
|
const screenHeight = (triggerScreen?.height ?? 1080);
|
|
const maxHeight = screenHeight - 100;
|
|
const contentHeight = contentLoader.item && contentLoader.item.implicitHeight > 0 ? contentLoader.item.implicitHeight + 20 : 400;
|
|
return Math.min(maxHeight, contentHeight);
|
|
}
|
|
triggerX: 0
|
|
triggerY: 0
|
|
triggerWidth: 80
|
|
positioning: ""
|
|
screen: triggerScreen
|
|
shouldBeVisible: false
|
|
|
|
property bool credentialsPromptOpen: NetworkService.credentialsRequested
|
|
property bool wifiPasswordModalOpen: PopoutService.wifiPasswordModal?.visible ?? false
|
|
property bool polkitModalOpen: PopoutService.polkitAuthModal?.visible ?? false
|
|
property bool anyModalOpen: credentialsPromptOpen || wifiPasswordModalOpen || polkitModalOpen || powerMenuOpen
|
|
|
|
backgroundInteractive: !anyModalOpen
|
|
|
|
customKeyboardFocus: {
|
|
if (!shouldBeVisible)
|
|
return WlrKeyboardFocus.None;
|
|
if (anyModalOpen)
|
|
return WlrKeyboardFocus.None;
|
|
if (CompositorService.useHyprlandFocusGrab)
|
|
return WlrKeyboardFocus.OnDemand;
|
|
return WlrKeyboardFocus.Exclusive;
|
|
}
|
|
|
|
onBackgroundClicked: close()
|
|
|
|
onShouldBeVisibleChanged: {
|
|
if (shouldBeVisible) {
|
|
collapseAll();
|
|
Qt.callLater(() => {
|
|
if (NetworkService.activeService)
|
|
NetworkService.activeService.autoRefreshEnabled = NetworkService.wifiEnabled;
|
|
});
|
|
} else {
|
|
Qt.callLater(() => {
|
|
if (NetworkService.activeService) {
|
|
NetworkService.activeService.autoRefreshEnabled = false;
|
|
}
|
|
if (BluetoothService.adapter && BluetoothService.adapter.discovering)
|
|
BluetoothService.adapter.discovering = false;
|
|
editMode = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
WidgetModel {
|
|
id: widgetModel
|
|
}
|
|
|
|
content: Component {
|
|
Rectangle {
|
|
id: controlContent
|
|
|
|
implicitHeight: mainColumn.implicitHeight + Theme.spacingM
|
|
property alias bluetoothCodecSelector: bluetoothCodecSelector
|
|
|
|
color: {
|
|
const transparency = Theme.popupTransparency;
|
|
const surface = Theme.surfaceContainer || Qt.rgba(0.1, 0.1, 0.1, 1);
|
|
return Qt.rgba(surface.r, surface.g, surface.b, transparency);
|
|
}
|
|
radius: Theme.cornerRadius
|
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
|
border.width: 0
|
|
antialiasing: true
|
|
smooth: true
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: Qt.rgba(0, 0, 0, 0.6)
|
|
radius: parent.radius
|
|
visible: root.powerMenuOpen
|
|
z: 5000
|
|
|
|
Behavior on opacity {
|
|
NumberAnimation {
|
|
duration: 200
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
}
|
|
|
|
Column {
|
|
id: mainColumn
|
|
width: parent.width - Theme.spacingL * 2
|
|
x: Theme.spacingL
|
|
y: Theme.spacingL
|
|
spacing: Theme.spacingS
|
|
|
|
HeaderPane {
|
|
id: headerPane
|
|
width: parent.width
|
|
editMode: root.editMode
|
|
onEditModeToggled: root.editMode = !root.editMode
|
|
onPowerButtonClicked: {
|
|
if (powerMenuModalLoader) {
|
|
powerMenuModalLoader.active = true;
|
|
if (powerMenuModalLoader.item) {
|
|
const bounds = Qt.rect(root.alignedX, root.alignedY, root.popupWidth, root.popupHeight);
|
|
powerMenuModalLoader.item.openFromControlCenter(bounds, root.screen);
|
|
}
|
|
}
|
|
}
|
|
onLockRequested: {
|
|
root.close();
|
|
root.lockRequested();
|
|
}
|
|
onSettingsButtonClicked: {
|
|
root.close();
|
|
}
|
|
}
|
|
|
|
DragDropGrid {
|
|
id: widgetGrid
|
|
width: parent.width
|
|
editMode: root.editMode
|
|
expandedSection: root.expandedSection
|
|
expandedWidgetIndex: root.expandedWidgetIndex
|
|
expandedWidgetData: root.expandedWidgetData
|
|
model: widgetModel
|
|
bluetoothCodecSelector: bluetoothCodecSelector
|
|
colorPickerModal: root.colorPickerModal
|
|
screenName: root.triggerScreen?.name || ""
|
|
screenModel: root.triggerScreen?.model || ""
|
|
parentScreen: root.triggerScreen
|
|
onExpandClicked: (widgetData, globalIndex) => {
|
|
root.expandedWidgetIndex = globalIndex;
|
|
root.expandedWidgetData = widgetData;
|
|
if (widgetData.id === "diskUsage") {
|
|
root.toggleSection("diskUsage_" + (widgetData.instanceId || "default"));
|
|
} else if (widgetData.id === "brightnessSlider") {
|
|
root.toggleSection("brightnessSlider_" + (widgetData.instanceId || "default"));
|
|
} else {
|
|
root.toggleSection(widgetData.id);
|
|
}
|
|
}
|
|
onRemoveWidget: index => widgetModel.removeWidget(index)
|
|
onMoveWidget: (fromIndex, toIndex) => widgetModel.moveWidget(fromIndex, toIndex)
|
|
onToggleWidgetSize: index => widgetModel.toggleWidgetSize(index)
|
|
onCollapseRequested: root.collapseAll()
|
|
}
|
|
|
|
EditControls {
|
|
width: parent.width
|
|
visible: editMode
|
|
popoutContent: controlContent
|
|
availableWidgets: {
|
|
if (!editMode)
|
|
return [];
|
|
const existingIds = (SettingsData.controlCenterWidgets || []).map(w => w.id);
|
|
const allWidgets = widgetModel.baseWidgetDefinitions.concat(widgetModel.getPluginWidgets());
|
|
return allWidgets.filter(w => w.allowMultiple || !existingIds.includes(w.id));
|
|
}
|
|
onAddWidget: widgetId => widgetModel.addWidget(widgetId)
|
|
onResetToDefault: () => widgetModel.resetToDefault()
|
|
onClearAll: () => widgetModel.clearAll()
|
|
}
|
|
}
|
|
|
|
BluetoothCodecSelector {
|
|
id: bluetoothCodecSelector
|
|
anchors.fill: parent
|
|
z: 10000
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: networkDetailComponent
|
|
NetworkDetail {}
|
|
}
|
|
|
|
Component {
|
|
id: bluetoothDetailComponent
|
|
BluetoothDetail {
|
|
id: bluetoothDetail
|
|
onShowCodecSelector: function (device) {
|
|
if (contentLoader.item && contentLoader.item.bluetoothCodecSelector) {
|
|
contentLoader.item.bluetoothCodecSelector.show(device);
|
|
contentLoader.item.bluetoothCodecSelector.codecSelected.connect(function (deviceAddress, codecName) {
|
|
bluetoothDetail.updateDeviceCodecDisplay(deviceAddress, codecName);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: audioOutputDetailComponent
|
|
AudioOutputDetail {}
|
|
}
|
|
|
|
Component {
|
|
id: audioInputDetailComponent
|
|
AudioInputDetail {}
|
|
}
|
|
|
|
Component {
|
|
id: batteryDetailComponent
|
|
BatteryDetail {}
|
|
}
|
|
|
|
property var colorPickerModal: null
|
|
property var powerMenuModalLoader: null
|
|
}
|