mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
* use iconSizeLarge if noBackground is on * widgets: pass noBackground to barIconSize in param
331 lines
11 KiB
QML
331 lines
11 KiB
QML
import QtQuick
|
|
import Quickshell.Io
|
|
import qs.Common
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property string layerNamespacePlugin: "plugin"
|
|
|
|
property var axis: null
|
|
property string section: "center"
|
|
property var parentScreen: null
|
|
property real widgetThickness: 30
|
|
property real barThickness: 48
|
|
property real barSpacing: 4
|
|
property var barConfig: null
|
|
property string pluginId: ""
|
|
property var pluginService: null
|
|
|
|
property string visibilityCommand: ""
|
|
property int visibilityInterval: 0
|
|
property bool conditionVisible: true
|
|
property bool _visibilityOverride: false
|
|
property bool _visibilityOverrideValue: true
|
|
|
|
readonly property bool effectiveVisible: {
|
|
if (_visibilityOverride)
|
|
return _visibilityOverrideValue;
|
|
if (!visibilityCommand)
|
|
return true;
|
|
return conditionVisible;
|
|
}
|
|
|
|
property Component horizontalBarPill: null
|
|
property Component verticalBarPill: null
|
|
property Component popoutContent: null
|
|
property real popoutWidth: 400
|
|
property real popoutHeight: 0
|
|
property var pillClickAction: null
|
|
property var pillRightClickAction: null
|
|
|
|
property Component controlCenterWidget: null
|
|
property string ccWidgetIcon: ""
|
|
property string ccWidgetPrimaryText: ""
|
|
property string ccWidgetSecondaryText: ""
|
|
property bool ccWidgetIsActive: false
|
|
property bool ccWidgetIsToggle: true
|
|
property Component ccDetailContent: null
|
|
property real ccDetailHeight: 250
|
|
|
|
signal ccWidgetToggled
|
|
signal ccWidgetExpanded
|
|
|
|
property var pluginData: ({})
|
|
property var variants: []
|
|
|
|
readonly property bool isVertical: axis?.isVertical ?? false
|
|
readonly property bool hasHorizontalPill: horizontalBarPill !== null
|
|
readonly property bool hasVerticalPill: verticalBarPill !== null
|
|
readonly property bool hasPopout: popoutContent !== null
|
|
|
|
readonly property int iconSize: Theme.barIconSize(barThickness, -4, root.barConfig?.noBackground)
|
|
readonly property int iconSizeLarge: Theme.barIconSize(barThickness, undefined, root.barConfig?.noBackground)
|
|
|
|
Component.onCompleted: {
|
|
loadPluginData();
|
|
if (visibilityCommand)
|
|
Qt.callLater(checkVisibility);
|
|
}
|
|
|
|
onPluginServiceChanged: {
|
|
loadPluginData();
|
|
}
|
|
|
|
onPluginIdChanged: {
|
|
loadPluginData();
|
|
}
|
|
|
|
Connections {
|
|
target: pluginService
|
|
function onPluginDataChanged(changedPluginId) {
|
|
if (changedPluginId === pluginId) {
|
|
loadPluginData();
|
|
}
|
|
}
|
|
}
|
|
|
|
function loadPluginData() {
|
|
if (!pluginService || !pluginId) {
|
|
pluginData = {};
|
|
variants = [];
|
|
return;
|
|
}
|
|
pluginData = SettingsData.getPluginSettingsForPlugin(pluginId);
|
|
variants = pluginService.getPluginVariants(pluginId);
|
|
}
|
|
|
|
function checkVisibility() {
|
|
if (!visibilityCommand) {
|
|
conditionVisible = true;
|
|
return;
|
|
}
|
|
visibilityProcess.running = true;
|
|
}
|
|
|
|
function setVisibilityOverride(visible) {
|
|
_visibilityOverride = true;
|
|
_visibilityOverrideValue = visible;
|
|
}
|
|
|
|
function clearVisibilityOverride() {
|
|
_visibilityOverride = false;
|
|
if (visibilityCommand)
|
|
checkVisibility();
|
|
}
|
|
|
|
onVisibilityCommandChanged: {
|
|
if (visibilityCommand)
|
|
Qt.callLater(checkVisibility);
|
|
else
|
|
conditionVisible = true;
|
|
}
|
|
|
|
onVisibilityIntervalChanged: {
|
|
if (visibilityInterval > 0 && visibilityCommand) {
|
|
visibilityTimer.restart();
|
|
} else {
|
|
visibilityTimer.stop();
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: visibilityTimer
|
|
interval: root.visibilityInterval * 1000
|
|
repeat: true
|
|
running: root.visibilityInterval > 0 && root.visibilityCommand !== ""
|
|
onTriggered: root.checkVisibility()
|
|
}
|
|
|
|
Process {
|
|
id: visibilityProcess
|
|
command: ["sh", "-c", root.visibilityCommand]
|
|
running: false
|
|
onExited: (exitCode, exitStatus) => {
|
|
root.conditionVisible = (exitCode === 0);
|
|
}
|
|
}
|
|
|
|
function createVariant(variantName, variantConfig) {
|
|
if (!pluginService || !pluginId) {
|
|
return null;
|
|
}
|
|
return pluginService.createPluginVariant(pluginId, variantName, variantConfig);
|
|
}
|
|
|
|
function removeVariant(variantId) {
|
|
if (!pluginService || !pluginId) {
|
|
return;
|
|
}
|
|
pluginService.removePluginVariant(pluginId, variantId);
|
|
}
|
|
|
|
function updateVariant(variantId, variantConfig) {
|
|
if (!pluginService || !pluginId) {
|
|
return;
|
|
}
|
|
pluginService.updatePluginVariant(pluginId, variantId, variantConfig);
|
|
}
|
|
|
|
width: isVertical ? (hasVerticalPill ? verticalPill.width : 0) : (hasHorizontalPill ? horizontalPill.width : 0)
|
|
height: isVertical ? (hasVerticalPill ? verticalPill.height : 0) : (hasHorizontalPill ? horizontalPill.height : 0)
|
|
|
|
BasePill {
|
|
id: horizontalPill
|
|
visible: !isVertical && hasHorizontalPill
|
|
opacity: root.effectiveVisible ? 1 : 0
|
|
axis: root.axis
|
|
section: root.section
|
|
popoutTarget: hasPopout ? pluginPopout : null
|
|
parentScreen: root.parentScreen
|
|
widgetThickness: root.widgetThickness
|
|
barThickness: root.barThickness
|
|
barSpacing: root.barSpacing
|
|
barConfig: root.barConfig
|
|
content: root.horizontalBarPill
|
|
|
|
states: State {
|
|
name: "hidden"
|
|
when: !root.effectiveVisible
|
|
PropertyChanges {
|
|
target: horizontalPill
|
|
width: 0
|
|
}
|
|
}
|
|
|
|
transitions: Transition {
|
|
NumberAnimation {
|
|
properties: "width,opacity"
|
|
duration: Theme.shortDuration
|
|
easing.type: Theme.standardEasing
|
|
}
|
|
}
|
|
|
|
onClicked: {
|
|
if (pillClickAction) {
|
|
if (pillClickAction.length === 0) {
|
|
pillClickAction();
|
|
} else {
|
|
const globalPos = mapToItem(null, 0, 0);
|
|
const currentScreen = parentScreen || Screen;
|
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
|
|
pillClickAction(pos.x, pos.y, pos.width, section, currentScreen);
|
|
}
|
|
} else if (hasPopout) {
|
|
pluginPopout.toggle();
|
|
}
|
|
}
|
|
onRightClicked: {
|
|
if (pillRightClickAction) {
|
|
if (pillRightClickAction.length === 0) {
|
|
pillRightClickAction();
|
|
} else {
|
|
const globalPos = mapToItem(null, 0, 0);
|
|
const currentScreen = parentScreen || Screen;
|
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
|
|
pillRightClickAction(pos.x, pos.y, pos.width, section, currentScreen);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BasePill {
|
|
id: verticalPill
|
|
visible: isVertical && hasVerticalPill
|
|
opacity: root.effectiveVisible ? 1 : 0
|
|
axis: root.axis
|
|
section: root.section
|
|
popoutTarget: hasPopout ? pluginPopout : null
|
|
parentScreen: root.parentScreen
|
|
widgetThickness: root.widgetThickness
|
|
barThickness: root.barThickness
|
|
barSpacing: root.barSpacing
|
|
barConfig: root.barConfig
|
|
content: root.verticalBarPill
|
|
isVerticalOrientation: true
|
|
|
|
states: State {
|
|
name: "hidden"
|
|
when: !root.effectiveVisible
|
|
PropertyChanges {
|
|
target: verticalPill
|
|
height: 0
|
|
}
|
|
}
|
|
|
|
transitions: Transition {
|
|
NumberAnimation {
|
|
properties: "height,opacity"
|
|
duration: Theme.shortDuration
|
|
easing.type: Theme.standardEasing
|
|
}
|
|
}
|
|
|
|
onClicked: {
|
|
if (pillClickAction) {
|
|
if (pillClickAction.length === 0) {
|
|
pillClickAction();
|
|
} else {
|
|
const globalPos = mapToItem(null, 0, 0);
|
|
const currentScreen = parentScreen || Screen;
|
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
|
|
pillClickAction(pos.x, pos.y, pos.width, section, currentScreen);
|
|
}
|
|
} else if (hasPopout) {
|
|
pluginPopout.toggle();
|
|
}
|
|
}
|
|
onRightClicked: {
|
|
if (pillRightClickAction) {
|
|
if (pillRightClickAction.length === 0) {
|
|
pillRightClickAction();
|
|
} else {
|
|
const globalPos = mapToItem(null, 0, 0);
|
|
const currentScreen = parentScreen || Screen;
|
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width);
|
|
pillRightClickAction(pos.x, pos.y, pos.width, section, currentScreen);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function closePopout() {
|
|
if (pluginPopout) {
|
|
pluginPopout.close();
|
|
}
|
|
}
|
|
|
|
function triggerPopout() {
|
|
if (pillClickAction) {
|
|
if (pillClickAction.length === 0) {
|
|
pillClickAction();
|
|
return;
|
|
}
|
|
const pill = isVertical ? verticalPill : horizontalPill;
|
|
const globalPos = pill.mapToItem(null, 0, 0);
|
|
const currentScreen = parentScreen || Screen;
|
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, pill.width);
|
|
pillClickAction(pos.x, pos.y, pos.width, section, currentScreen);
|
|
return;
|
|
}
|
|
if (!hasPopout)
|
|
return;
|
|
|
|
const pill = isVertical ? verticalPill : horizontalPill;
|
|
const globalPos = pill.visualContent.mapToItem(null, 0, 0);
|
|
const currentScreen = parentScreen || Screen;
|
|
const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1));
|
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, pill.visualWidth, barSpacing, barPosition, barConfig);
|
|
|
|
pluginPopout.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen, barPosition, barThickness, barSpacing, barConfig);
|
|
pluginPopout.toggle();
|
|
}
|
|
|
|
PluginPopout {
|
|
id: pluginPopout
|
|
contentWidth: root.popoutWidth
|
|
contentHeight: root.popoutHeight
|
|
pluginContent: root.popoutContent
|
|
}
|
|
}
|