mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-27 13:35:18 -04:00
tray: add automatic overflow popup (#2629)
This commit is contained in:
@@ -405,6 +405,9 @@ Singleton {
|
|||||||
property int barMaxVisibleApps: 0
|
property int barMaxVisibleApps: 0
|
||||||
property int barMaxVisibleRunningApps: 0
|
property int barMaxVisibleRunningApps: 0
|
||||||
property bool barShowOverflowBadge: true
|
property bool barShowOverflowBadge: true
|
||||||
|
property bool trayAutoOverflow: true
|
||||||
|
property bool trayPopupSingleLine: true
|
||||||
|
property int trayMaxVisibleItems: 0
|
||||||
property bool appsDockHideIndicators: false
|
property bool appsDockHideIndicators: false
|
||||||
property bool appsDockColorizeActive: false
|
property bool appsDockColorizeActive: false
|
||||||
property string appsDockActiveColorMode: "primary"
|
property string appsDockActiveColorMode: "primary"
|
||||||
|
|||||||
@@ -164,6 +164,9 @@ var SPEC = {
|
|||||||
barMaxVisibleApps: { def: 0 },
|
barMaxVisibleApps: { def: 0 },
|
||||||
barMaxVisibleRunningApps: { def: 0 },
|
barMaxVisibleRunningApps: { def: 0 },
|
||||||
barShowOverflowBadge: { def: true },
|
barShowOverflowBadge: { def: true },
|
||||||
|
trayAutoOverflow: { def: true },
|
||||||
|
trayPopupSingleLine: { def: true },
|
||||||
|
trayMaxVisibleItems: { def: 0 },
|
||||||
appsDockHideIndicators: { def: false },
|
appsDockHideIndicators: { def: false },
|
||||||
appsDockColorizeActive: { def: false },
|
appsDockColorizeActive: { def: false },
|
||||||
appsDockActiveColorMode: { def: "primary" },
|
appsDockActiveColorMode: { def: "primary" },
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Item {
|
|||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
property var blurBarWindow: null
|
property var blurBarWindow: null
|
||||||
|
property real sectionAvailablePrimarySize: 0
|
||||||
property bool overrideAxisLayout: false
|
property bool overrideAxisLayout: false
|
||||||
property bool forceVerticalLayout: false
|
property bool forceVerticalLayout: false
|
||||||
|
|
||||||
@@ -359,6 +360,7 @@ Item {
|
|||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
blurBarWindow: root.blurBarWindow
|
blurBarWindow: root.blurBarWindow
|
||||||
|
sectionAvailablePrimarySize: root.sectionAvailablePrimarySize
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === centerRepeater.count - 1
|
isLast: index === centerRepeater.count - 1
|
||||||
sectionSpacing: parent.itemSpacing
|
sectionSpacing: parent.itemSpacing
|
||||||
|
|||||||
@@ -497,6 +497,7 @@ Item {
|
|||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
barSpacing: barConfig?.spacing ?? 4
|
barSpacing: barConfig?.spacing ?? 4
|
||||||
|
sectionAvailablePrimarySize: Math.max(1, hCenterSection.x > 0 ? hCenterSection.x : parent.width / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
@@ -529,6 +530,7 @@ Item {
|
|||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
barSpacing: barConfig?.spacing ?? 4
|
barSpacing: barConfig?.spacing ?? 4
|
||||||
|
sectionAvailablePrimarySize: Math.max(1, hCenterSection.x > 0 ? parent.width - (hCenterSection.x + hCenterSection.width) : parent.width / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
@@ -561,6 +563,7 @@ Item {
|
|||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
barSpacing: barConfig?.spacing ?? 4
|
barSpacing: barConfig?.spacing ?? 4
|
||||||
|
sectionAvailablePrimarySize: Math.max(1, hRightSection.x > 0 ? hRightSection.x - (hLeftSection.x + hLeftSection.width) : parent.width / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
@@ -600,6 +603,7 @@ Item {
|
|||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
barSpacing: barConfig?.spacing ?? 4
|
barSpacing: barConfig?.spacing ?? 4
|
||||||
|
sectionAvailablePrimarySize: Math.max(1, vCenterSection.y > 0 ? vCenterSection.y : parent.height / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
@@ -633,6 +637,7 @@ Item {
|
|||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
barSpacing: barConfig?.spacing ?? 4
|
barSpacing: barConfig?.spacing ?? 4
|
||||||
|
sectionAvailablePrimarySize: Math.max(1, vRightSection.y > 0 ? vRightSection.y - (vLeftSection.y + vLeftSection.height) : parent.height / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
@@ -667,6 +672,7 @@ Item {
|
|||||||
widgetThickness: barWindow.widgetThickness
|
widgetThickness: barWindow.widgetThickness
|
||||||
barThickness: barWindow.effectiveBarThickness
|
barThickness: barWindow.effectiveBarThickness
|
||||||
barSpacing: barConfig?.spacing ?? 4
|
barSpacing: barConfig?.spacing ?? 4
|
||||||
|
sectionAvailablePrimarySize: Math.max(1, vCenterSection.y > 0 ? parent.height - (vCenterSection.y + vCenterSection.height) : parent.height / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Item {
|
|||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
property var blurBarWindow: null
|
property var blurBarWindow: null
|
||||||
|
property real sectionAvailablePrimarySize: 0
|
||||||
property bool overrideAxisLayout: false
|
property bool overrideAxisLayout: false
|
||||||
property bool forceVerticalLayout: false
|
property bool forceVerticalLayout: false
|
||||||
|
|
||||||
@@ -61,6 +62,7 @@ Item {
|
|||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
blurBarWindow: root.blurBarWindow
|
blurBarWindow: root.blurBarWindow
|
||||||
|
sectionAvailablePrimarySize: root.sectionAvailablePrimarySize
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === rowRepeater.count - 1
|
isLast: index === rowRepeater.count - 1
|
||||||
sectionSpacing: parent.rowSpacing
|
sectionSpacing: parent.rowSpacing
|
||||||
@@ -106,6 +108,7 @@ Item {
|
|||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
blurBarWindow: root.blurBarWindow
|
blurBarWindow: root.blurBarWindow
|
||||||
|
sectionAvailablePrimarySize: root.sectionAvailablePrimarySize
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === columnRepeater.count - 1
|
isLast: index === columnRepeater.count - 1
|
||||||
sectionSpacing: parent.columnSpacing
|
sectionSpacing: parent.columnSpacing
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Item {
|
|||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
property var blurBarWindow: null
|
property var blurBarWindow: null
|
||||||
|
property real sectionAvailablePrimarySize: 0
|
||||||
property bool overrideAxisLayout: false
|
property bool overrideAxisLayout: false
|
||||||
property bool forceVerticalLayout: false
|
property bool forceVerticalLayout: false
|
||||||
|
|
||||||
@@ -63,6 +64,7 @@ Item {
|
|||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
blurBarWindow: root.blurBarWindow
|
blurBarWindow: root.blurBarWindow
|
||||||
|
sectionAvailablePrimarySize: root.sectionAvailablePrimarySize
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === rowRepeater.count - 1
|
isLast: index === rowRepeater.count - 1
|
||||||
sectionSpacing: parent.rowSpacing
|
sectionSpacing: parent.rowSpacing
|
||||||
@@ -108,6 +110,7 @@ Item {
|
|||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
blurBarWindow: root.blurBarWindow
|
blurBarWindow: root.blurBarWindow
|
||||||
|
sectionAvailablePrimarySize: root.sectionAvailablePrimarySize
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === columnRepeater.count - 1
|
isLast: index === columnRepeater.count - 1
|
||||||
sectionSpacing: parent.columnSpacing
|
sectionSpacing: parent.columnSpacing
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ Loader {
|
|||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
property var blurBarWindow: null
|
property var blurBarWindow: null
|
||||||
|
property real sectionAvailablePrimarySize: 0
|
||||||
property bool isFirst: false
|
property bool isFirst: false
|
||||||
property bool isLast: false
|
property bool isLast: false
|
||||||
property real sectionSpacing: 0
|
property real sectionSpacing: 0
|
||||||
@@ -141,6 +142,14 @@ Loader {
|
|||||||
restoreMode: Binding.RestoreNone
|
restoreMode: Binding.RestoreNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: root.item
|
||||||
|
when: root.item && "sectionAvailablePrimarySize" in root.item
|
||||||
|
property: "sectionAvailablePrimarySize"
|
||||||
|
value: root.sectionAvailablePrimarySize
|
||||||
|
restoreMode: Binding.RestoreNone
|
||||||
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
target: root.item
|
target: root.item
|
||||||
when: root.item && "isLeftBarEdge" in root.item
|
when: root.item && "isLeftBarEdge" in root.item
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ BasePill {
|
|||||||
property bool isAtBottom: false
|
property bool isAtBottom: false
|
||||||
property bool isAutoHideBar: false
|
property bool isAutoHideBar: false
|
||||||
property bool useOverflowPopup: !widgetData?.trayUseInlineExpansion
|
property bool useOverflowPopup: !widgetData?.trayUseInlineExpansion
|
||||||
|
property bool useSingleLineOverflowPopup: widgetData?.trayPopupSingleLine ?? SettingsData.trayPopupSingleLine
|
||||||
|
property bool useAutomaticOverflow: widgetData?.trayAutoOverflow ?? SettingsData.trayAutoOverflow
|
||||||
|
property int configuredMaxVisibleItems: widgetData?.trayMaxVisibleItems ?? SettingsData.trayMaxVisibleItems
|
||||||
|
property real sectionAvailablePrimarySize: 0
|
||||||
readonly property var hiddenTrayIds: {
|
readonly property var hiddenTrayIds: {
|
||||||
const envValue = Quickshell.env("DMS_HIDE_TRAYIDS") || "";
|
const envValue = Quickshell.env("DMS_HIDE_TRAYIDS") || "";
|
||||||
return envValue ? envValue.split(",").map(id => id.trim().toLowerCase()) : [];
|
return envValue ? envValue.split(",").map(id => id.trim().toLowerCase()) : [];
|
||||||
@@ -146,12 +150,32 @@ BasePill {
|
|||||||
|
|
||||||
readonly property var allSortedTrayItems: sortByPreferredOrder(allTrayItems, _trayOrderTrigger)
|
readonly property var allSortedTrayItems: sortByPreferredOrder(allTrayItems, _trayOrderTrigger)
|
||||||
readonly property var allSortedTrayItemKeys: allSortedTrayItems.map(item => getTrayItemKey(item))
|
readonly property var allSortedTrayItemKeys: allSortedTrayItems.map(item => getTrayItemKey(item))
|
||||||
readonly property var mainBarItemsRaw: allSortedTrayItems.filter(item => !SessionData.isHiddenTrayId(root.getTrayItemKey(item)))
|
readonly property var visibleSortedTrayItems: allSortedTrayItems.filter(item => !SessionData.isHiddenTrayId(root.getTrayItemKey(item)))
|
||||||
|
readonly property int automaticVisibleItemLimit: {
|
||||||
|
if (!root.useAutomaticOverflow)
|
||||||
|
return root.visibleSortedTrayItems.length;
|
||||||
|
|
||||||
|
const explicitLimit = Number(root.configuredMaxVisibleItems || 0);
|
||||||
|
if (explicitLimit > 0)
|
||||||
|
return Math.max(1, Math.min(root.visibleSortedTrayItems.length, explicitLimit));
|
||||||
|
|
||||||
|
const scale = (typeof CompositorService !== "undefined" && CompositorService.getScreenScale) ? Math.max(1, CompositorService.getScreenScale(root.parentScreen)) : 1;
|
||||||
|
const sectionPrimary = root.sectionAvailablePrimarySize > 0 ? root.sectionAvailablePrimarySize : (root.isVerticalOrientation ? (root.parentScreen?.height || 0) : (root.parentScreen?.width || 0));
|
||||||
|
const logicalPrimary = sectionPrimary > 0 ? (sectionPrimary / scale) : 640;
|
||||||
|
const maxTrayShare = root.isVerticalOrientation ? 0.55 : 0.50;
|
||||||
|
const itemSize = Math.max(1, root.trayItemSize);
|
||||||
|
const slots = Math.floor((logicalPrimary * maxTrayShare) / itemSize);
|
||||||
|
return Math.max(2, Math.min(10, Math.min(root.visibleSortedTrayItems.length, slots)));
|
||||||
|
}
|
||||||
|
readonly property var mainBarItemsRaw: visibleSortedTrayItems.slice(0, automaticVisibleItemLimit)
|
||||||
readonly property var mainBarItems: mainBarItemsRaw.map((item, idx) => ({
|
readonly property var mainBarItems: mainBarItemsRaw.map((item, idx) => ({
|
||||||
key: getTrayItemKey(item),
|
key: getTrayItemKey(item),
|
||||||
item: item
|
item: item
|
||||||
}))
|
}))
|
||||||
readonly property var hiddenBarItems: allSortedTrayItems.filter(item => SessionData.isHiddenTrayId(root.getTrayItemKey(item)))
|
readonly property var autoOverflowBarItems: visibleSortedTrayItems.slice(automaticVisibleItemLimit)
|
||||||
|
readonly property var manualHiddenBarItems: allSortedTrayItems.filter(item => SessionData.isHiddenTrayId(root.getTrayItemKey(item)))
|
||||||
|
readonly property var hiddenBarItemKeys: manualHiddenBarItems.concat(autoOverflowBarItems).map(item => root.getTrayItemKey(item))
|
||||||
|
readonly property var hiddenBarItems: allSortedTrayItems.filter(item => hiddenBarItemKeys.indexOf(root.getTrayItemKey(item)) !== -1)
|
||||||
readonly property string trayIconTintMode: {
|
readonly property string trayIconTintMode: {
|
||||||
const configuredMode = SettingsData.systemTrayIconTintMode || "none";
|
const configuredMode = SettingsData.systemTrayIconTintMode || "none";
|
||||||
switch (configuredMode) {
|
switch (configuredMode) {
|
||||||
@@ -219,6 +243,10 @@ BasePill {
|
|||||||
|
|
||||||
const fromKey = mainBarItems[visibleFromIndex]?.key ?? null;
|
const fromKey = mainBarItems[visibleFromIndex]?.key ?? null;
|
||||||
const toKey = mainBarItems[visibleToIndex]?.key ?? null;
|
const toKey = mainBarItems[visibleToIndex]?.key ?? null;
|
||||||
|
moveTrayItemKeyInFullOrder(fromKey, toKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveTrayItemKeyInFullOrder(fromKey, toKey) {
|
||||||
if (!fromKey || !toKey)
|
if (!fromKey || !toKey)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -233,10 +261,103 @@ BasePill {
|
|||||||
SessionData.setTrayItemOrder(fullOrder);
|
SessionData.setTrayItemOrder(fullOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function promoteTrayItemToBar(item) {
|
||||||
|
const itemKey = getTrayItemKey(item);
|
||||||
|
if (!itemKey)
|
||||||
|
return;
|
||||||
|
if (SessionData.isHiddenTrayId(itemKey)) {
|
||||||
|
SessionData.showTrayId(itemKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullOrder = [...allSortedTrayItemKeys];
|
||||||
|
const fromIndex = fullOrder.indexOf(itemKey);
|
||||||
|
if (fromIndex < 0)
|
||||||
|
return;
|
||||||
|
const movedKey = fullOrder.splice(fromIndex, 1)[0];
|
||||||
|
const targetIndex = Math.max(0, Math.min(root.automaticVisibleItemLimit - 1, fullOrder.length));
|
||||||
|
fullOrder.splice(targetIndex, 0, movedKey);
|
||||||
|
SessionData.setTrayItemOrder(fullOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isManualHiddenTrayItem(item) {
|
||||||
|
return SessionData.isHiddenTrayId(getTrayItemKey(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAutoOverflowTrayItem(item) {
|
||||||
|
const key = getTrayItemKey(item);
|
||||||
|
return key && !isManualHiddenTrayItem(item) && root.autoOverflowBarItems.some(overflowItem => getTrayItemKey(overflowItem) === key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragShiftOffset(index, draggedIndex, dropTargetIndex, shiftAmount) {
|
||||||
|
if (draggedIndex < 0 || index === draggedIndex || dropTargetIndex < 0)
|
||||||
|
return 0;
|
||||||
|
if (draggedIndex < dropTargetIndex && index > draggedIndex && index <= dropTargetIndex)
|
||||||
|
return -shiftAmount;
|
||||||
|
if (draggedIndex > dropTargetIndex && index >= dropTargetIndex && index < draggedIndex)
|
||||||
|
return shiftAmount;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function beginMainDrag(visualIndex, reversed) {
|
||||||
|
root.draggedIndex = reversed ? (root.mainBarItems.length - 1 - visualIndex) : visualIndex;
|
||||||
|
root.dropTargetIndex = root.draggedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMainDrag(axisOffset, visualIndex, reversed) {
|
||||||
|
const itemSize = root.trayItemSize;
|
||||||
|
const slotOffset = Math.round(axisOffset / itemSize);
|
||||||
|
const visualTargetIndex = Math.max(0, Math.min(root.mainBarItems.length - 1, visualIndex + slotOffset));
|
||||||
|
const newTargetIndex = reversed ? (root.mainBarItems.length - 1 - visualTargetIndex) : visualTargetIndex;
|
||||||
|
if (newTargetIndex !== root.dropTargetIndex)
|
||||||
|
root.dropTargetIndex = newTargetIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishMainDrag() {
|
||||||
|
const didReorder = root.dropTargetIndex >= 0 && root.dropTargetIndex !== root.draggedIndex;
|
||||||
|
if (didReorder) {
|
||||||
|
root.suppressShiftAnimation = true;
|
||||||
|
root.moveTrayItemInFullOrder(root.draggedIndex, root.dropTargetIndex);
|
||||||
|
Qt.callLater(() => root.suppressShiftAnimation = false);
|
||||||
|
}
|
||||||
|
root.draggedIndex = -1;
|
||||||
|
root.dropTargetIndex = -1;
|
||||||
|
return didReorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
function beginPopupDrag(index) {
|
||||||
|
root.popupDraggedIndex = index;
|
||||||
|
root.popupDropTargetIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePopupDrag(axisOffset, index) {
|
||||||
|
const itemSize = root.trayItemSize + 6;
|
||||||
|
const slotOffset = Math.round(axisOffset / itemSize);
|
||||||
|
const newTargetIndex = Math.max(0, Math.min(root.hiddenBarItems.length - 1, index + slotOffset));
|
||||||
|
if (newTargetIndex !== root.popupDropTargetIndex)
|
||||||
|
root.popupDropTargetIndex = newTargetIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishPopupDrag() {
|
||||||
|
const didReorder = root.popupDropTargetIndex >= 0 && root.popupDropTargetIndex !== root.popupDraggedIndex;
|
||||||
|
if (didReorder) {
|
||||||
|
const fromItem = root.hiddenBarItems[root.popupDraggedIndex];
|
||||||
|
const toItem = root.hiddenBarItems[root.popupDropTargetIndex];
|
||||||
|
root.suppressShiftAnimation = true;
|
||||||
|
root.moveTrayItemKeyInFullOrder(root.getTrayItemKey(fromItem), root.getTrayItemKey(toItem));
|
||||||
|
Qt.callLater(() => root.suppressShiftAnimation = false);
|
||||||
|
}
|
||||||
|
root.popupDraggedIndex = -1;
|
||||||
|
root.popupDropTargetIndex = -1;
|
||||||
|
return didReorder;
|
||||||
|
}
|
||||||
|
|
||||||
property int draggedIndex: -1
|
property int draggedIndex: -1
|
||||||
property int dropTargetIndex: -1
|
property int dropTargetIndex: -1
|
||||||
|
property int popupDraggedIndex: -1
|
||||||
|
property int popupDropTargetIndex: -1
|
||||||
property bool suppressShiftAnimation: false
|
property bool suppressShiftAnimation: false
|
||||||
readonly property bool hasHiddenItems: allTrayItems.length > mainBarItems.length
|
readonly property bool hasHiddenItems: hiddenBarItems.length > 0
|
||||||
readonly property bool inlineExpanded: hasHiddenItems && !useOverflowPopup && menuOpen
|
readonly property bool inlineExpanded: hasHiddenItems && !useOverflowPopup && menuOpen
|
||||||
visible: allTrayItems.length > 0
|
visible: allTrayItems.length > 0
|
||||||
opacity: allTrayItems.length > 0 ? 1 : 0
|
opacity: allTrayItems.length > 0 ? 1 : 0
|
||||||
@@ -351,22 +472,7 @@ BasePill {
|
|||||||
height: root.barThickness
|
height: root.barThickness
|
||||||
z: dragHandler.dragging ? 100 : 0
|
z: dragHandler.dragging ? 100 : 0
|
||||||
|
|
||||||
property real shiftOffset: {
|
property real shiftOffset: root.dragShiftOffset(index, root.draggedIndex, root.dropTargetIndex, root.trayItemSize)
|
||||||
if (root.draggedIndex < 0)
|
|
||||||
return 0;
|
|
||||||
if (index === root.draggedIndex)
|
|
||||||
return 0;
|
|
||||||
const dragIdx = root.draggedIndex;
|
|
||||||
const dropIdx = root.dropTargetIndex;
|
|
||||||
const shiftAmount = root.trayItemSize;
|
|
||||||
if (dropIdx < 0)
|
|
||||||
return 0;
|
|
||||||
if (dragIdx < dropIdx && index > dragIdx && index <= dropIdx)
|
|
||||||
return -shiftAmount;
|
|
||||||
if (dragIdx > dropIdx && index >= dropIdx && index < dragIdx)
|
|
||||||
return shiftAmount;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform: Translate {
|
transform: Translate {
|
||||||
x: delegateRoot.shiftOffset
|
x: delegateRoot.shiftOffset
|
||||||
@@ -466,19 +572,12 @@ BasePill {
|
|||||||
onReleased: mouse => {
|
onReleased: mouse => {
|
||||||
longPressTimer.stop();
|
longPressTimer.stop();
|
||||||
const wasDragging = dragHandler.dragging;
|
const wasDragging = dragHandler.dragging;
|
||||||
const didReorder = wasDragging && root.dropTargetIndex >= 0 && root.dropTargetIndex !== root.draggedIndex;
|
if (wasDragging)
|
||||||
|
root.finishMainDrag();
|
||||||
if (didReorder) {
|
|
||||||
root.suppressShiftAnimation = true;
|
|
||||||
root.moveTrayItemInFullOrder(root.draggedIndex, root.dropTargetIndex);
|
|
||||||
Qt.callLater(() => root.suppressShiftAnimation = false);
|
|
||||||
}
|
|
||||||
|
|
||||||
dragHandler.longPressing = false;
|
dragHandler.longPressing = false;
|
||||||
dragHandler.dragging = false;
|
dragHandler.dragging = false;
|
||||||
dragHandler.dragAxisOffset = 0;
|
dragHandler.dragAxisOffset = 0;
|
||||||
root.draggedIndex = -1;
|
|
||||||
root.dropTargetIndex = -1;
|
|
||||||
|
|
||||||
if (wasDragging || mouse.button !== Qt.LeftButton)
|
if (wasDragging || mouse.button !== Qt.LeftButton)
|
||||||
return;
|
return;
|
||||||
@@ -501,8 +600,7 @@ BasePill {
|
|||||||
const distance = Math.abs(mouse.x - dragHandler.dragStartPos.x);
|
const distance = Math.abs(mouse.x - dragHandler.dragStartPos.x);
|
||||||
if (distance > 5) {
|
if (distance > 5) {
|
||||||
dragHandler.dragging = true;
|
dragHandler.dragging = true;
|
||||||
root.draggedIndex = root.reverseInlineHorizontal ? (root.mainBarItems.length - 1 - index) : index;
|
root.beginMainDrag(index, root.reverseInlineHorizontal);
|
||||||
root.dropTargetIndex = root.draggedIndex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!dragHandler.dragging)
|
if (!dragHandler.dragging)
|
||||||
@@ -510,13 +608,7 @@ BasePill {
|
|||||||
|
|
||||||
const axisOffset = mouse.x - dragHandler.dragStartPos.x;
|
const axisOffset = mouse.x - dragHandler.dragStartPos.x;
|
||||||
dragHandler.dragAxisOffset = axisOffset;
|
dragHandler.dragAxisOffset = axisOffset;
|
||||||
const itemSize = root.trayItemSize;
|
root.updateMainDrag(axisOffset, index, root.reverseInlineHorizontal);
|
||||||
const slotOffset = Math.round(axisOffset / itemSize);
|
|
||||||
const visualTargetIndex = Math.max(0, Math.min(root.mainBarItems.length - 1, index + slotOffset));
|
|
||||||
const newTargetIndex = root.reverseInlineHorizontal ? (root.mainBarItems.length - 1 - visualTargetIndex) : visualTargetIndex;
|
|
||||||
if (newTargetIndex !== root.dropTargetIndex) {
|
|
||||||
root.dropTargetIndex = newTargetIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: mouse => {
|
onClicked: mouse => {
|
||||||
@@ -706,22 +798,7 @@ BasePill {
|
|||||||
height: root.trayItemSize
|
height: root.trayItemSize
|
||||||
z: dragHandler.dragging ? 100 : 0
|
z: dragHandler.dragging ? 100 : 0
|
||||||
|
|
||||||
property real shiftOffset: {
|
property real shiftOffset: root.dragShiftOffset(index, root.draggedIndex, root.dropTargetIndex, root.trayItemSize)
|
||||||
if (root.draggedIndex < 0)
|
|
||||||
return 0;
|
|
||||||
if (index === root.draggedIndex)
|
|
||||||
return 0;
|
|
||||||
const dragIdx = root.draggedIndex;
|
|
||||||
const dropIdx = root.dropTargetIndex;
|
|
||||||
const shiftAmount = root.trayItemSize;
|
|
||||||
if (dropIdx < 0)
|
|
||||||
return 0;
|
|
||||||
if (dragIdx < dropIdx && index > dragIdx && index <= dropIdx)
|
|
||||||
return -shiftAmount;
|
|
||||||
if (dragIdx > dropIdx && index >= dropIdx && index < dragIdx)
|
|
||||||
return shiftAmount;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
transform: Translate {
|
transform: Translate {
|
||||||
y: shiftOffset
|
y: shiftOffset
|
||||||
@@ -821,19 +898,12 @@ BasePill {
|
|||||||
onReleased: mouse => {
|
onReleased: mouse => {
|
||||||
longPressTimer.stop();
|
longPressTimer.stop();
|
||||||
const wasDragging = dragHandler.dragging;
|
const wasDragging = dragHandler.dragging;
|
||||||
const didReorder = wasDragging && root.dropTargetIndex >= 0 && root.dropTargetIndex !== root.draggedIndex;
|
if (wasDragging)
|
||||||
|
root.finishMainDrag();
|
||||||
if (didReorder) {
|
|
||||||
root.suppressShiftAnimation = true;
|
|
||||||
root.moveTrayItemInFullOrder(root.draggedIndex, root.dropTargetIndex);
|
|
||||||
Qt.callLater(() => root.suppressShiftAnimation = false);
|
|
||||||
}
|
|
||||||
|
|
||||||
dragHandler.longPressing = false;
|
dragHandler.longPressing = false;
|
||||||
dragHandler.dragging = false;
|
dragHandler.dragging = false;
|
||||||
dragHandler.dragAxisOffset = 0;
|
dragHandler.dragAxisOffset = 0;
|
||||||
root.draggedIndex = -1;
|
|
||||||
root.dropTargetIndex = -1;
|
|
||||||
|
|
||||||
if (wasDragging || mouse.button !== Qt.LeftButton)
|
if (wasDragging || mouse.button !== Qt.LeftButton)
|
||||||
return;
|
return;
|
||||||
@@ -856,8 +926,7 @@ BasePill {
|
|||||||
const distance = Math.abs(mouse.y - dragHandler.dragStartPos.y);
|
const distance = Math.abs(mouse.y - dragHandler.dragStartPos.y);
|
||||||
if (distance > 5) {
|
if (distance > 5) {
|
||||||
dragHandler.dragging = true;
|
dragHandler.dragging = true;
|
||||||
root.draggedIndex = index;
|
root.beginMainDrag(index, false);
|
||||||
root.dropTargetIndex = root.draggedIndex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!dragHandler.dragging)
|
if (!dragHandler.dragging)
|
||||||
@@ -865,12 +934,7 @@ BasePill {
|
|||||||
|
|
||||||
const axisOffset = mouse.y - dragHandler.dragStartPos.y;
|
const axisOffset = mouse.y - dragHandler.dragStartPos.y;
|
||||||
dragHandler.dragAxisOffset = axisOffset;
|
dragHandler.dragAxisOffset = axisOffset;
|
||||||
const itemSize = root.trayItemSize;
|
root.updateMainDrag(axisOffset, index, false);
|
||||||
const slotOffset = Math.round(axisOffset / itemSize);
|
|
||||||
const newTargetIndex = Math.max(0, Math.min(root.mainBarItems.length - 1, index + slotOffset));
|
|
||||||
if (newTargetIndex !== root.dropTargetIndex) {
|
|
||||||
root.dropTargetIndex = newTargetIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: mouse => {
|
onClicked: mouse => {
|
||||||
@@ -1136,20 +1200,38 @@ BasePill {
|
|||||||
id: menuContainer
|
id: menuContainer
|
||||||
objectName: "overflowMenuContainer"
|
objectName: "overflowMenuContainer"
|
||||||
|
|
||||||
|
readonly property bool popupUsesVerticalLine: root.useSingleLineOverflowPopup && root.isVerticalOrientation
|
||||||
|
readonly property real popupPadding: Theme.spacingS + (popupUsesVerticalLine ? 3 : 0)
|
||||||
|
|
||||||
readonly property real rawWidth: {
|
readonly property real rawWidth: {
|
||||||
const itemCount = root.hiddenBarItems.length;
|
const itemCount = root.hiddenBarItems.length;
|
||||||
const cols = Math.min(5, itemCount);
|
if (itemCount === 0)
|
||||||
|
return 0;
|
||||||
|
if (popupUsesVerticalLine)
|
||||||
|
return root.trayItemSize + 4 + popupPadding * 2;
|
||||||
|
const cols = root.useSingleLineOverflowPopup ? itemCount : Math.min(5, itemCount);
|
||||||
const itemSize = root.trayItemSize + 4;
|
const itemSize = root.trayItemSize + 4;
|
||||||
const spacing = 2;
|
const spacing = 2;
|
||||||
return cols * itemSize + (cols - 1) * spacing + Theme.spacingS * 2;
|
const desiredWidth = cols * itemSize + (cols - 1) * spacing + popupPadding * 2;
|
||||||
|
if (!root.useSingleLineOverflowPopup)
|
||||||
|
return desiredWidth;
|
||||||
|
const maxWidth = Math.max(itemSize + popupPadding * 2, overflowMenu.maskWidth - 20);
|
||||||
|
return Math.min(desiredWidth, maxWidth);
|
||||||
}
|
}
|
||||||
readonly property real rawHeight: {
|
readonly property real rawHeight: {
|
||||||
const itemCount = root.hiddenBarItems.length;
|
const itemCount = root.hiddenBarItems.length;
|
||||||
const cols = Math.min(5, itemCount);
|
if (itemCount === 0)
|
||||||
const rows = Math.ceil(itemCount / cols);
|
return 0;
|
||||||
const itemSize = root.trayItemSize + 4;
|
const itemSize = root.trayItemSize + 4;
|
||||||
const spacing = 2;
|
const spacing = 2;
|
||||||
return rows * itemSize + (rows - 1) * spacing + Theme.spacingS * 2;
|
if (popupUsesVerticalLine) {
|
||||||
|
const desiredHeight = itemCount * itemSize + (itemCount - 1) * spacing + popupPadding * 2;
|
||||||
|
const maxHeight = Math.max(itemSize + popupPadding * 2, overflowMenu.maskHeight - 20);
|
||||||
|
return Math.min(desiredHeight, maxHeight);
|
||||||
|
}
|
||||||
|
const cols = root.useSingleLineOverflowPopup ? itemCount : Math.min(5, itemCount);
|
||||||
|
const rows = Math.ceil(itemCount / cols);
|
||||||
|
return rows * itemSize + (rows - 1) * spacing + popupPadding * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property real alignedWidth: Theme.px(rawWidth, overflowMenu.dpr)
|
readonly property real alignedWidth: Theme.px(rawWidth, overflowMenu.dpr)
|
||||||
@@ -1230,76 +1312,161 @@ BasePill {
|
|||||||
z: 100
|
z: 100
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid {
|
Flickable {
|
||||||
id: menuGrid
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
columns: Math.min(5, root.hiddenBarItems.length)
|
width: parent.width - menuContainer.popupPadding * 2
|
||||||
spacing: 2
|
height: parent.height - menuContainer.popupPadding * 2
|
||||||
rowSpacing: 2
|
contentWidth: menuGrid.implicitWidth
|
||||||
|
contentHeight: menuGrid.implicitHeight
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
clip: true
|
||||||
|
interactive: root.useSingleLineOverflowPopup && (menuContainer.popupUsesVerticalLine ? contentHeight > height : contentWidth > width)
|
||||||
|
|
||||||
Repeater {
|
Grid {
|
||||||
model: root.hiddenBarItems
|
id: menuGrid
|
||||||
|
anchors.verticalCenter: menuContainer.popupUsesVerticalLine ? undefined : parent.verticalCenter
|
||||||
|
anchors.horizontalCenter: menuContainer.popupUsesVerticalLine ? parent.horizontalCenter : undefined
|
||||||
|
columns: menuContainer.popupUsesVerticalLine ? 1 : (root.useSingleLineOverflowPopup ? root.hiddenBarItems.length : Math.min(5, root.hiddenBarItems.length))
|
||||||
|
spacing: 2
|
||||||
|
rowSpacing: 2
|
||||||
|
|
||||||
delegate: Rectangle {
|
Repeater {
|
||||||
property var trayItem: modelData
|
model: root.hiddenBarItems
|
||||||
property string iconSource: root.trayIconSourceFor(trayItem)
|
|
||||||
|
|
||||||
width: root.trayItemSize + 4
|
delegate: Rectangle {
|
||||||
height: root.trayItemSize + 4
|
id: overflowItemRoot
|
||||||
radius: Theme.cornerRadius
|
property var trayItem: modelData
|
||||||
color: itemArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : Theme.withAlpha(Theme.surfaceContainer, 0)
|
property string itemKey: root.getTrayItemKey(trayItem)
|
||||||
|
property string iconSource: root.trayIconSourceFor(trayItem)
|
||||||
|
|
||||||
IconImage {
|
width: root.trayItemSize + 4
|
||||||
id: menuIconImg
|
height: root.trayItemSize + 4
|
||||||
anchors.centerIn: parent
|
z: popupDragHandler.dragging ? 100 : 0
|
||||||
width: Theme.barIconSize(root.barThickness, undefined, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale)
|
radius: Theme.cornerRadius
|
||||||
height: Theme.barIconSize(root.barThickness, undefined, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale)
|
color: itemArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : Theme.withAlpha(Theme.surfaceContainer, 0)
|
||||||
source: parent.iconSource
|
border.width: popupDragHandler.dragging ? 2 : 0
|
||||||
asynchronous: true
|
border.color: Theme.primary
|
||||||
smooth: true
|
opacity: popupDragHandler.dragging ? 0.8 : 1.0
|
||||||
mipmap: true
|
|
||||||
visible: status === Image.Ready
|
|
||||||
layer.enabled: root.trayIconTintEnabled
|
|
||||||
layer.effect: MultiEffect {
|
|
||||||
saturation: root.trayIconSaturation
|
|
||||||
colorization: root.trayIconColorization
|
|
||||||
colorizationColor: root.trayIconTintColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
property real shiftOffset: root.dragShiftOffset(index, root.popupDraggedIndex, root.popupDropTargetIndex, root.trayItemSize + 6)
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: !menuIconImg.visible
|
|
||||||
text: {
|
|
||||||
const itemId = trayItem?.id || "";
|
|
||||||
if (!itemId)
|
|
||||||
return "?";
|
|
||||||
return itemId.charAt(0).toUpperCase();
|
|
||||||
}
|
|
||||||
font.pixelSize: 10
|
|
||||||
color: Theme.widgetTextColor
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
transform: Translate {
|
||||||
id: itemArea
|
x: !menuContainer.popupUsesVerticalLine ? overflowItemRoot.shiftOffset + (popupDragHandler.dragging ? popupDragHandler.dragAxisOffset : 0) : 0
|
||||||
anchors.fill: parent
|
y: menuContainer.popupUsesVerticalLine ? overflowItemRoot.shiftOffset + (popupDragHandler.dragging ? popupDragHandler.dragAxisOffset : 0) : 0
|
||||||
hoverEnabled: true
|
Behavior on x {
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
enabled: !root.suppressShiftAnimation && !menuContainer.popupUsesVerticalLine
|
||||||
cursorShape: Qt.PointingHandCursor
|
NumberAnimation {
|
||||||
onClicked: mouse => {
|
duration: 150
|
||||||
if (!trayItem)
|
easing.type: Easing.OutCubic
|
||||||
return;
|
}
|
||||||
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
|
|
||||||
trayItem.activate();
|
|
||||||
root.menuOpen = false;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!trayItem.hasMenu) {
|
Behavior on y {
|
||||||
const gp = itemArea.mapToGlobal(mouse.x, mouse.y);
|
enabled: !root.suppressShiftAnimation && menuContainer.popupUsesVerticalLine
|
||||||
root.callContextMenuFallback(trayItem.id, Math.round(gp.x), Math.round(gp.y));
|
NumberAnimation {
|
||||||
return;
|
duration: 150
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: popupDragHandler
|
||||||
|
anchors.fill: parent
|
||||||
|
property bool dragging: false
|
||||||
|
property point dragStartPos: Qt.point(0, 0)
|
||||||
|
property real dragAxisOffset: 0
|
||||||
|
property bool longPressing: false
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: popupLongPressTimer
|
||||||
|
interval: 400
|
||||||
|
repeat: false
|
||||||
|
onTriggered: popupDragHandler.longPressing = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
id: menuIconImg
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: Theme.barIconSize(root.barThickness, undefined, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale)
|
||||||
|
height: Theme.barIconSize(root.barThickness, undefined, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale)
|
||||||
|
source: parent.iconSource
|
||||||
|
asynchronous: true
|
||||||
|
smooth: true
|
||||||
|
mipmap: true
|
||||||
|
visible: status === Image.Ready
|
||||||
|
layer.enabled: root.trayIconTintEnabled
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
saturation: root.trayIconSaturation
|
||||||
|
colorization: root.trayIconColorization
|
||||||
|
colorizationColor: root.trayIconTintColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: !menuIconImg.visible
|
||||||
|
text: {
|
||||||
|
const itemId = trayItem?.id || "";
|
||||||
|
if (!itemId)
|
||||||
|
return "?";
|
||||||
|
return itemId.charAt(0).toUpperCase();
|
||||||
|
}
|
||||||
|
font.pixelSize: 10
|
||||||
|
color: Theme.widgetTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: itemArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
cursorShape: popupDragHandler.longPressing ? Qt.DragMoveCursor : Qt.PointingHandCursor
|
||||||
|
onPressed: mouse => {
|
||||||
|
if (mouse.button === Qt.LeftButton) {
|
||||||
|
popupDragHandler.dragStartPos = Qt.point(mouse.x, mouse.y);
|
||||||
|
popupLongPressTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onReleased: mouse => {
|
||||||
|
popupLongPressTimer.stop();
|
||||||
|
const wasDragging = popupDragHandler.dragging;
|
||||||
|
if (wasDragging)
|
||||||
|
root.finishPopupDrag();
|
||||||
|
|
||||||
|
popupDragHandler.longPressing = false;
|
||||||
|
popupDragHandler.dragging = false;
|
||||||
|
popupDragHandler.dragAxisOffset = 0;
|
||||||
|
}
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
const axisDelta = menuContainer.popupUsesVerticalLine ? (mouse.y - popupDragHandler.dragStartPos.y) : (mouse.x - popupDragHandler.dragStartPos.x);
|
||||||
|
if (popupDragHandler.longPressing && !popupDragHandler.dragging && Math.abs(axisDelta) > 5) {
|
||||||
|
popupDragHandler.dragging = true;
|
||||||
|
root.beginPopupDrag(index);
|
||||||
|
}
|
||||||
|
if (!popupDragHandler.dragging)
|
||||||
|
return;
|
||||||
|
|
||||||
|
popupDragHandler.dragAxisOffset = axisDelta;
|
||||||
|
root.updatePopupDrag(axisDelta, index);
|
||||||
|
}
|
||||||
|
onClicked: mouse => {
|
||||||
|
if (popupDragHandler.dragging)
|
||||||
|
return;
|
||||||
|
if (!trayItem)
|
||||||
|
return;
|
||||||
|
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
|
||||||
|
trayItem.activate();
|
||||||
|
root.menuOpen = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!trayItem.hasMenu) {
|
||||||
|
const gp = itemArea.mapToGlobal(mouse.x, mouse.y);
|
||||||
|
root.callContextMenuFallback(trayItem.id, Math.round(gp.x), Math.round(gp.y));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
root.showForTrayItem(trayItem, menuContainer, parentScreen, root.isAtBottom, root.isVerticalOrientation, root.axis);
|
||||||
}
|
}
|
||||||
root.showForTrayItem(trayItem, menuContainer, parentScreen, root.isAtBottom, root.isVerticalOrientation, root.axis);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1695,7 +1862,12 @@ BasePill {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: Theme.spacingS
|
anchors.leftMargin: Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: menuRoot.trayItem?.id || "Unknown"
|
text: {
|
||||||
|
const itemId = menuRoot.trayItem?.id || "Unknown";
|
||||||
|
if (root.isAutoOverflowTrayItem(menuRoot.trayItem))
|
||||||
|
return itemId + " · " + I18n.tr("Keep in Bar");
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceTextMedium
|
color: Theme.surfaceTextMedium
|
||||||
elide: Text.ElideMiddle
|
elide: Text.ElideMiddle
|
||||||
@@ -1706,7 +1878,11 @@ BasePill {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: Theme.spacingS
|
anchors.rightMargin: Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
name: SessionData.isHiddenTrayId(root.getTrayItemKey(menuRoot.trayItem)) ? "visibility" : "visibility_off"
|
name: {
|
||||||
|
if (root.isAutoOverflowTrayItem(menuRoot.trayItem))
|
||||||
|
return "push_pin";
|
||||||
|
return root.isManualHiddenTrayItem(menuRoot.trayItem) ? "visibility" : "visibility_off";
|
||||||
|
}
|
||||||
size: 16
|
size: 16
|
||||||
color: Theme.widgetTextColor
|
color: Theme.widgetTextColor
|
||||||
}
|
}
|
||||||
@@ -1720,7 +1896,9 @@ BasePill {
|
|||||||
const itemKey = root.getTrayItemKey(menuRoot.trayItem);
|
const itemKey = root.getTrayItemKey(menuRoot.trayItem);
|
||||||
if (!itemKey)
|
if (!itemKey)
|
||||||
return;
|
return;
|
||||||
if (SessionData.isHiddenTrayId(itemKey)) {
|
if (root.isAutoOverflowTrayItem(menuRoot.trayItem)) {
|
||||||
|
root.promoteTrayItemToBar(menuRoot.trayItem);
|
||||||
|
} else if (root.isManualHiddenTrayItem(menuRoot.trayItem)) {
|
||||||
SessionData.showTrayId(itemKey);
|
SessionData.showTrayId(itemKey);
|
||||||
} else {
|
} else {
|
||||||
SessionData.hideTrayId(itemKey);
|
SessionData.hideTrayId(itemKey);
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ Item {
|
|||||||
"id": widget.id,
|
"id": widget.id,
|
||||||
"enabled": widget.enabled
|
"enabled": widget.enabled
|
||||||
};
|
};
|
||||||
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowSize", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "keyboardLayoutNameShowIcon", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "showIdleInhibitorIcon", "showDoNotDisturbIcon", "controlCenterGroupOrder", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge", "trayUseInlineExpansion", "hideWhenIdle"];
|
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowSize", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "keyboardLayoutNameShowIcon", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "showIdleInhibitorIcon", "showDoNotDisturbIcon", "controlCenterGroupOrder", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge", "trayUseInlineExpansion", "trayPopupSingleLine", "trayAutoOverflow", "trayMaxVisibleItems", "hideWhenIdle"];
|
||||||
for (var i = 0; i < keys.length; i++) {
|
for (var i = 0; i < keys.length; i++) {
|
||||||
if (widget[keys[i]] !== undefined)
|
if (widget[keys[i]] !== undefined)
|
||||||
result[keys[i]] = widget[keys[i]];
|
result[keys[i]] = widget[keys[i]];
|
||||||
@@ -803,6 +803,12 @@ Item {
|
|||||||
item.barShowOverflowBadge = widget.barShowOverflowBadge;
|
item.barShowOverflowBadge = widget.barShowOverflowBadge;
|
||||||
if (widget.trayUseInlineExpansion !== undefined)
|
if (widget.trayUseInlineExpansion !== undefined)
|
||||||
item.trayUseInlineExpansion = widget.trayUseInlineExpansion;
|
item.trayUseInlineExpansion = widget.trayUseInlineExpansion;
|
||||||
|
if (widget.trayPopupSingleLine !== undefined)
|
||||||
|
item.trayPopupSingleLine = widget.trayPopupSingleLine;
|
||||||
|
if (widget.trayAutoOverflow !== undefined)
|
||||||
|
item.trayAutoOverflow = widget.trayAutoOverflow;
|
||||||
|
if (widget.trayMaxVisibleItems !== undefined)
|
||||||
|
item.trayMaxVisibleItems = widget.trayMaxVisibleItems;
|
||||||
if (widget.hideWhenIdle !== undefined)
|
if (widget.hideWhenIdle !== undefined)
|
||||||
item.hideWhenIdle = widget.hideWhenIdle;
|
item.hideWhenIdle = widget.hideWhenIdle;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Column {
|
|||||||
"id": widget.id,
|
"id": widget.id,
|
||||||
"enabled": widget.enabled
|
"enabled": widget.enabled
|
||||||
};
|
};
|
||||||
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowSize", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "keyboardLayoutNameShowIcon", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "showIdleInhibitorIcon", "showDoNotDisturbIcon", "controlCenterGroupOrder", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge", "trayUseInlineExpansion"];
|
var keys = ["size", "selectedGpuIndex", "pciId", "mountPath", "diskUsageMode", "minimumWidth", "showSwap", "showInGb", "mediaSize", "clockCompactMode", "focusedWindowSize", "focusedWindowCompactMode", "runningAppsCompactMode", "keyboardLayoutNameCompactMode", "keyboardLayoutNameShowIcon", "runningAppsGroupByApp", "runningAppsCurrentWorkspace", "runningAppsCurrentMonitor", "showNetworkIcon", "showBluetoothIcon", "showAudioIcon", "showAudioPercent", "showVpnIcon", "showBrightnessIcon", "showBrightnessPercent", "showMicIcon", "showMicPercent", "showBatteryIcon", "showPrinterIcon", "showScreenSharingIcon", "showIdleInhibitorIcon", "showDoNotDisturbIcon", "controlCenterGroupOrder", "barMaxVisibleApps", "barMaxVisibleRunningApps", "barShowOverflowBadge", "trayUseInlineExpansion", "trayPopupSingleLine", "trayAutoOverflow", "trayMaxVisibleItems"];
|
||||||
for (var i = 0; i < keys.length; i++) {
|
for (var i = 0; i < keys.length; i++) {
|
||||||
if (widget[keys[i]] !== undefined)
|
if (widget[keys[i]] !== undefined)
|
||||||
result[keys[i]] = widget[keys[i]];
|
result[keys[i]] = widget[keys[i]];
|
||||||
@@ -1126,6 +1126,188 @@ Column {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 32
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: trayPopupLineArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
opacity: (trayContextMenu.currentWidgetData?.trayUseInlineExpansion ?? false) ? 0.55 : 1
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "view_week"
|
||||||
|
size: 16
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Single-Line Popup")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
id: trayPopupLineToggle
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: 40
|
||||||
|
height: 20
|
||||||
|
checked: trayContextMenu.currentWidgetData?.trayPopupSingleLine ?? SettingsData.trayPopupSingleLine
|
||||||
|
enabled: !(trayContextMenu.currentWidgetData?.trayUseInlineExpansion ?? false)
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: trayPopupLineArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: (trayContextMenu.currentWidgetData?.trayUseInlineExpansion ?? false) ? Qt.ArrowCursor : Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if (trayContextMenu.currentWidgetData?.trayUseInlineExpansion ?? false)
|
||||||
|
return;
|
||||||
|
const newValue = !(trayContextMenu.currentWidgetData?.trayPopupSingleLine ?? SettingsData.trayPopupSingleLine);
|
||||||
|
root.overflowSettingChanged(trayContextMenu.sectionId, trayContextMenu.widgetIndex, "trayPopupSingleLine", newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 32
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: trayAutoOverflowArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "responsive_layout"
|
||||||
|
size: 16
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Auto Overflow")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
id: trayAutoOverflowToggle
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: 40
|
||||||
|
height: 20
|
||||||
|
checked: trayContextMenu.currentWidgetData?.trayAutoOverflow ?? SettingsData.trayAutoOverflow
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: trayAutoOverflowArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
const newValue = !(trayContextMenu.currentWidgetData?.trayAutoOverflow ?? SettingsData.trayAutoOverflow);
|
||||||
|
root.overflowSettingChanged(trayContextMenu.sectionId, trayContextMenu.widgetIndex, "trayAutoOverflow", newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 36
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: trayMaxVisibleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
opacity: (trayContextMenu.currentWidgetData?.trayAutoOverflow ?? SettingsData.trayAutoOverflow) ? 1 : 0.55
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "low_priority"
|
||||||
|
size: 16
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Max Visible")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Normal
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: {
|
||||||
|
const value = trayContextMenu.currentWidgetData?.trayMaxVisibleItems ?? SettingsData.trayMaxVisibleItems;
|
||||||
|
return value > 0 ? String(value) : I18n.tr("Auto");
|
||||||
|
}
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceTextMedium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.spacingXS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
buttonSize: 28
|
||||||
|
iconName: "remove"
|
||||||
|
iconSize: 16
|
||||||
|
iconColor: Theme.surfaceText
|
||||||
|
enabled: trayContextMenu.currentWidgetData?.trayAutoOverflow ?? SettingsData.trayAutoOverflow
|
||||||
|
onClicked: {
|
||||||
|
const current = trayContextMenu.currentWidgetData?.trayMaxVisibleItems ?? SettingsData.trayMaxVisibleItems;
|
||||||
|
root.overflowSettingChanged(trayContextMenu.sectionId, trayContextMenu.widgetIndex, "trayMaxVisibleItems", Math.max(0, current - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
buttonSize: 28
|
||||||
|
iconName: "add"
|
||||||
|
iconSize: 16
|
||||||
|
iconColor: Theme.surfaceText
|
||||||
|
enabled: trayContextMenu.currentWidgetData?.trayAutoOverflow ?? SettingsData.trayAutoOverflow
|
||||||
|
onClicked: {
|
||||||
|
const current = trayContextMenu.currentWidgetData?.trayMaxVisibleItems ?? SettingsData.trayMaxVisibleItems;
|
||||||
|
root.overflowSettingChanged(trayContextMenu.sectionId, trayContextMenu.widgetIndex, "trayMaxVisibleItems", Math.min(20, current + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: trayMaxVisibleArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user