mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-07 05:55:37 -05:00
feat: Implement drag & drop topbar widget sections in settings
This commit is contained in:
159
Common/Prefs.qml
159
Common/Prefs.qml
@@ -24,14 +24,43 @@ Singleton {
|
|||||||
property string profileImage: ""
|
property string profileImage: ""
|
||||||
property string weatherLocation: "New York, NY"
|
property string weatherLocation: "New York, NY"
|
||||||
property string weatherCoordinates: "40.7128,-74.0060"
|
property string weatherCoordinates: "40.7128,-74.0060"
|
||||||
|
property bool showLauncherButton: true
|
||||||
|
property bool showWorkspaceSwitcher: true
|
||||||
property bool showFocusedWindow: true
|
property bool showFocusedWindow: true
|
||||||
property bool showWeather: true
|
property bool showWeather: true
|
||||||
property bool showMusic: true
|
property bool showMusic: true
|
||||||
property bool showClipboard: true
|
property bool showClipboard: true
|
||||||
property bool showSystemResources: true
|
property bool showSystemResources: true
|
||||||
property bool showSystemTray: true
|
property bool showSystemTray: true
|
||||||
|
property bool showClock: true
|
||||||
|
property bool showNotificationButton: true
|
||||||
|
property bool showBattery: true
|
||||||
|
property bool showControlCenterButton: true
|
||||||
property bool showWorkspaceIndex: false
|
property bool showWorkspaceIndex: false
|
||||||
property bool showWorkspacePadding: false
|
property bool showWorkspacePadding: false
|
||||||
|
property var topBarLeftWidgets: ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
||||||
|
property var topBarCenterWidgets: ["clock", "music", "weather"]
|
||||||
|
property var topBarRightWidgets: ["systemTray", "clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"]
|
||||||
|
|
||||||
|
// Reactive ListModel properties for TopBar
|
||||||
|
property alias topBarLeftWidgetsModel: leftWidgetsModel
|
||||||
|
property alias topBarCenterWidgetsModel: centerWidgetsModel
|
||||||
|
property alias topBarRightWidgetsModel: rightWidgetsModel
|
||||||
|
|
||||||
|
// Signal to force immediate TopBar layout refresh
|
||||||
|
signal forceTopBarLayoutRefresh()
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: leftWidgetsModel
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: centerWidgetsModel
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: rightWidgetsModel
|
||||||
|
}
|
||||||
property string appLauncherViewMode: "list"
|
property string appLauncherViewMode: "list"
|
||||||
property string spotlightModalViewMode: "list"
|
property string spotlightModalViewMode: "list"
|
||||||
property string networkPreference: "auto"
|
property string networkPreference: "auto"
|
||||||
@@ -85,7 +114,14 @@ Singleton {
|
|||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
loadSettings();
|
loadSettings();
|
||||||
fontCheckTimer.start()
|
fontCheckTimer.start();
|
||||||
|
initializeListModels();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeListModels() {
|
||||||
|
updateListModel(leftWidgetsModel, topBarLeftWidgets);
|
||||||
|
updateListModel(centerWidgetsModel, topBarCenterWidgets);
|
||||||
|
updateListModel(rightWidgetsModel, topBarRightWidgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
@@ -109,14 +145,38 @@ Singleton {
|
|||||||
profileImage = settings.profileImage !== undefined ? settings.profileImage : "";
|
profileImage = settings.profileImage !== undefined ? settings.profileImage : "";
|
||||||
weatherLocation = settings.weatherLocation !== undefined ? settings.weatherLocation : "New York, NY";
|
weatherLocation = settings.weatherLocation !== undefined ? settings.weatherLocation : "New York, NY";
|
||||||
weatherCoordinates = settings.weatherCoordinates !== undefined ? settings.weatherCoordinates : "40.7128,-74.0060";
|
weatherCoordinates = settings.weatherCoordinates !== undefined ? settings.weatherCoordinates : "40.7128,-74.0060";
|
||||||
|
showLauncherButton = settings.showLauncherButton !== undefined ? settings.showLauncherButton : true;
|
||||||
|
showWorkspaceSwitcher = settings.showWorkspaceSwitcher !== undefined ? settings.showWorkspaceSwitcher : true;
|
||||||
showFocusedWindow = settings.showFocusedWindow !== undefined ? settings.showFocusedWindow : true;
|
showFocusedWindow = settings.showFocusedWindow !== undefined ? settings.showFocusedWindow : true;
|
||||||
showWeather = settings.showWeather !== undefined ? settings.showWeather : true;
|
showWeather = settings.showWeather !== undefined ? settings.showWeather : true;
|
||||||
showMusic = settings.showMusic !== undefined ? settings.showMusic : true;
|
showMusic = settings.showMusic !== undefined ? settings.showMusic : true;
|
||||||
showClipboard = settings.showClipboard !== undefined ? settings.showClipboard : true;
|
showClipboard = settings.showClipboard !== undefined ? settings.showClipboard : true;
|
||||||
showSystemResources = settings.showSystemResources !== undefined ? settings.showSystemResources : true;
|
showSystemResources = settings.showSystemResources !== undefined ? settings.showSystemResources : true;
|
||||||
showSystemTray = settings.showSystemTray !== undefined ? settings.showSystemTray : true;
|
showSystemTray = settings.showSystemTray !== undefined ? settings.showSystemTray : true;
|
||||||
|
showClock = settings.showClock !== undefined ? settings.showClock : true;
|
||||||
|
showNotificationButton = settings.showNotificationButton !== undefined ? settings.showNotificationButton : true;
|
||||||
|
showBattery = settings.showBattery !== undefined ? settings.showBattery : true;
|
||||||
|
showControlCenterButton = settings.showControlCenterButton !== undefined ? settings.showControlCenterButton : true;
|
||||||
showWorkspaceIndex = settings.showWorkspaceIndex !== undefined ? settings.showWorkspaceIndex : false;
|
showWorkspaceIndex = settings.showWorkspaceIndex !== undefined ? settings.showWorkspaceIndex : false;
|
||||||
showWorkspacePadding = settings.showWorkspacePadding !== undefined ? settings.showWorkspacePadding : false;
|
showWorkspacePadding = settings.showWorkspacePadding !== undefined ? settings.showWorkspacePadding : false;
|
||||||
|
if (settings.topBarWidgetOrder) {
|
||||||
|
// Migrate from old single list to new three-list system
|
||||||
|
topBarLeftWidgets = settings.topBarWidgetOrder.filter(w => ["launcherButton", "workspaceSwitcher", "focusedWindow"].includes(w));
|
||||||
|
topBarCenterWidgets = settings.topBarWidgetOrder.filter(w => ["clock", "music", "weather"].includes(w));
|
||||||
|
topBarRightWidgets = settings.topBarWidgetOrder.filter(w => ["systemTray", "clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"].includes(w));
|
||||||
|
} else {
|
||||||
|
var leftWidgets = settings.topBarLeftWidgets !== undefined ? settings.topBarLeftWidgets : ["launcherButton", "workspaceSwitcher", "focusedWindow"];
|
||||||
|
var centerWidgets = settings.topBarCenterWidgets !== undefined ? settings.topBarCenterWidgets : ["clock", "music", "weather"];
|
||||||
|
var rightWidgets = settings.topBarRightWidgets !== undefined ? settings.topBarRightWidgets : ["systemTray", "clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"];
|
||||||
|
|
||||||
|
topBarLeftWidgets = leftWidgets;
|
||||||
|
topBarCenterWidgets = centerWidgets;
|
||||||
|
topBarRightWidgets = rightWidgets;
|
||||||
|
|
||||||
|
updateListModel(leftWidgetsModel, leftWidgets);
|
||||||
|
updateListModel(centerWidgetsModel, centerWidgets);
|
||||||
|
updateListModel(rightWidgetsModel, rightWidgets);
|
||||||
|
}
|
||||||
appLauncherViewMode = settings.appLauncherViewMode !== undefined ? settings.appLauncherViewMode : "list";
|
appLauncherViewMode = settings.appLauncherViewMode !== undefined ? settings.appLauncherViewMode : "list";
|
||||||
spotlightModalViewMode = settings.spotlightModalViewMode !== undefined ? settings.spotlightModalViewMode : "list";
|
spotlightModalViewMode = settings.spotlightModalViewMode !== undefined ? settings.spotlightModalViewMode : "list";
|
||||||
networkPreference = settings.networkPreference !== undefined ? settings.networkPreference : "auto";
|
networkPreference = settings.networkPreference !== undefined ? settings.networkPreference : "auto";
|
||||||
@@ -163,14 +223,23 @@ Singleton {
|
|||||||
"profileImage": profileImage,
|
"profileImage": profileImage,
|
||||||
"weatherLocation": weatherLocation,
|
"weatherLocation": weatherLocation,
|
||||||
"weatherCoordinates": weatherCoordinates,
|
"weatherCoordinates": weatherCoordinates,
|
||||||
|
"showLauncherButton": showLauncherButton,
|
||||||
|
"showWorkspaceSwitcher": showWorkspaceSwitcher,
|
||||||
"showFocusedWindow": showFocusedWindow,
|
"showFocusedWindow": showFocusedWindow,
|
||||||
"showWeather": showWeather,
|
"showWeather": showWeather,
|
||||||
"showMusic": showMusic,
|
"showMusic": showMusic,
|
||||||
"showClipboard": showClipboard,
|
"showClipboard": showClipboard,
|
||||||
"showSystemResources": showSystemResources,
|
"showSystemResources": showSystemResources,
|
||||||
"showSystemTray": showSystemTray,
|
"showSystemTray": showSystemTray,
|
||||||
|
"showClock": showClock,
|
||||||
|
"showNotificationButton": showNotificationButton,
|
||||||
|
"showBattery": showBattery,
|
||||||
|
"showControlCenterButton": showControlCenterButton,
|
||||||
"showWorkspaceIndex": showWorkspaceIndex,
|
"showWorkspaceIndex": showWorkspaceIndex,
|
||||||
"showWorkspacePadding": showWorkspacePadding,
|
"showWorkspacePadding": showWorkspacePadding,
|
||||||
|
"topBarLeftWidgets": topBarLeftWidgets,
|
||||||
|
"topBarCenterWidgets": topBarCenterWidgets,
|
||||||
|
"topBarRightWidgets": topBarRightWidgets,
|
||||||
"appLauncherViewMode": appLauncherViewMode,
|
"appLauncherViewMode": appLauncherViewMode,
|
||||||
"spotlightModalViewMode": spotlightModalViewMode,
|
"spotlightModalViewMode": spotlightModalViewMode,
|
||||||
"networkPreference": networkPreference,
|
"networkPreference": networkPreference,
|
||||||
@@ -340,6 +409,16 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Widget visibility setters
|
// Widget visibility setters
|
||||||
|
function setShowLauncherButton(enabled) {
|
||||||
|
showLauncherButton = enabled;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setShowWorkspaceSwitcher(enabled) {
|
||||||
|
showWorkspaceSwitcher = enabled;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
function setShowFocusedWindow(enabled) {
|
function setShowFocusedWindow(enabled) {
|
||||||
showFocusedWindow = enabled;
|
showFocusedWindow = enabled;
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@@ -370,6 +449,84 @@ Singleton {
|
|||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setShowClock(enabled) {
|
||||||
|
showClock = enabled;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setShowNotificationButton(enabled) {
|
||||||
|
showNotificationButton = enabled;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setShowBattery(enabled) {
|
||||||
|
showBattery = enabled;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setShowControlCenterButton(enabled) {
|
||||||
|
showControlCenterButton = enabled;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTopBarWidgetOrder(order) {
|
||||||
|
topBarWidgetOrder = order;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTopBarLeftWidgets(order) {
|
||||||
|
topBarLeftWidgets = order;
|
||||||
|
updateListModel(leftWidgetsModel, order);
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTopBarCenterWidgets(order) {
|
||||||
|
topBarCenterWidgets = order;
|
||||||
|
updateListModel(centerWidgetsModel, order);
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTopBarRightWidgets(order) {
|
||||||
|
topBarRightWidgets = order;
|
||||||
|
updateListModel(rightWidgetsModel, order);
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateListModel(listModel, order) {
|
||||||
|
listModel.clear();
|
||||||
|
for (var i = 0; i < order.length; i++) {
|
||||||
|
listModel.append({"widgetId": order[i]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetTopBarWidgetsToDefault() {
|
||||||
|
var defaultLeft = ["launcherButton", "workspaceSwitcher", "focusedWindow"];
|
||||||
|
var defaultCenter = ["clock", "music", "weather"];
|
||||||
|
var defaultRight = ["systemTray", "clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"];
|
||||||
|
|
||||||
|
topBarLeftWidgets = defaultLeft;
|
||||||
|
topBarCenterWidgets = defaultCenter;
|
||||||
|
topBarRightWidgets = defaultRight;
|
||||||
|
|
||||||
|
updateListModel(leftWidgetsModel, defaultLeft);
|
||||||
|
updateListModel(centerWidgetsModel, defaultCenter);
|
||||||
|
updateListModel(rightWidgetsModel, defaultRight);
|
||||||
|
|
||||||
|
showLauncherButton = true;
|
||||||
|
showWorkspaceSwitcher = true;
|
||||||
|
showFocusedWindow = true;
|
||||||
|
showWeather = true;
|
||||||
|
showMusic = true;
|
||||||
|
showClipboard = true;
|
||||||
|
showSystemResources = true;
|
||||||
|
showSystemTray = true;
|
||||||
|
showClock = true;
|
||||||
|
showNotificationButton = true;
|
||||||
|
showBattery = true;
|
||||||
|
showControlCenterButton = true;
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
// View mode setters
|
// View mode setters
|
||||||
function setAppLauncherViewMode(mode) {
|
function setAppLauncherViewMode(mode) {
|
||||||
appLauncherViewMode = mode;
|
appLauncherViewMode = mode;
|
||||||
|
|||||||
@@ -10,6 +10,249 @@ ScrollView {
|
|||||||
contentHeight: column.implicitHeight + Theme.spacingXL
|
contentHeight: column.implicitHeight + Theme.spacingXL
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
property var baseWidgetDefinitions: [
|
||||||
|
{
|
||||||
|
id: "launcherButton",
|
||||||
|
text: "App Launcher",
|
||||||
|
description: "Quick access to application launcher",
|
||||||
|
icon: "apps",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "workspaceSwitcher",
|
||||||
|
text: "Workspace Switcher",
|
||||||
|
description: "Shows current workspace and allows switching",
|
||||||
|
icon: "view_module",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "focusedWindow",
|
||||||
|
text: "Focused Window",
|
||||||
|
description: "Display currently focused application title",
|
||||||
|
icon: "window",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "clock",
|
||||||
|
text: "Clock",
|
||||||
|
description: "Current time and date display",
|
||||||
|
icon: "schedule",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "weather",
|
||||||
|
text: "Weather Widget",
|
||||||
|
description: "Current weather conditions and temperature",
|
||||||
|
icon: "wb_sunny",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "music",
|
||||||
|
text: "Media Controls",
|
||||||
|
description: "Control currently playing media",
|
||||||
|
icon: "music_note",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "clipboard",
|
||||||
|
text: "Clipboard Manager",
|
||||||
|
description: "Access clipboard history",
|
||||||
|
icon: "content_paste",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "systemResources",
|
||||||
|
text: "System Resources",
|
||||||
|
description: "CPU and memory usage indicators",
|
||||||
|
icon: "memory",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "systemTray",
|
||||||
|
text: "System Tray",
|
||||||
|
description: "System notification area icons",
|
||||||
|
icon: "notifications",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "controlCenterButton",
|
||||||
|
text: "Control Center",
|
||||||
|
description: "Access to system controls and settings",
|
||||||
|
icon: "settings",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "notificationButton",
|
||||||
|
text: "Notification Center",
|
||||||
|
description: "Access to notifications and do not disturb",
|
||||||
|
icon: "notifications",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "battery",
|
||||||
|
text: "Battery",
|
||||||
|
description: "Battery level and power management",
|
||||||
|
icon: "battery_std",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "spacer",
|
||||||
|
text: "Spacer",
|
||||||
|
description: "Empty space to separate widgets",
|
||||||
|
icon: "more_horiz",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "separator",
|
||||||
|
text: "Separator",
|
||||||
|
description: "Visual divider between widgets",
|
||||||
|
icon: "remove",
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// Default widget configurations for each section
|
||||||
|
property var defaultLeftWidgets: ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
||||||
|
property var defaultCenterWidgets: ["music", "clock", "weather"]
|
||||||
|
property var defaultRightWidgets: ["clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"]
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
// Initialize sections with defaults if they're empty
|
||||||
|
if (!Prefs.topBarLeftWidgets || Prefs.topBarLeftWidgets.length === 0) {
|
||||||
|
Prefs.setTopBarLeftWidgets(defaultLeftWidgets)
|
||||||
|
}
|
||||||
|
if (!Prefs.topBarCenterWidgets || Prefs.topBarCenterWidgets.length === 0) {
|
||||||
|
Prefs.setTopBarCenterWidgets(defaultCenterWidgets)
|
||||||
|
}
|
||||||
|
if (!Prefs.topBarRightWidgets || Prefs.topBarRightWidgets.length === 0) {
|
||||||
|
Prefs.setTopBarRightWidgets(defaultRightWidgets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addWidgetToSection(widgetId, targetSection) {
|
||||||
|
var leftWidgets = Prefs.topBarLeftWidgets.slice()
|
||||||
|
var centerWidgets = Prefs.topBarCenterWidgets.slice()
|
||||||
|
var rightWidgets = Prefs.topBarRightWidgets.slice()
|
||||||
|
|
||||||
|
if (targetSection === "left") {
|
||||||
|
leftWidgets.push(widgetId)
|
||||||
|
Prefs.setTopBarLeftWidgets(leftWidgets)
|
||||||
|
} else if (targetSection === "center") {
|
||||||
|
centerWidgets.push(widgetId)
|
||||||
|
Prefs.setTopBarCenterWidgets(centerWidgets)
|
||||||
|
} else if (targetSection === "right") {
|
||||||
|
rightWidgets.push(widgetId)
|
||||||
|
Prefs.setTopBarRightWidgets(rightWidgets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLastWidgetFromSection(sectionId) {
|
||||||
|
var leftWidgets = Prefs.topBarLeftWidgets.slice()
|
||||||
|
var centerWidgets = Prefs.topBarCenterWidgets.slice()
|
||||||
|
var rightWidgets = Prefs.topBarRightWidgets.slice()
|
||||||
|
|
||||||
|
if (sectionId === "left" && leftWidgets.length > 0) {
|
||||||
|
leftWidgets.pop()
|
||||||
|
Prefs.setTopBarLeftWidgets(leftWidgets)
|
||||||
|
} else if (sectionId === "center" && centerWidgets.length > 0) {
|
||||||
|
centerWidgets.pop()
|
||||||
|
Prefs.setTopBarCenterWidgets(centerWidgets)
|
||||||
|
} else if (sectionId === "right" && rightWidgets.length > 0) {
|
||||||
|
rightWidgets.pop()
|
||||||
|
Prefs.setTopBarRightWidgets(rightWidgets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleItemEnabledChanged(itemId, enabled) {
|
||||||
|
// Update the widget's enabled state in preferences
|
||||||
|
if (itemId === "focusedWindow") {
|
||||||
|
Prefs.setShowFocusedWindow(enabled)
|
||||||
|
} else if (itemId === "weather") {
|
||||||
|
Prefs.setShowWeather(enabled)
|
||||||
|
} else if (itemId === "music") {
|
||||||
|
Prefs.setShowMusic(enabled)
|
||||||
|
} else if (itemId === "clipboard") {
|
||||||
|
Prefs.setShowClipboard(enabled)
|
||||||
|
} else if (itemId === "systemResources") {
|
||||||
|
Prefs.setShowSystemResources(enabled)
|
||||||
|
} else if (itemId === "systemTray") {
|
||||||
|
Prefs.setShowSystemTray(enabled)
|
||||||
|
} else if (itemId === "clock") {
|
||||||
|
Prefs.setShowClock(enabled)
|
||||||
|
} else if (itemId === "notificationButton") {
|
||||||
|
Prefs.setShowNotificationButton(enabled)
|
||||||
|
} else if (itemId === "controlCenterButton") {
|
||||||
|
Prefs.setShowControlCenterButton(enabled)
|
||||||
|
} else if (itemId === "battery") {
|
||||||
|
Prefs.setShowBattery(enabled)
|
||||||
|
} else if (itemId === "launcherButton") {
|
||||||
|
Prefs.setShowLauncherButton(enabled)
|
||||||
|
} else if (itemId === "workspaceSwitcher") {
|
||||||
|
Prefs.setShowWorkspaceSwitcher(enabled)
|
||||||
|
}
|
||||||
|
// Note: spacer and separator don't need preference handling as they're always enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleItemOrderChanged(sectionId, newOrder) {
|
||||||
|
if (sectionId === "left") {
|
||||||
|
Prefs.setTopBarLeftWidgets(newOrder)
|
||||||
|
} else if (sectionId === "center") {
|
||||||
|
Prefs.setTopBarCenterWidgets(newOrder)
|
||||||
|
} else if (sectionId === "right") {
|
||||||
|
Prefs.setTopBarRightWidgets(newOrder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItemsForSection(sectionId) {
|
||||||
|
var widgets = []
|
||||||
|
var widgetIds = []
|
||||||
|
|
||||||
|
if (sectionId === "left") {
|
||||||
|
widgetIds = Prefs.topBarLeftWidgets || []
|
||||||
|
} else if (sectionId === "center") {
|
||||||
|
widgetIds = Prefs.topBarCenterWidgets || []
|
||||||
|
} else if (sectionId === "right") {
|
||||||
|
widgetIds = Prefs.topBarRightWidgets || []
|
||||||
|
}
|
||||||
|
|
||||||
|
widgetIds.forEach(widgetId => {
|
||||||
|
var widgetDef = baseWidgetDefinitions.find(w => w.id === widgetId)
|
||||||
|
if (widgetDef) {
|
||||||
|
var item = Object.assign({}, widgetDef)
|
||||||
|
// Set enabled state based on preferences
|
||||||
|
if (widgetId === "focusedWindow") {
|
||||||
|
item.enabled = Prefs.showFocusedWindow
|
||||||
|
} else if (widgetId === "weather") {
|
||||||
|
item.enabled = Prefs.showWeather
|
||||||
|
} else if (widgetId === "music") {
|
||||||
|
item.enabled = Prefs.showMusic
|
||||||
|
} else if (widgetId === "clipboard") {
|
||||||
|
item.enabled = Prefs.showClipboard
|
||||||
|
} else if (widgetId === "systemResources") {
|
||||||
|
item.enabled = Prefs.showSystemResources
|
||||||
|
} else if (widgetId === "systemTray") {
|
||||||
|
item.enabled = Prefs.showSystemTray
|
||||||
|
} else if (widgetId === "clock") {
|
||||||
|
item.enabled = Prefs.showClock
|
||||||
|
} else if (widgetId === "notificationButton") {
|
||||||
|
item.enabled = Prefs.showNotificationButton
|
||||||
|
} else if (widgetId === "controlCenterButton") {
|
||||||
|
item.enabled = Prefs.showControlCenterButton
|
||||||
|
} else if (widgetId === "battery") {
|
||||||
|
item.enabled = Prefs.showBattery
|
||||||
|
} else if (widgetId === "launcherButton") {
|
||||||
|
item.enabled = Prefs.showLauncherButton
|
||||||
|
} else if (widgetId === "workspaceSwitcher") {
|
||||||
|
item.enabled = Prefs.showWorkspaceSwitcher
|
||||||
|
}
|
||||||
|
// spacer and separator are always enabled (no preference toggle needed)
|
||||||
|
widgets.push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return widgets
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: column
|
id: column
|
||||||
|
|
||||||
@@ -18,105 +261,213 @@ ScrollView {
|
|||||||
topPadding: Theme.spacingL
|
topPadding: Theme.spacingL
|
||||||
bottomPadding: Theme.spacingXL
|
bottomPadding: Theme.spacingXL
|
||||||
|
|
||||||
// Top Bar Widgets Section
|
// Header section
|
||||||
StyledRect {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: topBarSection.implicitHeight + Theme.spacingL * 2
|
spacing: Theme.spacingM
|
||||||
radius: Theme.cornerRadiusLarge
|
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Column {
|
DankIcon {
|
||||||
id: topBarSection
|
name: "widgets"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
StyledText {
|
||||||
anchors.margins: Theme.spacingL
|
text: "Top Bar Widget Management"
|
||||||
spacing: Theme.spacingM
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width - 400
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 80
|
||||||
|
height: 28
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: resetArea.containsMouse ? Theme.surfacePressed : Theme.surfaceVariant
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
border.width: 1
|
||||||
|
border.color: resetArea.containsMouse ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.5)
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "widgets"
|
name: "refresh"
|
||||||
size: Theme.iconSize
|
size: 14
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Top Bar Widgets"
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
StyledText {
|
||||||
|
text: "Reset"
|
||||||
DankToggle {
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
width: parent.width
|
font.weight: Font.Medium
|
||||||
text: "Focused Window"
|
color: Theme.surfaceText
|
||||||
description: "Show the currently focused application in the top bar"
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
checked: Prefs.showFocusedWindow
|
|
||||||
onToggled: (checked) => {
|
|
||||||
return Prefs.setShowFocusedWindow(checked);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
MouseArea {
|
||||||
width: parent.width
|
id: resetArea
|
||||||
text: "Weather Widget"
|
anchors.fill: parent
|
||||||
description: "Display weather information in the top bar"
|
hoverEnabled: true
|
||||||
checked: Prefs.showWeather
|
cursorShape: Qt.PointingHandCursor
|
||||||
onToggled: (checked) => {
|
onClicked: {
|
||||||
return Prefs.setShowWeather(checked);
|
// Reset all sections to defaults
|
||||||
|
Prefs.setTopBarLeftWidgets(defaultLeftWidgets)
|
||||||
|
Prefs.setTopBarCenterWidgets(defaultCenterWidgets)
|
||||||
|
Prefs.setTopBarRightWidgets(defaultRightWidgets)
|
||||||
|
|
||||||
|
// Reset all widget enabled states to defaults (all enabled)
|
||||||
|
Prefs.setShowFocusedWindow(true)
|
||||||
|
Prefs.setShowWeather(true)
|
||||||
|
Prefs.setShowMusic(true)
|
||||||
|
Prefs.setShowClipboard(true)
|
||||||
|
Prefs.setShowSystemResources(true)
|
||||||
|
Prefs.setShowSystemTray(true)
|
||||||
|
Prefs.setShowClock(true)
|
||||||
|
Prefs.setShowNotificationButton(true)
|
||||||
|
Prefs.setShowControlCenterButton(true)
|
||||||
|
Prefs.setShowBattery(true)
|
||||||
|
Prefs.setShowLauncherButton(true)
|
||||||
|
Prefs.setShowWorkspaceSwitcher(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
Behavior on color {
|
||||||
width: parent.width
|
ColorAnimation {
|
||||||
text: "Media Controls"
|
duration: Theme.shortDuration
|
||||||
description: "Show currently playing media in the top bar"
|
easing.type: Theme.standardEasing
|
||||||
checked: Prefs.showMusic
|
|
||||||
onToggled: (checked) => {
|
|
||||||
return Prefs.setShowMusic(checked);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
Behavior on border.color {
|
||||||
width: parent.width
|
ColorAnimation {
|
||||||
text: "Clipboard Button"
|
duration: Theme.shortDuration
|
||||||
description: "Show clipboard access button in the top bar"
|
easing.type: Theme.standardEasing
|
||||||
checked: Prefs.showClipboard
|
|
||||||
onToggled: (checked) => {
|
|
||||||
return Prefs.setShowClipboard(checked);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DankToggle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "System Resources"
|
height: messageText.contentHeight + Theme.spacingM * 2
|
||||||
description: "Display CPU and RAM usage indicators"
|
radius: Theme.cornerRadius
|
||||||
checked: Prefs.showSystemResources
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
onToggled: (checked) => {
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
return Prefs.setShowSystemResources(checked);
|
border.width: 1
|
||||||
}
|
visible: true
|
||||||
|
opacity: 1.0
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: messageText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "Drag widgets to reorder within sections. Use + to add widgets and - to remove the last widget from each section."
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.outline
|
||||||
|
width: parent.width - Theme.spacingM * 2
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget sections
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
|
// Left Section
|
||||||
|
DankSections {
|
||||||
|
width: parent.width
|
||||||
|
title: "Left Section"
|
||||||
|
titleIcon: "format_align_left"
|
||||||
|
sectionId: "left"
|
||||||
|
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||||
|
items: widgetsTab.getItemsForSection("left")
|
||||||
|
|
||||||
|
onItemEnabledChanged: (itemId, enabled) => {
|
||||||
|
widgetsTab.handleItemEnabledChanged(itemId, enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
onItemOrderChanged: (newOrder) => {
|
||||||
width: parent.width
|
widgetsTab.handleItemOrderChanged("left", newOrder)
|
||||||
text: "System Tray"
|
|
||||||
description: "Show system tray icons in the top bar"
|
|
||||||
checked: Prefs.showSystemTray
|
|
||||||
onToggled: (checked) => {
|
|
||||||
return Prefs.setShowSystemTray(checked);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAddWidget: (sectionId) => {
|
||||||
|
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||||
|
widgetSelectionPopup.targetSection = sectionId
|
||||||
|
widgetSelectionPopup.safeOpen()
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemoveLastWidget: (sectionId) => {
|
||||||
|
widgetsTab.removeLastWidgetFromSection(sectionId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Center Section
|
||||||
|
DankSections {
|
||||||
|
width: parent.width
|
||||||
|
title: "Center Section"
|
||||||
|
titleIcon: "format_align_center"
|
||||||
|
sectionId: "center"
|
||||||
|
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||||
|
items: widgetsTab.getItemsForSection("center")
|
||||||
|
|
||||||
|
onItemEnabledChanged: (itemId, enabled) => {
|
||||||
|
widgetsTab.handleItemEnabledChanged(itemId, enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
onItemOrderChanged: (newOrder) => {
|
||||||
|
widgetsTab.handleItemOrderChanged("center", newOrder)
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddWidget: (sectionId) => {
|
||||||
|
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||||
|
widgetSelectionPopup.targetSection = sectionId
|
||||||
|
widgetSelectionPopup.safeOpen()
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemoveLastWidget: (sectionId) => {
|
||||||
|
widgetsTab.removeLastWidgetFromSection(sectionId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right Section
|
||||||
|
DankSections {
|
||||||
|
width: parent.width
|
||||||
|
title: "Right Section"
|
||||||
|
titleIcon: "format_align_right"
|
||||||
|
sectionId: "right"
|
||||||
|
allWidgets: widgetsTab.baseWidgetDefinitions
|
||||||
|
items: widgetsTab.getItemsForSection("right")
|
||||||
|
|
||||||
|
onItemEnabledChanged: (itemId, enabled) => {
|
||||||
|
widgetsTab.handleItemEnabledChanged(itemId, enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
onItemOrderChanged: (newOrder) => {
|
||||||
|
widgetsTab.handleItemOrderChanged("right", newOrder)
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddWidget: (sectionId) => {
|
||||||
|
widgetSelectionPopup.allWidgets = widgetsTab.baseWidgetDefinitions
|
||||||
|
widgetSelectionPopup.targetSection = sectionId
|
||||||
|
widgetSelectionPopup.safeOpen()
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemoveLastWidget: (sectionId) => {
|
||||||
|
widgetsTab.removeLastWidgetFromSection(sectionId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workspace Section
|
// Workspace Section
|
||||||
@@ -153,7 +504,6 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
@@ -175,11 +525,47 @@ ScrollView {
|
|||||||
return Prefs.setShowWorkspacePadding(checked);
|
return Prefs.setShowWorkspacePadding(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tooltip for reset button (positioned above the button)
|
||||||
|
Rectangle {
|
||||||
|
width: tooltipText.contentWidth + Theme.spacingM * 2
|
||||||
|
height: tooltipText.contentHeight + Theme.spacingS * 2
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Theme.surfaceContainer
|
||||||
|
border.color: Theme.outline
|
||||||
|
border.width: 1
|
||||||
|
visible: resetArea.containsMouse
|
||||||
|
opacity: resetArea.containsMouse ? 1 : 0
|
||||||
|
y: column.y + 48 // Position above the reset button in the header
|
||||||
|
x: parent.width - width - Theme.spacingM
|
||||||
|
z: 100
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: tooltipText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "Reset widget layout to defaults"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget selection popup
|
||||||
|
DankWidgetSelectionPopup {
|
||||||
|
id: widgetSelectionPopup
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
onWidgetSelected: (widgetId, targetSection) => {
|
||||||
|
widgetsTab.addWidgetToSection(widgetId, targetSection)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -29,6 +29,22 @@ PanelWindow {
|
|||||||
if (fonts.indexOf("Material Symbols Rounded") === -1)
|
if (fonts.indexOf("Material Symbols Rounded") === -1)
|
||||||
ToastService.showError("Please install Material Symbols Rounded and Restart your Shell. See README.md for instructions");
|
ToastService.showError("Please install Material Symbols Rounded and Restart your Shell. See README.md for instructions");
|
||||||
|
|
||||||
|
// Connect to the force refresh signal
|
||||||
|
Prefs.forceTopBarLayoutRefresh.connect(function() {
|
||||||
|
console.log("TopBar: Forcing layout refresh");
|
||||||
|
// Force layout recalculation by toggling visibility briefly
|
||||||
|
Qt.callLater(() => {
|
||||||
|
leftSection.visible = false;
|
||||||
|
centerSection.visible = false;
|
||||||
|
rightSection.visible = false;
|
||||||
|
Qt.callLater(() => {
|
||||||
|
leftSection.visible = true;
|
||||||
|
centerSection.visible = true;
|
||||||
|
rightSection.visible = true;
|
||||||
|
console.log("TopBar: Layout refresh completed");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
@@ -36,6 +52,8 @@ PanelWindow {
|
|||||||
root.backgroundTransparency = Prefs.topBarTransparency;
|
root.backgroundTransparency = Prefs.topBarTransparency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove old manual refresh handlers - ListModel updates are automatic
|
||||||
|
|
||||||
target: Prefs
|
target: Prefs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,12 +134,12 @@ PanelWindow {
|
|||||||
// Use estimated fixed widths to break circular dependencies
|
// Use estimated fixed widths to break circular dependencies
|
||||||
readonly property int launcherButtonWidth: 40
|
readonly property int launcherButtonWidth: 40
|
||||||
readonly property int workspaceSwitcherWidth: 120 // Approximate
|
readonly property int workspaceSwitcherWidth: 120 // Approximate
|
||||||
readonly property int focusedAppMaxWidth: focusedApp.visible ? 456 : 0
|
readonly property int focusedAppMaxWidth: 456 // Fixed width since we don't have focusedApp reference
|
||||||
readonly property int estimatedLeftSectionWidth: launcherButtonWidth + workspaceSwitcherWidth + focusedAppMaxWidth + (Theme.spacingXS * 2)
|
readonly property int estimatedLeftSectionWidth: launcherButtonWidth + workspaceSwitcherWidth + focusedAppMaxWidth + (Theme.spacingXS * 2)
|
||||||
readonly property int rightSectionWidth: rightSection.width
|
readonly property int rightSectionWidth: rightSection.width
|
||||||
readonly property int clockWidth: clock.width
|
readonly property int clockWidth: 120 // Approximate clock width
|
||||||
readonly property int mediaMaxWidth: media.visible ? 280 : 0 // Normal max width
|
readonly property int mediaMaxWidth: 280 // Normal max width
|
||||||
readonly property int weatherWidth: weather.visible ? weather.width : 0
|
readonly property int weatherWidth: 80 // Approximate weather width
|
||||||
readonly property bool validLayout: availableWidth > 100 && estimatedLeftSectionWidth > 0 && rightSectionWidth > 0
|
readonly property bool validLayout: availableWidth > 100 && estimatedLeftSectionWidth > 0 && rightSectionWidth > 0
|
||||||
readonly property int clockLeftEdge: (availableWidth - clockWidth) / 2
|
readonly property int clockLeftEdge: (availableWidth - clockWidth) / 2
|
||||||
readonly property int clockRightEdge: clockLeftEdge + clockWidth
|
readonly property int clockRightEdge: clockLeftEdge + clockWidth
|
||||||
@@ -135,6 +153,79 @@ PanelWindow {
|
|||||||
readonly property bool spacingTight: validLayout && (leftToMediaGap < 150 || clockToRightGap < 100)
|
readonly property bool spacingTight: validLayout && (leftToMediaGap < 150 || clockToRightGap < 100)
|
||||||
readonly property bool overlapping: validLayout && (leftToMediaGap < 100 || clockToRightGap < 50)
|
readonly property bool overlapping: validLayout && (leftToMediaGap < 100 || clockToRightGap < 50)
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
function getWidgetEnabled(widgetId) {
|
||||||
|
switch (widgetId) {
|
||||||
|
case "launcherButton": return Prefs.showLauncherButton
|
||||||
|
case "workspaceSwitcher": return Prefs.showWorkspaceSwitcher
|
||||||
|
case "focusedWindow": return Prefs.showFocusedWindow
|
||||||
|
case "clock": return Prefs.showClock
|
||||||
|
case "music": return Prefs.showMusic
|
||||||
|
case "weather": return Prefs.showWeather
|
||||||
|
case "systemTray": return Prefs.showSystemTray
|
||||||
|
case "clipboard": return Prefs.showClipboard
|
||||||
|
case "systemResources": return Prefs.showSystemResources
|
||||||
|
case "notificationButton": return Prefs.showNotificationButton
|
||||||
|
case "battery": return Prefs.showBattery
|
||||||
|
case "controlCenterButton": return Prefs.showControlCenterButton
|
||||||
|
default: return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWidgetVisible(widgetId) {
|
||||||
|
// Some widgets have additional visibility conditions
|
||||||
|
switch (widgetId) {
|
||||||
|
case "launcherButton": return true
|
||||||
|
case "workspaceSwitcher": return true // Simplified - was NiriService.niriAvailable
|
||||||
|
case "focusedWindow": return true
|
||||||
|
case "clock": return true
|
||||||
|
case "music": return true // Simplified - was MprisController.activePlayer
|
||||||
|
case "weather": return true // Simplified - was complex weather condition
|
||||||
|
case "systemTray": return true
|
||||||
|
case "clipboard": return true
|
||||||
|
case "systemResources": return true
|
||||||
|
case "notificationButton": return true
|
||||||
|
case "battery": return true
|
||||||
|
case "controlCenterButton": return true
|
||||||
|
default: return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWidgetComponent(widgetId) {
|
||||||
|
switch (widgetId) {
|
||||||
|
case "launcherButton":
|
||||||
|
return launcherButtonComponent
|
||||||
|
case "workspaceSwitcher":
|
||||||
|
return workspaceSwitcherComponent
|
||||||
|
case "focusedWindow":
|
||||||
|
return focusedWindowComponent
|
||||||
|
case "clock":
|
||||||
|
return clockComponent
|
||||||
|
case "music":
|
||||||
|
return mediaComponent
|
||||||
|
case "weather":
|
||||||
|
return weatherComponent
|
||||||
|
case "systemTray":
|
||||||
|
return systemTrayComponent
|
||||||
|
case "clipboard":
|
||||||
|
return clipboardComponent
|
||||||
|
case "systemResources":
|
||||||
|
return systemResourcesComponent
|
||||||
|
case "notificationButton":
|
||||||
|
return notificationButtonComponent
|
||||||
|
case "battery":
|
||||||
|
return batteryComponent
|
||||||
|
case "controlCenterButton":
|
||||||
|
return controlCenterButtonComponent
|
||||||
|
case "spacer":
|
||||||
|
return spacerComponent
|
||||||
|
case "separator":
|
||||||
|
return separatorComponent
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingM
|
anchors.leftMargin: Theme.spacingM
|
||||||
anchors.rightMargin: Theme.spacingM
|
anchors.rightMargin: Theme.spacingM
|
||||||
@@ -142,6 +233,7 @@ PanelWindow {
|
|||||||
anchors.bottomMargin: Theme.spacingXS
|
anchors.bottomMargin: Theme.spacingXS
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
// Dynamic left section
|
||||||
Row {
|
Row {
|
||||||
id: leftSection
|
id: leftSection
|
||||||
|
|
||||||
@@ -150,67 +242,45 @@ PanelWindow {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
LauncherButton {
|
Repeater {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
model: Prefs.topBarLeftWidgetsModel
|
||||||
isActive: appDrawerPopout ? appDrawerPopout.isVisible : false
|
|
||||||
onClicked: {
|
|
||||||
if (appDrawerPopout)
|
|
||||||
appDrawerPopout.toggle();
|
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||||
|
active: topBarContent.getWidgetEnabled(model.widgetId) && topBarContent.getWidgetVisible(model.widgetId)
|
||||||
|
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
||||||
|
|
||||||
|
property string widgetId: model.widgetId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkspaceSwitcher {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
screenName: root.screenName
|
|
||||||
}
|
|
||||||
|
|
||||||
FocusedApp {
|
|
||||||
id: focusedApp
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: Prefs.showFocusedWindow
|
|
||||||
compactMode: topBarContent.spacingTight
|
|
||||||
availableWidth: topBarContent.leftToMediaGap
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Clock {
|
// Dynamic center section
|
||||||
id: clock
|
Row {
|
||||||
|
id: centerSection
|
||||||
|
|
||||||
|
height: parent.height
|
||||||
|
spacing: Theme.spacingS
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
compactMode: topBarContent.overlapping
|
|
||||||
onClockClicked: {
|
Component.onCompleted: {
|
||||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
console.log("Center widgets model count:", Prefs.topBarCenterWidgetsModel.count)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Repeater {
|
||||||
Media {
|
model: Prefs.topBarCenterWidgetsModel
|
||||||
id: media
|
|
||||||
|
Loader {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||||
anchors.right: clock.left
|
active: topBarContent.getWidgetEnabled(model.widgetId) && topBarContent.getWidgetVisible(model.widgetId)
|
||||||
anchors.rightMargin: Theme.spacingS
|
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
||||||
visible: Prefs.showMusic && MprisController.activePlayer
|
|
||||||
compactMode: topBarContent.spacingTight || topBarContent.overlapping
|
property string widgetId: model.widgetId
|
||||||
onClicked: {
|
}
|
||||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Weather {
|
|
||||||
id: weather
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: clock.right
|
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
visible: Prefs.showWeather && WeatherService.weather.available && WeatherService.weather.temp > 0 && WeatherService.weather.tempF > 0
|
|
||||||
onClicked: {
|
|
||||||
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic right section
|
||||||
Row {
|
Row {
|
||||||
id: rightSection
|
id: rightSection
|
||||||
|
|
||||||
@@ -219,9 +289,82 @@ PanelWindow {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
console.log("Right widgets model count:", Prefs.topBarRightWidgetsModel.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: Prefs.topBarRightWidgetsModel
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||||
|
active: topBarContent.getWidgetEnabled(model.widgetId) && topBarContent.getWidgetVisible(model.widgetId)
|
||||||
|
sourceComponent: topBarContent.getWidgetComponent(model.widgetId)
|
||||||
|
|
||||||
|
property string widgetId: model.widgetId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget Components
|
||||||
|
Component {
|
||||||
|
id: launcherButtonComponent
|
||||||
|
LauncherButton {
|
||||||
|
isActive: appDrawerPopout ? appDrawerPopout.isVisible : false
|
||||||
|
onClicked: {
|
||||||
|
if (appDrawerPopout)
|
||||||
|
appDrawerPopout.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: workspaceSwitcherComponent
|
||||||
|
WorkspaceSwitcher {
|
||||||
|
screenName: root.screenName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: focusedWindowComponent
|
||||||
|
FocusedApp {
|
||||||
|
compactMode: topBarContent.spacingTight
|
||||||
|
availableWidth: topBarContent.leftToMediaGap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: clockComponent
|
||||||
|
Clock {
|
||||||
|
compactMode: topBarContent.overlapping
|
||||||
|
onClockClicked: {
|
||||||
|
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: mediaComponent
|
||||||
|
Media {
|
||||||
|
compactMode: topBarContent.spacingTight || topBarContent.overlapping
|
||||||
|
onClicked: {
|
||||||
|
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: weatherComponent
|
||||||
|
Weather {
|
||||||
|
onClicked: {
|
||||||
|
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: systemTrayComponent
|
||||||
SystemTrayBar {
|
SystemTrayBar {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: Prefs.showSystemTray
|
|
||||||
onMenuRequested: (menu, item, x, y) => {
|
onMenuRequested: (menu, item, x, y) => {
|
||||||
systemTrayContextMenu.currentTrayMenu = menu;
|
systemTrayContextMenu.currentTrayMenu = menu;
|
||||||
systemTrayContextMenu.currentTrayItem = item;
|
systemTrayContextMenu.currentTrayItem = item;
|
||||||
@@ -231,7 +374,10 @@ PanelWindow {
|
|||||||
menu.menuVisible = true;
|
menu.menuVisible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: clipboardComponent
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 40
|
width: 40
|
||||||
height: 30
|
height: 30
|
||||||
@@ -240,8 +386,6 @@ PanelWindow {
|
|||||||
const baseColor = clipboardArea.containsMouse ? Theme.primaryHover : Theme.secondaryHover;
|
const baseColor = clipboardArea.containsMouse ? Theme.primaryHover : Theme.secondaryHover;
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: Prefs.showClipboard
|
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -252,7 +396,6 @@ PanelWindow {
|
|||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: clipboardArea
|
id: clipboardArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -266,71 +409,80 @@ PanelWindow {
|
|||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Component {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
id: systemResourcesComponent
|
||||||
active: Prefs.showSystemResources
|
Row {
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
sourceComponent: Component {
|
CpuMonitor {
|
||||||
CpuMonitor {
|
toggleProcessList: () => {
|
||||||
toggleProcessList: () => {
|
return processListPopout.toggle();
|
||||||
return processListPopout.toggle();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
RamMonitor {
|
||||||
|
toggleProcessList: () => {
|
||||||
Loader {
|
return processListPopout.toggle();
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
active: Prefs.showSystemResources
|
|
||||||
|
|
||||||
sourceComponent: Component {
|
|
||||||
RamMonitor {
|
|
||||||
toggleProcessList: () => {
|
|
||||||
return processListPopout.toggle();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: notificationButtonComponent
|
||||||
NotificationCenterButton {
|
NotificationCenterButton {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
hasUnread: root.notificationCount > 0
|
hasUnread: root.notificationCount > 0
|
||||||
isActive: notificationCenter.notificationHistoryVisible
|
isActive: notificationCenter.notificationHistoryVisible
|
||||||
onClicked: {
|
onClicked: {
|
||||||
notificationCenter.notificationHistoryVisible = !notificationCenter.notificationHistoryVisible;
|
notificationCenter.notificationHistoryVisible = !notificationCenter.notificationHistoryVisible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: batteryComponent
|
||||||
Battery {
|
Battery {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
batteryPopupVisible: batteryPopout.batteryPopupVisible
|
batteryPopupVisible: batteryPopout.batteryPopupVisible
|
||||||
onToggleBatteryPopup: {
|
onToggleBatteryPopup: {
|
||||||
batteryPopout.batteryPopupVisible = !batteryPopout.batteryPopupVisible;
|
batteryPopout.batteryPopupVisible = !batteryPopout.batteryPopupVisible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: controlCenterButtonComponent
|
||||||
ControlCenterButton {
|
ControlCenterButton {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
isActive: controlCenterPopout.controlCenterVisible
|
isActive: controlCenterPopout.controlCenterVisible
|
||||||
onClicked: {
|
onClicked: {
|
||||||
controlCenterPopout.controlCenterVisible = !controlCenterPopout.controlCenterVisible;
|
controlCenterPopout.controlCenterVisible = !controlCenterPopout.controlCenterVisible;
|
||||||
if (controlCenterPopout.controlCenterVisible) {
|
if (controlCenterPopout.controlCenterVisible) {
|
||||||
if (NetworkService.wifiEnabled)
|
if (NetworkService.wifiEnabled)
|
||||||
NetworkService.scanWifi();
|
NetworkService.scanWifi();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: spacerComponent
|
||||||
|
Item {
|
||||||
|
width: 20
|
||||||
|
height: 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: separatorComponent
|
||||||
|
Rectangle {
|
||||||
|
width: 1
|
||||||
|
height: 20
|
||||||
|
color: Theme.outline
|
||||||
|
opacity: 0.3
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,10 @@ StyledRect {
|
|||||||
StateLayer {
|
StateLayer {
|
||||||
stateColor: Theme.primary
|
stateColor: Theme.primary
|
||||||
cornerRadius: root.radius
|
cornerRadius: root.radius
|
||||||
onClicked: root.clicked()
|
onClicked: {
|
||||||
|
console.log("StateLayer clicked for button:", root.iconName);
|
||||||
|
root.clicked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ Rectangle {
|
|||||||
if (selectedIndex >= 0 && selectedIndex < filteredOptions.length) {
|
if (selectedIndex >= 0 && selectedIndex < filteredOptions.length) {
|
||||||
root.currentValue = filteredOptions[selectedIndex];
|
root.currentValue = filteredOptions[selectedIndex];
|
||||||
root.valueChanged(filteredOptions[selectedIndex]);
|
root.valueChanged(filteredOptions[selectedIndex]);
|
||||||
dropdownMenu.close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,17 +256,17 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 1
|
anchors.margins: 1
|
||||||
placeholderText: "Search..."
|
placeholderText: "Search..."
|
||||||
text: dropdownMenu.searchQuery
|
text: searchQuery
|
||||||
topPadding: Theme.spacingS
|
topPadding: Theme.spacingS
|
||||||
bottomPadding: Theme.spacingS
|
bottomPadding: Theme.spacingS
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
dropdownMenu.searchQuery = text;
|
searchQuery = text;
|
||||||
dropdownMenu.updateFilteredOptions();
|
updateFilteredOptions();
|
||||||
}
|
}
|
||||||
Keys.onDownPressed: dropdownMenu.selectNext()
|
Keys.onDownPressed: selectNext()
|
||||||
Keys.onUpPressed: dropdownMenu.selectPrevious()
|
Keys.onUpPressed: selectPrevious()
|
||||||
Keys.onReturnPressed: dropdownMenu.selectCurrent()
|
Keys.onReturnPressed: selectCurrent()
|
||||||
Keys.onEnterPressed: dropdownMenu.selectCurrent()
|
Keys.onEnterPressed: selectCurrent()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -286,7 +286,7 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - (root.enableFuzzySearch ? searchContainer.height + Theme.spacingXS : 0)
|
height: parent.height - (root.enableFuzzySearch ? searchContainer.height + Theme.spacingXS : 0)
|
||||||
clip: true
|
clip: true
|
||||||
model: dropdownMenu.filteredOptions
|
model: filteredOptions
|
||||||
spacing: 2
|
spacing: 2
|
||||||
|
|
||||||
WheelHandler {
|
WheelHandler {
|
||||||
@@ -311,7 +311,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
property bool isSelected: dropdownMenu.selectedIndex === index
|
property bool isSelected: selectedIndex === index
|
||||||
property bool isCurrentValue: root.currentValue === modelData
|
property bool isCurrentValue: root.currentValue === modelData
|
||||||
property int optionIndex: root.options.indexOf(modelData)
|
property int optionIndex: root.options.indexOf(modelData)
|
||||||
|
|
||||||
@@ -354,7 +354,7 @@ Rectangle {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
root.currentValue = modelData;
|
root.currentValue = modelData;
|
||||||
root.valueChanged(modelData);
|
root.valueChanged(modelData);
|
||||||
dropdownMenu.close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
263
Widgets/DankSections.qml
Normal file
263
Widgets/DankSections.qml
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var items: []
|
||||||
|
property var allWidgets: []
|
||||||
|
property string title: ""
|
||||||
|
property string titleIcon: "widgets"
|
||||||
|
property string sectionId: ""
|
||||||
|
|
||||||
|
signal itemEnabledChanged(string itemId, bool enabled)
|
||||||
|
signal itemOrderChanged(var newOrder)
|
||||||
|
signal addWidget(string sectionId)
|
||||||
|
signal removeLastWidget(string sectionId)
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
// Header
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: root.titleIcon
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: root.title
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width - 60
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget Items
|
||||||
|
Column {
|
||||||
|
id: itemsList
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.items
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
id: delegateItem
|
||||||
|
width: itemsList.width
|
||||||
|
height: 70
|
||||||
|
|
||||||
|
property int visualIndex: index
|
||||||
|
property bool held: dragArea.pressed
|
||||||
|
property string itemId: modelData.id
|
||||||
|
|
||||||
|
z: held ? 2 : 1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: itemBackground
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
// Drag handle
|
||||||
|
Rectangle {
|
||||||
|
width: 40
|
||||||
|
height: parent.height
|
||||||
|
color: "transparent"
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "drag_indicator"
|
||||||
|
size: Theme.iconSize - 4
|
||||||
|
color: Theme.outline
|
||||||
|
anchors.centerIn: parent
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget icon
|
||||||
|
DankIcon {
|
||||||
|
name: modelData.icon
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: modelData.enabled ? Theme.primary : Theme.outline
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingM + 40 + Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget info
|
||||||
|
Column {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingM + 40 + Theme.spacingM + Theme.iconSize + Theme.spacingM
|
||||||
|
anchors.right: toggle.left
|
||||||
|
anchors.rightMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: modelData.text
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: modelData.enabled ? Theme.surfaceText : Theme.outline
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: modelData.description
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: modelData.enabled ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.6)
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle - positioned at right edge
|
||||||
|
DankToggle {
|
||||||
|
id: toggle
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: 48
|
||||||
|
height: 24
|
||||||
|
hideText: true
|
||||||
|
checked: modelData.enabled
|
||||||
|
onToggled: (checked) => {
|
||||||
|
root.itemEnabledChanged(modelData.id, checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drag functionality
|
||||||
|
MouseArea {
|
||||||
|
id: dragArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
property bool validDragStart: false
|
||||||
|
|
||||||
|
drag.target: held && validDragStart ? delegateItem : undefined
|
||||||
|
drag.axis: Drag.YAxis
|
||||||
|
drag.minimumY: -delegateItem.height
|
||||||
|
drag.maximumY: itemsList.height
|
||||||
|
|
||||||
|
onPressed: (mouse) => {
|
||||||
|
// Only allow dragging from the drag handle area (first 60px)
|
||||||
|
if (mouse.x <= 60) {
|
||||||
|
validDragStart = true
|
||||||
|
delegateItem.z = 2
|
||||||
|
} else {
|
||||||
|
validDragStart = false
|
||||||
|
mouse.accepted = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
delegateItem.z = 1
|
||||||
|
|
||||||
|
if (drag.active && validDragStart) {
|
||||||
|
// Calculate new index based on position
|
||||||
|
var newIndex = Math.round(delegateItem.y / (delegateItem.height + itemsList.spacing))
|
||||||
|
newIndex = Math.max(0, Math.min(newIndex, root.items.length - 1))
|
||||||
|
|
||||||
|
if (newIndex !== index) {
|
||||||
|
var newItems = root.items.slice()
|
||||||
|
var draggedItem = newItems.splice(index, 1)[0]
|
||||||
|
newItems.splice(newIndex, 0, draggedItem)
|
||||||
|
|
||||||
|
root.itemOrderChanged(newItems.map(item => item.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset position
|
||||||
|
delegateItem.x = 0
|
||||||
|
delegateItem.y = 0
|
||||||
|
validDragStart = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animations for drag
|
||||||
|
Behavior on y {
|
||||||
|
enabled: !dragArea.held && !dragArea.drag.active
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add/Remove Controls
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width * 0.5
|
||||||
|
height: 40
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
border.width: 1
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Add or remove widgets"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.outline
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
// Add button
|
||||||
|
DankActionButton {
|
||||||
|
iconName: "add"
|
||||||
|
iconSize: Theme.iconSize - 4
|
||||||
|
iconColor: Theme.primary
|
||||||
|
hoverColor: Theme.primaryContainer
|
||||||
|
onClicked: {
|
||||||
|
root.addWidget(root.sectionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove button
|
||||||
|
DankActionButton {
|
||||||
|
iconName: "remove"
|
||||||
|
iconSize: Theme.iconSize - 4
|
||||||
|
iconColor: Theme.error
|
||||||
|
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.1)
|
||||||
|
enabled: root.items.length > 0
|
||||||
|
opacity: root.items.length > 0 ? 1.0 : 0.5
|
||||||
|
onClicked: {
|
||||||
|
if (root.items.length > 0) {
|
||||||
|
root.removeLastWidget(root.sectionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
265
Widgets/DankSections_backup.qml
Normal file
265
Widgets/DankSections_backup.qml
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var items: []
|
||||||
|
property var allWidgets: []
|
||||||
|
property string title: ""
|
||||||
|
property string titleIcon: "widgets"
|
||||||
|
property string sectionId: ""
|
||||||
|
|
||||||
|
signal itemEnabledChanged(string itemId, bool enabled)
|
||||||
|
signal itemOrderChanged(var newOrder)
|
||||||
|
signal addWidget(string sectionId)
|
||||||
|
signal removeLastWidget(string sectionId)
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
// Header
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: root.titleIcon
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: root.title
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width - 60
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget Items
|
||||||
|
Column {
|
||||||
|
id: itemsList
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.items
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
id: delegateItem
|
||||||
|
width: itemsList.width
|
||||||
|
height: 70
|
||||||
|
|
||||||
|
property int visualIndex: index
|
||||||
|
property bool held: dragArea.pressed
|
||||||
|
property string itemId: modelData.id
|
||||||
|
|
||||||
|
z: held ? 2 : 1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: itemBackground
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingM
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
// Drag handle
|
||||||
|
Rectangle {
|
||||||
|
width: 40
|
||||||
|
height: parent.height
|
||||||
|
color: "transparent"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "drag_indicator"
|
||||||
|
size: Theme.iconSize - 4
|
||||||
|
color: Theme.outline
|
||||||
|
anchors.centerIn: parent
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget icon
|
||||||
|
DankIcon {
|
||||||
|
name: modelData.icon
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: modelData.enabled ? Theme.primary : Theme.outline
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget info
|
||||||
|
Column {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 2
|
||||||
|
width: parent.width - 200 // Leave space for toggle
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: modelData.text
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: modelData.enabled ? Theme.surfaceText : Theme.outline
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: modelData.description
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: modelData.enabled ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.6)
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spacer to push toggle to right
|
||||||
|
Item {
|
||||||
|
width: parent.width - 280 // Dynamic width
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle - positioned at right edge
|
||||||
|
DankToggle {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: 48
|
||||||
|
height: 24
|
||||||
|
hideText: true
|
||||||
|
checked: modelData.enabled
|
||||||
|
onToggled: (checked) => {
|
||||||
|
root.itemEnabledChanged(modelData.id, checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drag functionality
|
||||||
|
MouseArea {
|
||||||
|
id: dragArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
property bool validDragStart: false
|
||||||
|
|
||||||
|
drag.target: held && validDragStart ? delegateItem : undefined
|
||||||
|
drag.axis: Drag.YAxis
|
||||||
|
drag.minimumY: -delegateItem.height
|
||||||
|
drag.maximumY: itemsList.height
|
||||||
|
|
||||||
|
onPressed: (mouse) => {
|
||||||
|
// Only allow dragging from the drag handle area (first 60px)
|
||||||
|
if (mouse.x <= 60) {
|
||||||
|
validDragStart = true
|
||||||
|
delegateItem.z = 2
|
||||||
|
} else {
|
||||||
|
validDragStart = false
|
||||||
|
mouse.accepted = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
delegateItem.z = 1
|
||||||
|
|
||||||
|
if (drag.active && validDragStart) {
|
||||||
|
// Calculate new index based on position
|
||||||
|
var newIndex = Math.round(delegateItem.y / (delegateItem.height + itemsList.spacing))
|
||||||
|
newIndex = Math.max(0, Math.min(newIndex, root.items.length - 1))
|
||||||
|
|
||||||
|
if (newIndex !== index) {
|
||||||
|
var newItems = root.items.slice()
|
||||||
|
var draggedItem = newItems.splice(index, 1)[0]
|
||||||
|
newItems.splice(newIndex, 0, draggedItem)
|
||||||
|
|
||||||
|
root.itemOrderChanged(newItems.map(item => item.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset position
|
||||||
|
delegateItem.x = 0
|
||||||
|
delegateItem.y = 0
|
||||||
|
validDragStart = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animations for drag
|
||||||
|
Behavior on y {
|
||||||
|
enabled: !dragArea.held && !dragArea.drag.active
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add/Remove Controls
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width * 0.5
|
||||||
|
height: 40
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
border.width: 1
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Add or remove widgets"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.outline
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
// Add button
|
||||||
|
DankActionButton {
|
||||||
|
iconName: "add"
|
||||||
|
iconSize: Theme.iconSize - 4
|
||||||
|
iconColor: Theme.primary
|
||||||
|
hoverColor: Theme.primaryContainer
|
||||||
|
onClicked: {
|
||||||
|
root.addWidget(root.sectionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove button
|
||||||
|
DankActionButton {
|
||||||
|
iconName: "remove"
|
||||||
|
iconSize: Theme.iconSize - 4
|
||||||
|
iconColor: Theme.error
|
||||||
|
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.1)
|
||||||
|
enabled: root.items.length > 0
|
||||||
|
opacity: root.items.length > 0 ? 1.0 : 0.5
|
||||||
|
onClicked: {
|
||||||
|
if (root.items.length > 0) {
|
||||||
|
root.removeLastWidget(root.sectionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,23 +10,24 @@ Item {
|
|||||||
property bool toggling: false
|
property bool toggling: false
|
||||||
property string text: ""
|
property string text: ""
|
||||||
property string description: ""
|
property string description: ""
|
||||||
|
property bool hideText: false
|
||||||
|
|
||||||
signal clicked()
|
signal clicked()
|
||||||
signal toggled(bool checked)
|
signal toggled(bool checked)
|
||||||
|
|
||||||
width: text ? parent.width : 48
|
width: (text && !hideText) ? parent.width : 48
|
||||||
height: text ? 60 : 24
|
height: (text && !hideText) ? 60 : 24
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
id: background
|
id: background
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: toggle.text ? Theme.cornerRadius : 0
|
radius: (toggle.text && !toggle.hideText) ? Theme.cornerRadius : 0
|
||||||
color: toggle.text ? Theme.surfaceHover : "transparent"
|
color: (toggle.text && !toggle.hideText) ? Theme.surfaceHover : "transparent"
|
||||||
visible: toggle.text
|
visible: (toggle.text && !toggle.hideText)
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
visible: toggle.text
|
visible: (toggle.text && !toggle.hideText)
|
||||||
disabled: !toggle.enabled
|
disabled: !toggle.enabled
|
||||||
stateColor: Theme.primary
|
stateColor: Theme.primary
|
||||||
cornerRadius: parent.radius
|
cornerRadius: parent.radius
|
||||||
@@ -50,7 +51,7 @@ Item {
|
|||||||
anchors.leftMargin: Theme.spacingM
|
anchors.leftMargin: Theme.spacingM
|
||||||
anchors.rightMargin: Theme.spacingM
|
anchors.rightMargin: Theme.spacingM
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
visible: toggle.text
|
visible: (toggle.text && !toggle.hideText)
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|||||||
187
Widgets/DankWidgetSelectionPopup.qml
Normal file
187
Widgets/DankWidgetSelectionPopup.qml
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var allWidgets: []
|
||||||
|
property string targetSection: ""
|
||||||
|
property bool isOpening: false
|
||||||
|
|
||||||
|
signal widgetSelected(string widgetId, string targetSection)
|
||||||
|
|
||||||
|
width: 400
|
||||||
|
height: 450
|
||||||
|
modal: true
|
||||||
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||||
|
|
||||||
|
// Prevent multiple openings
|
||||||
|
function safeOpen() {
|
||||||
|
if (!isOpening && !visible) {
|
||||||
|
isOpening = true
|
||||||
|
open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
isOpening = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
isOpening = false
|
||||||
|
// Clear references to prevent memory leaks
|
||||||
|
allWidgets = []
|
||||||
|
targetSection = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 1)
|
||||||
|
border.color: Theme.primarySelected
|
||||||
|
border.width: 1
|
||||||
|
radius: Theme.cornerRadiusLarge
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
// Close button in top-right
|
||||||
|
DankActionButton {
|
||||||
|
iconName: "close"
|
||||||
|
iconSize: Theme.iconSize - 2
|
||||||
|
iconColor: Theme.outline
|
||||||
|
hoverColor: Theme.primaryContainer
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: Theme.spacingM
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.spacingM
|
||||||
|
onClicked: root.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: contentColumn
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
anchors.topMargin: Theme.spacingL + 30 // Space for close button
|
||||||
|
|
||||||
|
// Header
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "add_circle"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Add Widget to " + root.targetSection + " Section"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Select a widget to add to the " + root.targetSection.toLowerCase() + " section of the top bar. You can add multiple instances of the same widget if needed."
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.outline
|
||||||
|
width: parent.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget List
|
||||||
|
ScrollView {
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - 120 // Leave space for header and description
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: widgetList
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
model: root.allWidgets
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
width: widgetList.width
|
||||||
|
height: 60
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: widgetArea.containsMouse ? Theme.primaryHover : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingM
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
// Widget icon
|
||||||
|
DankIcon {
|
||||||
|
name: modelData.icon
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget info
|
||||||
|
Column {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: 2
|
||||||
|
width: parent.width - Theme.iconSize - Theme.spacingM * 3
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: modelData.text
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: modelData.description
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.outline
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add icon
|
||||||
|
DankIcon {
|
||||||
|
name: "add"
|
||||||
|
size: Theme.iconSize - 4
|
||||||
|
color: Theme.primary
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: widgetArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.widgetSelected(modelData.id, root.targetSection)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user