mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-28 15:32:50 -05:00
uncomment toast, and format
This commit is contained in:
@@ -6,9 +6,9 @@ import Quickshell.Io
|
|||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modules.AppDrawer
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
import qs.Modules.AppDrawer
|
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: appDrawerPopout
|
id: appDrawerPopout
|
||||||
@@ -50,10 +50,9 @@ PanelWindow {
|
|||||||
// App launcher logic
|
// App launcher logic
|
||||||
AppLauncher {
|
AppLauncher {
|
||||||
id: appLauncher
|
id: appLauncher
|
||||||
|
|
||||||
viewMode: Prefs.appLauncherViewMode
|
viewMode: Prefs.appLauncherViewMode
|
||||||
gridColumns: 4
|
gridColumns: 4
|
||||||
|
|
||||||
onAppLaunched: appDrawerPopout.hide()
|
onAppLaunched: appDrawerPopout.hide()
|
||||||
onViewModeSelected: function(mode) {
|
onViewModeSelected: function(mode) {
|
||||||
Prefs.setAppLauncherViewMode(mode);
|
Prefs.setAppLauncherViewMode(mode);
|
||||||
@@ -67,48 +66,48 @@ PanelWindow {
|
|||||||
onClicked: function(mouse) {
|
onClicked: function(mouse) {
|
||||||
// Only close if click is outside the launcher panel
|
// Only close if click is outside the launcher panel
|
||||||
var localPos = mapToItem(launcherLoader, mouse.x, mouse.y);
|
var localPos = mapToItem(launcherLoader, mouse.x, mouse.y);
|
||||||
if (localPos.x < 0 || localPos.x > launcherLoader.width ||
|
if (localPos.x < 0 || localPos.x > launcherLoader.width || localPos.y < 0 || localPos.y > launcherLoader.height)
|
||||||
localPos.y < 0 || localPos.y > launcherLoader.height) {
|
|
||||||
appDrawerPopout.hide();
|
appDrawerPopout.hide();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main launcher panel with asynchronous loading
|
// Main launcher panel with asynchronous loading
|
||||||
Loader {
|
Loader {
|
||||||
id: launcherLoader
|
id: launcherLoader
|
||||||
|
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
active: appDrawerPopout.isVisible
|
active: appDrawerPopout.isVisible
|
||||||
|
|
||||||
width: 520
|
width: 520
|
||||||
height: 600
|
height: 600
|
||||||
x: Theme.spacingL
|
x: Theme.spacingL
|
||||||
y: Theme.barHeight + Theme.spacingXS
|
y: Theme.barHeight + Theme.spacingXS
|
||||||
|
|
||||||
opacity: appDrawerPopout.isVisible ? 1 : 0
|
opacity: appDrawerPopout.isVisible ? 1 : 0
|
||||||
scale: appDrawerPopout.isVisible ? 1 : 0.9
|
scale: appDrawerPopout.isVisible ? 1 : 0.9
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Anims.durMed
|
duration: Anims.durMed
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
easing.bezierCurve: Anims.emphasized
|
easing.bezierCurve: Anims.emphasized
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Anims.durMed
|
duration: Anims.durMed
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
easing.bezierCurve: Anims.emphasized
|
easing.bezierCurve: Anims.emphasized
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceComponent: Rectangle {
|
sourceComponent: Rectangle {
|
||||||
id: launcherPanel
|
id: launcherPanel
|
||||||
|
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
radius: Theme.cornerRadiusXLarge
|
radius: Theme.cornerRadiusXLarge
|
||||||
|
|
||||||
// Remove layer rendering for better performance
|
// Remove layer rendering for better performance
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
smooth: true
|
smooth: true
|
||||||
@@ -146,13 +145,14 @@ PanelWindow {
|
|||||||
// Content with focus management
|
// Content with focus management
|
||||||
Item {
|
Item {
|
||||||
id: keyHandler
|
id: keyHandler
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
focus: true
|
focus: true
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (appDrawerPopout.isVisible)
|
if (appDrawerPopout.isVisible)
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle keyboard shortcuts
|
// Handle keyboard shortcuts
|
||||||
Keys.onPressed: function(event) {
|
Keys.onPressed: function(event) {
|
||||||
if (event.key === Qt.Key_Escape) {
|
if (event.key === Qt.Key_Escape) {
|
||||||
@@ -214,6 +214,7 @@ PanelWindow {
|
|||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced search field
|
// Enhanced search field
|
||||||
@@ -252,26 +253,25 @@ PanelWindow {
|
|||||||
event.accepted = false;
|
event.accepted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (appDrawerPopout.isVisible) {
|
if (appDrawerPopout.isVisible)
|
||||||
searchField.forceActiveFocus();
|
searchField.forceActiveFocus();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onIsVisibleChanged() {
|
function onIsVisibleChanged() {
|
||||||
if (appDrawerPopout.isVisible) {
|
if (appDrawerPopout.isVisible)
|
||||||
Qt.callLater(function() {
|
Qt.callLater(function() {
|
||||||
searchField.forceActiveFocus();
|
searchField.forceActiveFocus();
|
||||||
});
|
});
|
||||||
} else {
|
else
|
||||||
searchField.clearFocus();
|
searchField.clearFocus();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target: appDrawerPopout
|
target: appDrawerPopout
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Category filter and view mode controls
|
// Category filter and view mode controls
|
||||||
@@ -285,7 +285,7 @@ PanelWindow {
|
|||||||
Item {
|
Item {
|
||||||
width: 200
|
width: 200
|
||||||
height: 36
|
height: 36
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
text: ""
|
text: ""
|
||||||
@@ -296,6 +296,7 @@ PanelWindow {
|
|||||||
appLauncher.setCategory(value);
|
appLauncher.setCategory(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -335,7 +336,9 @@ PanelWindow {
|
|||||||
appLauncher.setViewMode("grid");
|
appLauncher.setViewMode("grid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// App grid/list container
|
// App grid/list container
|
||||||
@@ -399,10 +402,15 @@ PanelWindow {
|
|||||||
appLauncher.keyboardNavigationActive = false;
|
appLauncher.keyboardNavigationActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,62 +18,35 @@ Item {
|
|||||||
property bool debounceSearch: true
|
property bool debounceSearch: true
|
||||||
property int debounceInterval: 50
|
property int debounceInterval: 50
|
||||||
property bool keyboardNavigationActive: false
|
property bool keyboardNavigationActive: false
|
||||||
|
|
||||||
// Categories (computed from AppSearchService)
|
// Categories (computed from AppSearchService)
|
||||||
property var categories: {
|
property var categories: {
|
||||||
var allCategories = AppSearchService.getAllCategories().filter(cat => {
|
var allCategories = AppSearchService.getAllCategories().filter((cat) => {
|
||||||
return cat !== "Education" && cat !== "Science";
|
return cat !== "Education" && cat !== "Science";
|
||||||
});
|
});
|
||||||
var result = ["All"];
|
var result = ["All"];
|
||||||
return result.concat(allCategories.filter(cat => {
|
return result.concat(allCategories.filter((cat) => {
|
||||||
return cat !== "All";
|
return cat !== "All";
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Category icons (computed from AppSearchService)
|
// Category icons (computed from AppSearchService)
|
||||||
property var categoryIcons: categories.map(category => AppSearchService.getCategoryIcon(category))
|
property var categoryIcons: categories.map((category) => {
|
||||||
|
return AppSearchService.getCategoryIcon(category);
|
||||||
|
})
|
||||||
// App usage ranking helper
|
// App usage ranking helper
|
||||||
property var appUsageRanking: Prefs.appUsageRanking
|
property var appUsageRanking: Prefs.appUsageRanking
|
||||||
|
// Internal model
|
||||||
|
property alias model: filteredModel
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
signal appLaunched(var app)
|
signal appLaunched(var app)
|
||||||
signal categorySelected(string category)
|
signal categorySelected(string category)
|
||||||
signal viewModeSelected(string mode)
|
signal viewModeSelected(string mode)
|
||||||
|
|
||||||
// Internal model
|
|
||||||
property alias model: filteredModel
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: filteredModel
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search debouncing
|
|
||||||
Timer {
|
|
||||||
id: searchDebounceTimer
|
|
||||||
interval: root.debounceInterval
|
|
||||||
repeat: false
|
|
||||||
onTriggered: updateFilteredModel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch for changes
|
|
||||||
onSearchQueryChanged: {
|
|
||||||
if (debounceSearch) {
|
|
||||||
searchDebounceTimer.restart();
|
|
||||||
} else {
|
|
||||||
updateFilteredModel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onSelectedCategoryChanged: updateFilteredModel()
|
|
||||||
onAppUsageRankingChanged: updateFilteredModel()
|
|
||||||
|
|
||||||
function updateFilteredModel() {
|
function updateFilteredModel() {
|
||||||
filteredModel.clear();
|
filteredModel.clear();
|
||||||
selectedIndex = 0;
|
selectedIndex = 0;
|
||||||
keyboardNavigationActive = false;
|
keyboardNavigationActive = false;
|
||||||
|
|
||||||
var apps = [];
|
var apps = [];
|
||||||
|
|
||||||
if (searchQuery.length === 0) {
|
if (searchQuery.length === 0) {
|
||||||
// Show apps from category
|
// Show apps from category
|
||||||
if (selectedCategory === "All") {
|
if (selectedCategory === "All") {
|
||||||
@@ -90,8 +63,10 @@ Item {
|
|||||||
var categoryApps = AppSearchService.getAppsInCategory(selectedCategory);
|
var categoryApps = AppSearchService.getAppsInCategory(selectedCategory);
|
||||||
if (categoryApps.length > 0) {
|
if (categoryApps.length > 0) {
|
||||||
var allSearchResults = AppSearchService.searchApplications(searchQuery);
|
var allSearchResults = AppSearchService.searchApplications(searchQuery);
|
||||||
var categoryNames = new Set(categoryApps.map(app => app.name));
|
var categoryNames = new Set(categoryApps.map((app) => {
|
||||||
apps = allSearchResults.filter(searchApp => {
|
return app.name;
|
||||||
|
}));
|
||||||
|
apps = allSearchResults.filter((searchApp) => {
|
||||||
return categoryNames.has(searchApp.name);
|
return categoryNames.has(searchApp.name);
|
||||||
}).slice(0, maxResults);
|
}).slice(0, maxResults);
|
||||||
} else {
|
} else {
|
||||||
@@ -99,25 +74,20 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort apps by usage ranking, then alphabetically
|
// Sort apps by usage ranking, then alphabetically
|
||||||
apps = apps.sort(function(a, b) {
|
apps = apps.sort(function(a, b) {
|
||||||
var aId = a.id || (a.execString || a.exec || "");
|
var aId = a.id || (a.execString || a.exec || "");
|
||||||
var bId = b.id || (b.execString || b.exec || "");
|
var bId = b.id || (b.execString || b.exec || "");
|
||||||
|
|
||||||
var aUsage = appUsageRanking[aId] ? appUsageRanking[aId].usageCount : 0;
|
var aUsage = appUsageRanking[aId] ? appUsageRanking[aId].usageCount : 0;
|
||||||
var bUsage = appUsageRanking[bId] ? appUsageRanking[bId].usageCount : 0;
|
var bUsage = appUsageRanking[bId] ? appUsageRanking[bId].usageCount : 0;
|
||||||
|
if (aUsage !== bUsage)
|
||||||
if (aUsage !== bUsage) {
|
|
||||||
return bUsage - aUsage; // Higher usage first
|
return bUsage - aUsage; // Higher usage first
|
||||||
}
|
|
||||||
|
|
||||||
return (a.name || "").localeCompare(b.name || ""); // Alphabetical fallback
|
return (a.name || "").localeCompare(b.name || ""); // Alphabetical fallback
|
||||||
});
|
});
|
||||||
|
|
||||||
// Convert to model format and populate
|
// Convert to model format and populate
|
||||||
apps.forEach(app => {
|
apps.forEach((app) => {
|
||||||
if (app) {
|
if (app)
|
||||||
filteredModel.append({
|
filteredModel.append({
|
||||||
"name": app.name || "",
|
"name": app.name || "",
|
||||||
"exec": app.execString || "",
|
"exec": app.execString || "",
|
||||||
@@ -126,7 +96,7 @@ Item {
|
|||||||
"categories": app.categories || [],
|
"categories": app.categories || [],
|
||||||
"desktopEntry": app
|
"desktopEntry": app
|
||||||
});
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,9 +150,8 @@ Item {
|
|||||||
function launchApp(appData) {
|
function launchApp(appData) {
|
||||||
if (!appData) {
|
if (!appData) {
|
||||||
console.warn("AppLauncher: No app data provided");
|
console.warn("AppLauncher: No app data provided");
|
||||||
return;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
appData.desktopEntry.execute();
|
appData.desktopEntry.execute();
|
||||||
appLaunched(appData);
|
appLaunched(appData);
|
||||||
Prefs.addAppUsage(appData.desktopEntry);
|
Prefs.addAppUsage(appData.desktopEntry);
|
||||||
@@ -200,8 +169,31 @@ Item {
|
|||||||
viewModeSelected(mode);
|
viewModeSelected(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Watch for changes
|
||||||
|
onSearchQueryChanged: {
|
||||||
|
if (debounceSearch)
|
||||||
|
searchDebounceTimer.restart();
|
||||||
|
else
|
||||||
|
updateFilteredModel();
|
||||||
|
}
|
||||||
|
onSelectedCategoryChanged: updateFilteredModel()
|
||||||
|
onAppUsageRankingChanged: updateFilteredModel()
|
||||||
// Initialize
|
// Initialize
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
updateFilteredModel();
|
updateFilteredModel();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
ListModel {
|
||||||
|
id: filteredModel
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search debouncing
|
||||||
|
Timer {
|
||||||
|
id: searchDebounceTimer
|
||||||
|
|
||||||
|
interval: root.debounceInterval
|
||||||
|
repeat: false
|
||||||
|
onTriggered: updateFilteredModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,8 +48,11 @@ Item {
|
|||||||
categorySelected(modelData);
|
categorySelected(modelData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Two-row layout (for SpotlightModal organized style)
|
// Two-row layout (for SpotlightModal organized style)
|
||||||
@@ -66,7 +69,7 @@ Item {
|
|||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: parent.topRowCategories.filter(cat => {
|
model: parent.topRowCategories.filter((cat) => {
|
||||||
return categories.includes(cat);
|
return categories.includes(cat);
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -95,8 +98,11 @@ Item {
|
|||||||
categorySelected(modelData);
|
categorySelected(modelData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom row: Internet, Media, Office, Settings, System (5 items)
|
// Bottom row: Internet, Media, Office, Settings, System (5 items)
|
||||||
@@ -107,7 +113,7 @@ Item {
|
|||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: parent.bottomRowCategories.filter(cat => {
|
model: parent.bottomRowCategories.filter((cat) => {
|
||||||
return categories.includes(cat);
|
return categories.includes(cat);
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -136,8 +142,13 @@ Item {
|
|||||||
categorySelected(modelData);
|
categorySelected(modelData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import Quickshell.Services.Mpris
|
|||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
|
||||||
import qs.Modules.CentcomCenter
|
import qs.Modules.CentcomCenter
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: root
|
id: root
|
||||||
@@ -17,25 +17,25 @@ PanelWindow {
|
|||||||
property bool internalVisible: false
|
property bool internalVisible: false
|
||||||
|
|
||||||
visible: internalVisible
|
visible: internalVisible
|
||||||
|
|
||||||
onCalendarVisibleChanged: {
|
onCalendarVisibleChanged: {
|
||||||
if (calendarVisible) {
|
if (calendarVisible) {
|
||||||
internalVisible = true
|
internalVisible = true;
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
// This ensures opacity changes after window is visible
|
// This ensures opacity changes after window is visible
|
||||||
internalVisible = true // Force re-trigger if needed
|
internalVisible = true;
|
||||||
|
// Force re-trigger if needed
|
||||||
// Ensure events are loaded for current display month
|
// Ensure events are loaded for current display month
|
||||||
calendarGrid.loadEventsForMonth()
|
calendarGrid.loadEventsForMonth();
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
internalVisible = false
|
internalVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible && calendarGrid)
|
if (visible && calendarGrid)
|
||||||
calendarGrid.loadEventsForMonth();
|
calendarGrid.loadEventsForMonth();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: 480
|
implicitWidth: 480
|
||||||
implicitHeight: 600
|
implicitHeight: 600
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
@@ -53,6 +53,8 @@ PanelWindow {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: mainContainer
|
id: mainContainer
|
||||||
|
|
||||||
|
readonly property real targetWidth: Math.min(Screen.width * 0.9, 600)
|
||||||
|
|
||||||
function calculateWidth() {
|
function calculateWidth() {
|
||||||
let baseWidth = 320;
|
let baseWidth = 320;
|
||||||
if (leftWidgets.hasAnyWidgets)
|
if (leftWidgets.hasAnyWidgets)
|
||||||
@@ -80,7 +82,6 @@ PanelWindow {
|
|||||||
return Math.min(contentHeight, parent.height * 0.9);
|
return Math.min(contentHeight, parent.height * 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property real targetWidth: Math.min(Screen.width * 0.9, 600)
|
|
||||||
width: targetWidth
|
width: targetWidth
|
||||||
height: calculateHeight()
|
height: calculateHeight()
|
||||||
color: Theme.surfaceContainer
|
color: Theme.surfaceContainer
|
||||||
@@ -92,44 +93,27 @@ PanelWindow {
|
|||||||
scale: calendarVisible ? 1 : 0.9
|
scale: calendarVisible ? 1 : 0.9
|
||||||
x: (Screen.width - targetWidth) / 2
|
x: (Screen.width - targetWidth) / 2
|
||||||
y: Theme.barHeight + 4
|
y: Theme.barHeight + 4
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Anims.durMed
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Anims.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only resize after animation is complete
|
// Only resize after animation is complete
|
||||||
onOpacityChanged: {
|
onOpacityChanged: {
|
||||||
if (opacity === 1) {
|
if (opacity === 1)
|
||||||
// Animation finished, now we can safely resize
|
// Animation finished, now we can safely resize
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
height = calculateHeight();
|
height = calculateHeight();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onEventsByDateChanged() {
|
function onEventsByDateChanged() {
|
||||||
if (mainContainer.opacity === 1) {
|
if (mainContainer.opacity === 1)
|
||||||
mainContainer.height = mainContainer.calculateHeight();
|
mainContainer.height = mainContainer.calculateHeight();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKhalAvailableChanged() {
|
function onKhalAvailableChanged() {
|
||||||
if (mainContainer.opacity === 1) {
|
if (mainContainer.opacity === 1)
|
||||||
mainContainer.height = mainContainer.calculateHeight();
|
mainContainer.height = mainContainer.calculateHeight();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target: CalendarService
|
target: CalendarService
|
||||||
@@ -138,9 +122,9 @@ PanelWindow {
|
|||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onSelectedDateEventsChanged() {
|
function onSelectedDateEventsChanged() {
|
||||||
if (mainContainer.opacity === 1) {
|
if (mainContainer.opacity === 1)
|
||||||
mainContainer.height = mainContainer.calculateHeight();
|
mainContainer.height = mainContainer.calculateHeight();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target: events
|
target: events
|
||||||
@@ -172,8 +156,6 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
anchors.margins: Theme.spacingM
|
||||||
@@ -236,6 +218,24 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Anims.durMed
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Anims.emphasized
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Anims.durMed
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Anims.emphasized
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: true
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
@@ -245,8 +245,6 @@ PanelWindow {
|
|||||||
shadowOpacity: 0.15
|
shadowOpacity: 0.15
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -256,10 +254,9 @@ PanelWindow {
|
|||||||
onClicked: function(mouse) {
|
onClicked: function(mouse) {
|
||||||
// Only close if click is outside the main container
|
// Only close if click is outside the main container
|
||||||
var localPos = mapToItem(mainContainer, mouse.x, mouse.y);
|
var localPos = mapToItem(mainContainer, mouse.x, mouse.y);
|
||||||
if (localPos.x < 0 || localPos.x > mainContainer.width ||
|
if (localPos.x < 0 || localPos.x > mainContainer.width || localPos.y < 0 || localPos.y > mainContainer.height)
|
||||||
localPos.y < 0 || localPos.y > mainContainer.height) {
|
|
||||||
calendarVisible = false;
|
calendarVisible = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Rectangle {
|
|||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
|
|
||||||
Ref {
|
Ref {
|
||||||
service: WeatherService
|
service: WeatherService
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ PanelWindow {
|
|||||||
|
|
||||||
visible: notificationHistoryVisible
|
visible: notificationHistoryVisible
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
implicitHeight: Math.min(Screen.height * 0.60, Math.max(580, (notificationsList.contentHeight || 0) + 140))
|
implicitHeight: Math.min(Screen.height * 0.6, Math.max(580, (notificationsList.contentHeight || 0) + 140))
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
WlrLayershell.layer: WlrLayershell.Overlay
|
||||||
WlrLayershell.exclusiveZone: -1
|
WlrLayershell.exclusiveZone: -1
|
||||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
@@ -39,7 +39,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 400
|
width: 400
|
||||||
height: Math.min(Screen.height * 0.60, Math.max(580, (notificationsList.contentHeight || 0) + 140))
|
height: Math.min(Screen.height * 0.6, Math.max(580, (notificationsList.contentHeight || 0) + 140))
|
||||||
x: Screen.width - width - Theme.spacingL
|
x: Screen.width - width - Theme.spacingL
|
||||||
y: Theme.barHeight + Theme.spacingXS
|
y: Theme.barHeight + Theme.spacingXS
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
@@ -710,7 +710,6 @@ PanelWindow {
|
|||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
required property var modelData
|
required property var modelData
|
||||||
|
|
||||||
readonly property bool messageExpanded: NotificationService.expandedMessages[modelData.notification.id] || false
|
readonly property bool messageExpanded: NotificationService.expandedMessages[modelData.notification.id] || false
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -726,7 +725,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: messageIcon
|
id: messageIcon
|
||||||
|
|
||||||
readonly property bool hasNotificationImage: modelData.image && modelData.image !== ""
|
readonly property bool hasNotificationImage: modelData.image && modelData.image !== ""
|
||||||
|
|
||||||
width: 32
|
width: 32
|
||||||
@@ -830,7 +829,6 @@ PanelWindow {
|
|||||||
bodyText = bodyText.length > 500 ? bodyText.substring(0, 497) + "..." : bodyText;
|
bodyText = bodyText.length > 500 ? bodyText.substring(0, 497) + "..." : bodyText;
|
||||||
else
|
else
|
||||||
bodyText = bodyText.length > 80 ? bodyText.substring(0, 77) + "..." : bodyText;
|
bodyText = bodyText.length > 80 ? bodyText.substring(0, 77) + "..." : bodyText;
|
||||||
|
|
||||||
// Auto-detect and make URLs clickable
|
// Auto-detect and make URLs clickable
|
||||||
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
||||||
return bodyText.replace(urlRegex, '<a href="$1" style="color: ' + Theme.primary + '; text-decoration: underline;">$1</a>');
|
return bodyText.replace(urlRegex, '<a href="$1" style="color: ' + Theme.primary + '; text-decoration: underline;">$1</a>');
|
||||||
@@ -916,7 +914,6 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1114,6 +1111,7 @@ PanelWindow {
|
|||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ PanelWindow {
|
|||||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
implicitHeight: Math.min(Screen.height * 0.60, Math.max(400, (notificationsList.contentHeight || 0) + 32))
|
implicitHeight: Math.min(Screen.height * 0.6, Math.max(400, (notificationsList.contentHeight || 0) + 32))
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
top: true
|
top: true
|
||||||
@@ -35,18 +35,11 @@ PanelWindow {
|
|||||||
anchors.rightMargin: 16
|
anchors.rightMargin: 16
|
||||||
anchors.bottomMargin: 16
|
anchors.bottomMargin: 16
|
||||||
width: 380
|
width: 380
|
||||||
height: Math.min(Screen.height * 0.60 - 32, Math.max(368, (notificationsList.contentHeight || 0) + 32))
|
height: Math.min(Screen.height * 0.6 - 32, Math.max(368, (notificationsList.contentHeight || 0) + 32))
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
radius: 12
|
radius: 12
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
@@ -607,6 +600,7 @@ PanelWindow {
|
|||||||
// Body text with expand capability
|
// Body text with expand capability
|
||||||
Text {
|
Text {
|
||||||
id: bodyText
|
id: bodyText
|
||||||
|
|
||||||
property bool hasUrls: {
|
property bool hasUrls: {
|
||||||
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
||||||
return urlRegex.test(modelData.body || "");
|
return urlRegex.test(modelData.body || "");
|
||||||
@@ -908,6 +902,14 @@ PanelWindow {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on height {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
Behavior on implicitHeight {
|
||||||
|
|||||||
@@ -7,18 +7,19 @@ import qs.Widgets
|
|||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
id: appearanceTab
|
id: appearanceTab
|
||||||
|
|
||||||
contentWidth: availableWidth
|
contentWidth: availableWidth
|
||||||
contentHeight: column.implicitHeight + Theme.spacingXL
|
contentHeight: column.implicitHeight + Theme.spacingXL
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: column
|
id: column
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingXL
|
spacing: Theme.spacingXL
|
||||||
topPadding: Theme.spacingL
|
topPadding: Theme.spacingL
|
||||||
bottomPadding: Theme.spacingXL
|
bottomPadding: Theme.spacingXL
|
||||||
|
|
||||||
// Display Settings Section
|
// Display Settings Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -27,24 +28,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: displaySection
|
id: displaySection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "monitor"
|
name: "monitor"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Display Settings"
|
text: "Display Settings"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -52,8 +54,9 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Night Mode"
|
text: "Night Mode"
|
||||||
@@ -67,7 +70,7 @@ ScrollView {
|
|||||||
nightModeDisableProcess.running = true;
|
nightModeDisableProcess.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Light Mode"
|
text: "Light Mode"
|
||||||
@@ -78,7 +81,7 @@ ScrollView {
|
|||||||
Theme.isLightMode = checked;
|
Theme.isLightMode = checked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Icon Theme"
|
text: "Icon Theme"
|
||||||
@@ -89,9 +92,11 @@ ScrollView {
|
|||||||
Prefs.setIconTheme(value);
|
Prefs.setIconTheme(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transparency Settings Section
|
// Transparency Settings Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -100,24 +105,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: transparencySection
|
id: transparencySection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "opacity"
|
name: "opacity"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Transparency Settings"
|
text: "Transparency Settings"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -125,19 +131,20 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Top Bar Transparency"
|
text: "Top Bar Transparency"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
}
|
}
|
||||||
|
|
||||||
DankSlider {
|
DankSlider {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 24
|
height: 24
|
||||||
@@ -150,19 +157,20 @@ ScrollView {
|
|||||||
Prefs.setTopBarTransparency(newValue / 100);
|
Prefs.setTopBarTransparency(newValue / 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Popup Transparency"
|
text: "Popup Transparency"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
}
|
}
|
||||||
|
|
||||||
DankSlider {
|
DankSlider {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 24
|
height: 24
|
||||||
@@ -175,10 +183,13 @@ ScrollView {
|
|||||||
Prefs.setPopupTransparency(newValue / 100);
|
Prefs.setPopupTransparency(newValue / 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Theme Picker Section
|
// Theme Picker Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -187,24 +198,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: themeSection
|
id: themeSection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "palette"
|
name: "palette"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Theme Color"
|
text: "Theme Color"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -212,12 +224,13 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Current Theme: " + (Theme.isDynamicTheme ? "Auto" : (Theme.currentThemeIndex < Theme.themes.length ? Theme.themes[Theme.currentThemeIndex].name : "Blue"))
|
text: "Current Theme: " + (Theme.isDynamicTheme ? "Auto" : (Theme.currentThemeIndex < Theme.themes.length ? Theme.themes[Theme.currentThemeIndex].name : "Blue"))
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
@@ -225,12 +238,12 @@ ScrollView {
|
|||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
if (Theme.isDynamicTheme)
|
if (Theme.isDynamicTheme)
|
||||||
return "Wallpaper-based dynamic colors";
|
return "Wallpaper-based dynamic colors";
|
||||||
|
|
||||||
var descriptions = ["Material blue inspired by modern interfaces", "Deep blue inspired by material 3", "Rich purple tones for BB elegance", "Natural green for productivity", "Energetic orange for creativity", "Bold red for impact", "Cool cyan for tranquility", "Vibrant pink for expression", "Warm amber for comfort", "Soft coral for gentle warmth"];
|
var descriptions = ["Material blue inspired by modern interfaces", "Deep blue inspired by material 3", "Rich purple tones for BB elegance", "Natural green for productivity", "Energetic orange for creativity", "Bold red for impact", "Cool cyan for tranquility", "Vibrant pink for expression", "Warm amber for comfort", "Soft coral for gentle warmth"];
|
||||||
return descriptions[Theme.currentThemeIndex] || "Select a theme";
|
return descriptions[Theme.currentThemeIndex] || "Select a theme";
|
||||||
}
|
}
|
||||||
@@ -241,21 +254,22 @@ ScrollView {
|
|||||||
width: Math.min(parent.width, 400)
|
width: Math.min(parent.width, 400)
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Theme Grid
|
// Theme Grid
|
||||||
Column {
|
Column {
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
// First row - Blue, Deep Blue, Purple, Green, Orange
|
// First row - Blue, Deep Blue, Purple, Green, Orange
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: 5
|
model: 5
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 32
|
width: 32
|
||||||
height: 32
|
height: 32
|
||||||
@@ -264,7 +278,7 @@ ScrollView {
|
|||||||
border.color: Theme.outline
|
border.color: Theme.outline
|
||||||
border.width: (Theme.currentThemeIndex === index && !Theme.isDynamicTheme) ? 2 : 1
|
border.width: (Theme.currentThemeIndex === index && !Theme.isDynamicTheme) ? 2 : 1
|
||||||
scale: (Theme.currentThemeIndex === index && !Theme.isDynamicTheme) ? 1.1 : 1
|
scale: (Theme.currentThemeIndex === index && !Theme.isDynamicTheme) ? 1.1 : 1
|
||||||
|
|
||||||
// Theme name tooltip
|
// Theme name tooltip
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: nameText.contentWidth + Theme.spacingS * 2
|
width: nameText.contentWidth + Theme.spacingS * 2
|
||||||
@@ -277,18 +291,21 @@ ScrollView {
|
|||||||
anchors.bottomMargin: Theme.spacingXS
|
anchors.bottomMargin: Theme.spacingXS
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: mouseArea.containsMouse
|
visible: mouseArea.containsMouse
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: nameText
|
id: nameText
|
||||||
|
|
||||||
text: Theme.themes[index].name
|
text: Theme.themes[index].name
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -296,35 +313,40 @@ ScrollView {
|
|||||||
Theme.switchTheme(index, false);
|
Theme.switchTheme(index, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on border.width {
|
Behavior on border.width {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second row - Red, Cyan, Pink, Amber, Coral
|
// Second row - Red, Cyan, Pink, Amber, Coral
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: 5
|
model: 5
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
property int themeIndex: index + 5
|
property int themeIndex: index + 5
|
||||||
|
|
||||||
width: 32
|
width: 32
|
||||||
height: 32
|
height: 32
|
||||||
radius: 16
|
radius: 16
|
||||||
@@ -333,7 +355,7 @@ ScrollView {
|
|||||||
border.width: Theme.currentThemeIndex === themeIndex ? 2 : 1
|
border.width: Theme.currentThemeIndex === themeIndex ? 2 : 1
|
||||||
visible: themeIndex < Theme.themes.length
|
visible: themeIndex < Theme.themes.length
|
||||||
scale: Theme.currentThemeIndex === themeIndex ? 1.1 : 1
|
scale: Theme.currentThemeIndex === themeIndex ? 1.1 : 1
|
||||||
|
|
||||||
// Theme name tooltip
|
// Theme name tooltip
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: nameText2.contentWidth + Theme.spacingS * 2
|
width: nameText2.contentWidth + Theme.spacingS * 2
|
||||||
@@ -346,50 +368,59 @@ ScrollView {
|
|||||||
anchors.bottomMargin: Theme.spacingXS
|
anchors.bottomMargin: Theme.spacingXS
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: mouseArea2.containsMouse && themeIndex < Theme.themes.length
|
visible: mouseArea2.containsMouse && themeIndex < Theme.themes.length
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: nameText2
|
id: nameText2
|
||||||
|
|
||||||
text: themeIndex < Theme.themes.length ? Theme.themes[themeIndex].name : ""
|
text: themeIndex < Theme.themes.length ? Theme.themes[themeIndex].name : ""
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea2
|
id: mouseArea2
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (themeIndex < Theme.themes.length)
|
if (themeIndex < Theme.themes.length)
|
||||||
Theme.switchTheme(themeIndex);
|
Theme.switchTheme(themeIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on border.width {
|
Behavior on border.width {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spacer
|
// Spacer
|
||||||
Item {
|
Item {
|
||||||
width: 1
|
width: 1
|
||||||
height: Theme.spacingM
|
height: Theme.spacingM
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto theme button
|
// Auto theme button
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 120
|
width: 120
|
||||||
@@ -412,11 +443,11 @@ ScrollView {
|
|||||||
}
|
}
|
||||||
border.width: Theme.isDynamicTheme ? 2 : 1
|
border.width: Theme.isDynamicTheme ? 2 : 1
|
||||||
scale: Theme.isDynamicTheme ? 1.1 : (autoMouseArea.containsMouse ? 1.02 : 1)
|
scale: Theme.isDynamicTheme ? 1.1 : (autoMouseArea.containsMouse ? 1.02 : 1)
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: {
|
name: {
|
||||||
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
|
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
|
||||||
@@ -433,7 +464,7 @@ ScrollView {
|
|||||||
}
|
}
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
if (ToastService.wallpaperErrorStatus === "error")
|
if (ToastService.wallpaperErrorStatus === "error")
|
||||||
@@ -453,24 +484,25 @@ ScrollView {
|
|||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: autoMouseArea
|
id: autoMouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (ToastService.wallpaperErrorStatus === "matugen_missing") {
|
if (ToastService.wallpaperErrorStatus === "matugen_missing")
|
||||||
ToastService.showError("matugen not found - install matugen package for dynamic theming");
|
ToastService.showError("matugen not found - install matugen package for dynamic theming");
|
||||||
} else if (ToastService.wallpaperErrorStatus === "error") {
|
else if (ToastService.wallpaperErrorStatus === "error")
|
||||||
ToastService.showError("Wallpaper processing failed - check wallpaper path");
|
ToastService.showError("Wallpaper processing failed - check wallpaper path");
|
||||||
} else {
|
else
|
||||||
Theme.switchTheme(10, true);
|
Theme.switchTheme(10, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tooltip for Auto button
|
// Tooltip for Auto button
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: autoTooltipText.contentWidth + Theme.spacingM * 2
|
width: autoTooltipText.contentWidth + Theme.spacingM * 2
|
||||||
@@ -483,9 +515,10 @@ ScrollView {
|
|||||||
anchors.bottomMargin: Theme.spacingS
|
anchors.bottomMargin: Theme.spacingS
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: autoMouseArea.containsMouse && (!Theme.isDynamicTheme || ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
|
visible: autoMouseArea.containsMouse && (!Theme.isDynamicTheme || ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: autoTooltipText
|
id: autoTooltipText
|
||||||
|
|
||||||
text: {
|
text: {
|
||||||
if (ToastService.wallpaperErrorStatus === "error")
|
if (ToastService.wallpaperErrorStatus === "error")
|
||||||
return "Wallpaper symlink missing at ~/quickshell/current_wallpaper";
|
return "Wallpaper symlink missing at ~/quickshell/current_wallpaper";
|
||||||
@@ -501,37 +534,47 @@ ScrollView {
|
|||||||
width: Math.min(implicitWidth, 250)
|
width: Math.min(implicitWidth, 250)
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on border.color {
|
Behavior on border.color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Night mode processes
|
// Night mode processes
|
||||||
Process {
|
Process {
|
||||||
id: nightModeEnableProcess
|
id: nightModeEnableProcess
|
||||||
|
|
||||||
command: ["bash", "-c", "if command -v wlsunset > /dev/null; then pkill wlsunset; wlsunset -t 3000 & elif command -v redshift > /dev/null; then pkill redshift; redshift -P -O 3000 & else echo 'No night mode tool available'; fi"]
|
command: ["bash", "-c", "if command -v wlsunset > /dev/null; then pkill wlsunset; wlsunset -t 3000 & elif command -v redshift > /dev/null; then pkill redshift; redshift -P -O 3000 & else echo 'No night mode tool available'; fi"]
|
||||||
running: false
|
running: false
|
||||||
onExited: (exitCode) => {
|
onExited: (exitCode) => {
|
||||||
@@ -541,14 +584,17 @@ ScrollView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: nightModeDisableProcess
|
id: nightModeDisableProcess
|
||||||
|
|
||||||
command: ["bash", "-c", "pkill wlsunset; pkill redshift; if command -v wlsunset > /dev/null; then wlsunset -t 6500 -T 6500 & sleep 1; pkill wlsunset; elif command -v redshift > /dev/null; then redshift -P -O 6500; redshift -x; fi"]
|
command: ["bash", "-c", "pkill wlsunset; pkill redshift; if command -v wlsunset > /dev/null; then wlsunset -t 6500 -T 6500 & sleep 1; pkill wlsunset; elif command -v redshift > /dev/null; then redshift -P -O 6500; redshift -x; fi"]
|
||||||
running: false
|
running: false
|
||||||
onExited: (exitCode) => {
|
onExited: (exitCode) => {
|
||||||
if (exitCode !== 0)
|
if (exitCode !== 0)
|
||||||
console.warn("Failed to disable night mode");
|
console.warn("Failed to disable night mode");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -296,18 +296,26 @@ ScrollView {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
if (!modelData.lastUsed) return "Never used";
|
if (!modelData.lastUsed)
|
||||||
|
return "Never used";
|
||||||
|
|
||||||
var date = new Date(modelData.lastUsed);
|
var date = new Date(modelData.lastUsed);
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
var diffMs = now - date;
|
var diffMs = now - date;
|
||||||
var diffMins = Math.floor(diffMs / (1000 * 60));
|
var diffMins = Math.floor(diffMs / (1000 * 60));
|
||||||
var diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
var diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
||||||
var diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
var diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
||||||
|
if (diffMins < 1)
|
||||||
if (diffMins < 1) return "Last launched just now";
|
return "Last launched just now";
|
||||||
if (diffMins < 60) return "Last launched " + diffMins + " minute" + (diffMins === 1 ? "" : "s") + " ago";
|
|
||||||
if (diffHours < 24) return "Last launched " + diffHours + " hour" + (diffHours === 1 ? "" : "s") + " ago";
|
if (diffMins < 60)
|
||||||
if (diffDays < 7) return "Last launched " + diffDays + " day" + (diffDays === 1 ? "" : "s") + " ago";
|
return "Last launched " + diffMins + " minute" + (diffMins === 1 ? "" : "s") + " ago";
|
||||||
|
|
||||||
|
if (diffHours < 24)
|
||||||
|
return "Last launched " + diffHours + " hour" + (diffHours === 1 ? "" : "s") + " ago";
|
||||||
|
|
||||||
|
if (diffDays < 7)
|
||||||
|
return "Last launched " + diffDays + " day" + (diffDays === 1 ? "" : "s") + " ago";
|
||||||
|
|
||||||
return "Last launched " + date.toLocaleDateString();
|
return "Last launched " + date.toLocaleDateString();
|
||||||
}
|
}
|
||||||
@@ -329,7 +337,8 @@ ScrollView {
|
|||||||
iconColor: Theme.error
|
iconColor: Theme.error
|
||||||
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var currentRanking = Object.assign({}, Prefs.appUsageRanking);
|
var currentRanking = Object.assign({
|
||||||
|
}, Prefs.appUsageRanking);
|
||||||
delete currentRanking[modelData.id];
|
delete currentRanking[modelData.id];
|
||||||
Prefs.appUsageRanking = currentRanking;
|
Prefs.appUsageRanking = currentRanking;
|
||||||
Prefs.saveSettings();
|
Prefs.saveSettings();
|
||||||
|
|||||||
@@ -3,22 +3,26 @@ import QtQuick.Controls
|
|||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modals
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
import qs.Modals
|
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
id: personalizationTab
|
id: personalizationTab
|
||||||
|
|
||||||
|
property alias profileBrowser: profileBrowserLoader.item
|
||||||
|
property alias wallpaperBrowser: wallpaperBrowserLoader.item
|
||||||
|
|
||||||
contentWidth: availableWidth
|
contentWidth: availableWidth
|
||||||
contentHeight: column.implicitHeight
|
contentHeight: column.implicitHeight
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: column
|
id: column
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingXL
|
spacing: Theme.spacingXL
|
||||||
|
|
||||||
// Profile Section
|
// Profile Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -27,24 +31,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: profileSection
|
id: profileSection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "person"
|
name: "person"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Profile Image"
|
text: "Profile Image"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -52,21 +57,22 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingL
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
// Circular profile image preview
|
// Circular profile image preview
|
||||||
Item {
|
Item {
|
||||||
id: avatarContainer
|
id: avatarContainer
|
||||||
|
|
||||||
property bool hasImage: avatarImageSource.status === Image.Ready
|
property bool hasImage: avatarImageSource.status === Image.Ready
|
||||||
|
|
||||||
width: 80
|
width: 80
|
||||||
height: 80
|
height: 80
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
@@ -75,17 +81,17 @@ ScrollView {
|
|||||||
border.width: 1
|
border.width: 1
|
||||||
visible: parent.hasImage
|
visible: parent.hasImage
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: avatarImageSource
|
id: avatarImageSource
|
||||||
|
|
||||||
source: {
|
source: {
|
||||||
if (Prefs.profileImage === "")
|
if (Prefs.profileImage === "")
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
if (Prefs.profileImage.startsWith("/"))
|
if (Prefs.profileImage.startsWith("/"))
|
||||||
return "file://" + Prefs.profileImage;
|
return "file://" + Prefs.profileImage;
|
||||||
|
|
||||||
return Prefs.profileImage;
|
return Prefs.profileImage;
|
||||||
}
|
}
|
||||||
smooth: true
|
smooth: true
|
||||||
@@ -94,7 +100,7 @@ ScrollView {
|
|||||||
cache: true
|
cache: true
|
||||||
visible: false
|
visible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiEffect {
|
MultiEffect {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 5
|
anchors.margins: 5
|
||||||
@@ -105,38 +111,40 @@ ScrollView {
|
|||||||
maskThresholdMin: 0.5
|
maskThresholdMin: 0.5
|
||||||
maskSpreadAtMin: 1
|
maskSpreadAtMin: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: settingsCircularMask
|
id: settingsCircularMask
|
||||||
|
|
||||||
width: 70
|
width: 70
|
||||||
height: 70
|
height: 70
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.smooth: true
|
layer.smooth: true
|
||||||
visible: false
|
visible: false
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
color: "black"
|
color: "black"
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
visible: !parent.hasImage
|
visible: !parent.hasImage
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
name: "person"
|
name: "person"
|
||||||
size: Theme.iconSizeLarge + 8
|
size: Theme.iconSizeLarge + 8
|
||||||
color: Theme.primaryText
|
color: Theme.primaryText
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
name: "warning"
|
name: "warning"
|
||||||
@@ -144,13 +152,14 @@ ScrollView {
|
|||||||
color: Theme.error
|
color: Theme.error
|
||||||
visible: Prefs.profileImage !== "" && avatarImageSource.status === Image.Error
|
visible: Prefs.profileImage !== "" && avatarImageSource.status === Image.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width - 80 - Theme.spacingL
|
width: parent.width - 80 - Theme.spacingL
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Prefs.profileImage ? Prefs.profileImage.split('/').pop() : "No profile image selected"
|
text: Prefs.profileImage ? Prefs.profileImage.split('/').pop() : "No profile image selected"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -158,7 +167,7 @@ ScrollView {
|
|||||||
elide: Text.ElideMiddle
|
elide: Text.ElideMiddle
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Prefs.profileImage ? Prefs.profileImage : ""
|
text: Prefs.profileImage ? Prefs.profileImage : ""
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -167,35 +176,36 @@ ScrollView {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
visible: Prefs.profileImage !== ""
|
visible: Prefs.profileImage !== ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: 100
|
width: 100
|
||||||
height: 32
|
height: 32
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "folder_open"
|
name: "folder_open"
|
||||||
size: Theme.iconSizeSmall
|
size: Theme.iconSizeSmall
|
||||||
color: Theme.primaryText
|
color: Theme.primaryText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Browse"
|
text: "Browse"
|
||||||
color: Theme.primaryText
|
color: Theme.primaryText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -204,34 +214,36 @@ ScrollView {
|
|||||||
profileBrowser.visible = true;
|
profileBrowser.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: 80
|
width: 80
|
||||||
height: 32
|
height: 32
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceVariant
|
color: Theme.surfaceVariant
|
||||||
opacity: Prefs.profileImage !== "" ? 1.0 : 0.5
|
opacity: Prefs.profileImage !== "" ? 1 : 0.5
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "clear"
|
name: "clear"
|
||||||
size: Theme.iconSizeSmall
|
size: Theme.iconSizeSmall
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Clear"
|
text: "Clear"
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: Prefs.profileImage !== ""
|
enabled: Prefs.profileImage !== ""
|
||||||
@@ -240,13 +252,19 @@ ScrollView {
|
|||||||
Prefs.setProfileImage("");
|
Prefs.setProfileImage("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wallpaper Section
|
// Wallpaper Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -255,24 +273,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: wallpaperSection
|
id: wallpaperSection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "wallpaper"
|
name: "wallpaper"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Wallpaper"
|
text: "Wallpaper"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -280,12 +299,13 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingL
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
// Wallpaper Preview
|
// Wallpaper Preview
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: 160
|
width: 160
|
||||||
@@ -294,7 +314,7 @@ ScrollView {
|
|||||||
color: Theme.surfaceVariant
|
color: Theme.surfaceVariant
|
||||||
border.color: Theme.outline
|
border.color: Theme.outline
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
CachingImage {
|
CachingImage {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 1
|
anchors.margins: 1
|
||||||
@@ -303,16 +323,19 @@ ScrollView {
|
|||||||
visible: Prefs.wallpaperPath !== ""
|
visible: Prefs.wallpaperPath !== ""
|
||||||
maxCacheSize: 160
|
maxCacheSize: 160
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
|
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
maskEnabled: true
|
maskEnabled: true
|
||||||
maskSource: wallpaperMask
|
maskSource: wallpaperMask
|
||||||
maskThresholdMin: 0.5
|
maskThresholdMin: 0.5
|
||||||
maskSpreadAtMin: 1.0
|
maskSpreadAtMin: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: wallpaperMask
|
id: wallpaperMask
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 1
|
anchors.margins: 1
|
||||||
radius: Theme.cornerRadius - 1
|
radius: Theme.cornerRadius - 1
|
||||||
@@ -320,7 +343,7 @@ ScrollView {
|
|||||||
visible: false
|
visible: false
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
name: "image"
|
name: "image"
|
||||||
@@ -328,13 +351,14 @@ ScrollView {
|
|||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
visible: Prefs.wallpaperPath === ""
|
visible: Prefs.wallpaperPath === ""
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width - 160 - Theme.spacingL
|
width: parent.width - 160 - Theme.spacingL
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Prefs.wallpaperPath ? Prefs.wallpaperPath.split('/').pop() : "No wallpaper selected"
|
text: Prefs.wallpaperPath ? Prefs.wallpaperPath.split('/').pop() : "No wallpaper selected"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -342,7 +366,7 @@ ScrollView {
|
|||||||
elide: Text.ElideMiddle
|
elide: Text.ElideMiddle
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: Prefs.wallpaperPath ? Prefs.wallpaperPath : ""
|
text: Prefs.wallpaperPath ? Prefs.wallpaperPath : ""
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -351,35 +375,36 @@ ScrollView {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
visible: Prefs.wallpaperPath !== ""
|
visible: Prefs.wallpaperPath !== ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: 100
|
width: 100
|
||||||
height: 32
|
height: 32
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "folder_open"
|
name: "folder_open"
|
||||||
size: Theme.iconSizeSmall
|
size: Theme.iconSizeSmall
|
||||||
color: Theme.primaryText
|
color: Theme.primaryText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Browse"
|
text: "Browse"
|
||||||
color: Theme.primaryText
|
color: Theme.primaryText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -388,34 +413,36 @@ ScrollView {
|
|||||||
wallpaperBrowser.visible = true;
|
wallpaperBrowser.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: 80
|
width: 80
|
||||||
height: 32
|
height: 32
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceVariant
|
color: Theme.surfaceVariant
|
||||||
opacity: Prefs.wallpaperPath !== "" ? 1.0 : 0.5
|
opacity: Prefs.wallpaperPath !== "" ? 1 : 0.5
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "clear"
|
name: "clear"
|
||||||
size: Theme.iconSizeSmall
|
size: Theme.iconSizeSmall
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Clear"
|
text: "Clear"
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: Prefs.wallpaperPath !== ""
|
enabled: Prefs.wallpaperPath !== ""
|
||||||
@@ -424,13 +451,19 @@ ScrollView {
|
|||||||
Prefs.setWallpaperPath("");
|
Prefs.setWallpaperPath("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic Theming Section
|
// Dynamic Theming Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -439,36 +472,37 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: dynamicThemeSection
|
id: dynamicThemeSection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "palette"
|
name: "palette"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width - Theme.iconSize - Theme.spacingM - toggle.width - Theme.spacingM
|
width: parent.width - Theme.iconSize - Theme.spacingM - toggle.width - Theme.spacingM
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Dynamic Theming"
|
text: "Dynamic Theming"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Automatically extract colors from wallpaper"
|
text: "Automatically extract colors from wallpaper"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -476,23 +510,25 @@ ScrollView {
|
|||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
id: toggle
|
id: toggle
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
checked: Theme.isDynamicTheme
|
checked: Theme.isDynamicTheme
|
||||||
enabled: ToastService.wallpaperErrorStatus !== "matugen_missing"
|
enabled: ToastService.wallpaperErrorStatus !== "matugen_missing"
|
||||||
onToggled: (toggled) => {
|
onToggled: (toggled) => {
|
||||||
if (toggled) {
|
if (toggled)
|
||||||
Theme.switchTheme(10, true)
|
Theme.switchTheme(10, true);
|
||||||
} else {
|
else
|
||||||
Theme.switchTheme(0)
|
Theme.switchTheme(0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "matugen not detected - dynamic theming unavailable"
|
text: "matugen not detected - dynamic theming unavailable"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -501,16 +537,21 @@ ScrollView {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
leftPadding: Theme.iconSize + Theme.spacingM
|
leftPadding: Theme.iconSize + Theme.spacingM
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: profileBrowserLoader
|
id: profileBrowserLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
FileBrowserModal {
|
FileBrowserModal {
|
||||||
id: profileBrowser
|
id: profileBrowser
|
||||||
|
|
||||||
browserTitle: "Select Profile Image"
|
browserTitle: "Select Profile Image"
|
||||||
browserIcon: "person"
|
browserIcon: "person"
|
||||||
browserType: "profile"
|
browserType: "profile"
|
||||||
@@ -520,14 +561,17 @@ ScrollView {
|
|||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: wallpaperBrowserLoader
|
id: wallpaperBrowserLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
FileBrowserModal {
|
FileBrowserModal {
|
||||||
id: wallpaperBrowser
|
id: wallpaperBrowser
|
||||||
|
|
||||||
browserTitle: "Select Wallpaper"
|
browserTitle: "Select Wallpaper"
|
||||||
browserIcon: "wallpaper"
|
browserIcon: "wallpaper"
|
||||||
browserType: "wallpaper"
|
browserType: "wallpaper"
|
||||||
@@ -537,8 +581,7 @@ ScrollView {
|
|||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property alias profileBrowser: profileBrowserLoader.item
|
}
|
||||||
property alias wallpaperBrowser: wallpaperBrowserLoader.item
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ Column {
|
|||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: expanded ? Theme.spacingM : 0
|
spacing: expanded ? Theme.spacingM : 0
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (!collapsible)
|
||||||
|
expanded = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Section header
|
// Section header
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -23,7 +28,12 @@ Column {
|
|||||||
height: headerRow.height
|
height: headerRow.height
|
||||||
enabled: collapsible
|
enabled: collapsible
|
||||||
hoverEnabled: collapsible
|
hoverEnabled: collapsible
|
||||||
|
onClicked: {
|
||||||
|
if (collapsible)
|
||||||
|
expanded = !expanded;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: parent.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
|
color: parent.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
|
||||||
@@ -32,7 +42,7 @@ Column {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: headerRow
|
id: headerRow
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
topPadding: Theme.spacingS
|
topPadding: Theme.spacingS
|
||||||
@@ -43,14 +53,16 @@ Column {
|
|||||||
size: Theme.iconSize - 2
|
size: Theme.iconSize - 2
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
Behavior on rotation {
|
Behavior on rotation {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Appearance.anim.durations.fast
|
duration: Appearance.anim.durations.fast
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
easing.bezierCurve: Appearance.anim.curves.standard
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
@@ -68,13 +80,9 @@ Column {
|
|||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
if (collapsible) {
|
|
||||||
expanded = !expanded
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Divider
|
// Divider
|
||||||
@@ -93,21 +101,17 @@ Column {
|
|||||||
active: lazyLoad ? expanded || !collapsible : true
|
active: lazyLoad ? expanded || !collapsible : true
|
||||||
visible: expanded || !collapsible
|
visible: expanded || !collapsible
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Appearance.anim.durations.normal
|
duration: Appearance.anim.durations.normal
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
easing.bezierCurve: Appearance.anim.curves.standard
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opacity: visible ? 1 : 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (!collapsible) {
|
|
||||||
expanded = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,17 @@ import qs.Widgets
|
|||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
id: timeWeatherTab
|
id: timeWeatherTab
|
||||||
|
|
||||||
contentWidth: availableWidth
|
contentWidth: availableWidth
|
||||||
contentHeight: column.implicitHeight
|
contentHeight: column.implicitHeight
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: column
|
id: column
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingXL
|
spacing: Theme.spacingXL
|
||||||
|
|
||||||
// Time Settings Section
|
// Time Settings Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -23,24 +24,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: timeSection
|
id: timeSection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "schedule"
|
name: "schedule"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Time Format"
|
text: "Time Format"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -48,8 +50,9 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "24-Hour Format"
|
text: "24-Hour Format"
|
||||||
@@ -59,9 +62,11 @@ ScrollView {
|
|||||||
return Prefs.setClockFormat(checked);
|
return Prefs.setClockFormat(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Weather Settings Section
|
// Weather Settings Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -70,24 +75,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: weatherSection
|
id: weatherSection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "cloud"
|
name: "cloud"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Weather"
|
text: "Weather"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -95,8 +101,9 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Fahrenheit"
|
text: "Fahrenheit"
|
||||||
@@ -106,7 +113,7 @@ ScrollView {
|
|||||||
return Prefs.setTemperatureUnit(checked);
|
return Prefs.setTemperatureUnit(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Override Location"
|
text: "Override Location"
|
||||||
@@ -116,21 +123,21 @@ ScrollView {
|
|||||||
return Prefs.setWeatherLocationOverrideEnabled(checked);
|
return Prefs.setWeatherLocationOverrideEnabled(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Location input - only visible when override is enabled
|
// Location input - only visible when override is enabled
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
visible: Prefs.weatherLocationOverrideEnabled
|
visible: Prefs.weatherLocationOverrideEnabled
|
||||||
opacity: visible ? 1 : 0
|
opacity: visible ? 1 : 0
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Location"
|
text: "Location"
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
}
|
}
|
||||||
|
|
||||||
DankLocationSearch {
|
DankLocationSearch {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
currentLocation: Prefs.weatherLocationOverride
|
currentLocation: Prefs.weatherLocationOverride
|
||||||
@@ -139,7 +146,7 @@ ScrollView {
|
|||||||
Prefs.setWeatherLocationOverride(coordinates);
|
Prefs.setWeatherLocationOverride(coordinates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Examples: \"New York\", \"Tokyo\", \"90210\""
|
text: "Examples: \"New York\", \"Tokyo\", \"90210\""
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
@@ -147,15 +154,21 @@ ScrollView {
|
|||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.mediumDuration
|
duration: Theme.mediumDuration
|
||||||
easing.type: Theme.emphasizedEasing
|
easing.type: Theme.emphasizedEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,18 +5,19 @@ import qs.Widgets
|
|||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
id: widgetsTab
|
id: widgetsTab
|
||||||
|
|
||||||
contentWidth: availableWidth
|
contentWidth: availableWidth
|
||||||
contentHeight: column.implicitHeight + Theme.spacingXL
|
contentHeight: column.implicitHeight + Theme.spacingXL
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: column
|
id: column
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingXL
|
spacing: Theme.spacingXL
|
||||||
topPadding: Theme.spacingL
|
topPadding: Theme.spacingL
|
||||||
bottomPadding: Theme.spacingXL
|
bottomPadding: Theme.spacingXL
|
||||||
|
|
||||||
// Top Bar Widgets Section
|
// Top Bar Widgets Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -25,24 +26,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: topBarSection
|
id: topBarSection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "widgets"
|
name: "widgets"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Top Bar Widgets"
|
text: "Top Bar Widgets"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -50,8 +52,9 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Focused Window"
|
text: "Focused Window"
|
||||||
@@ -61,7 +64,7 @@ ScrollView {
|
|||||||
return Prefs.setShowFocusedWindow(checked);
|
return Prefs.setShowFocusedWindow(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Weather Widget"
|
text: "Weather Widget"
|
||||||
@@ -71,7 +74,7 @@ ScrollView {
|
|||||||
return Prefs.setShowWeather(checked);
|
return Prefs.setShowWeather(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Media Controls"
|
text: "Media Controls"
|
||||||
@@ -81,7 +84,7 @@ ScrollView {
|
|||||||
return Prefs.setShowMusic(checked);
|
return Prefs.setShowMusic(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Clipboard Button"
|
text: "Clipboard Button"
|
||||||
@@ -91,7 +94,7 @@ ScrollView {
|
|||||||
return Prefs.setShowClipboard(checked);
|
return Prefs.setShowClipboard(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "System Resources"
|
text: "System Resources"
|
||||||
@@ -101,7 +104,7 @@ ScrollView {
|
|||||||
return Prefs.setShowSystemResources(checked);
|
return Prefs.setShowSystemResources(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "System Tray"
|
text: "System Tray"
|
||||||
@@ -111,9 +114,11 @@ ScrollView {
|
|||||||
return Prefs.setShowSystemTray(checked);
|
return Prefs.setShowSystemTray(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workspace Section
|
// Workspace Section
|
||||||
StyledRect {
|
StyledRect {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -122,24 +127,25 @@ ScrollView {
|
|||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
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.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: workspaceSection
|
id: workspaceSection
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: "view_module"
|
name: "view_module"
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Workspace Settings"
|
text: "Workspace Settings"
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
@@ -147,8 +153,9 @@ ScrollView {
|
|||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Workspace Index Numbers"
|
text: "Workspace Index Numbers"
|
||||||
@@ -158,7 +165,7 @@ ScrollView {
|
|||||||
return Prefs.setShowWorkspaceIndex(checked);
|
return Prefs.setShowWorkspaceIndex(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Workspace Padding"
|
text: "Workspace Padding"
|
||||||
@@ -168,7 +175,11 @@ ScrollView {
|
|||||||
return Prefs.setShowWorkspacePadding(checked);
|
return Prefs.setShowWorkspacePadding(checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -115,12 +115,12 @@ PanelWindow {
|
|||||||
readonly property int availableWidth: width
|
readonly property int availableWidth: width
|
||||||
// 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: focusedApp.visible ? 456 : 0
|
||||||
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: clock.width
|
||||||
readonly property int mediaMaxWidth: media.visible ? 280 : 0 // Normal max width
|
readonly property int mediaMaxWidth: media.visible ? 280 : 0 // Normal max width
|
||||||
readonly property int weatherWidth: weather.visible ? weather.width : 0
|
readonly property int weatherWidth: weather.visible ? weather.width : 0
|
||||||
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
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ Image {
|
|||||||
property string imagePath: ""
|
property string imagePath: ""
|
||||||
property string imageHash: ""
|
property string imageHash: ""
|
||||||
property int maxCacheSize: 512
|
property int maxCacheSize: 512
|
||||||
|
|
||||||
readonly property string cachePath: imageHash ? `${Paths.stringify(Paths.imagecache)}/${imageHash}@${maxCacheSize}x${maxCacheSize}.png` : ""
|
readonly property string cachePath: imageHash ? `${Paths.stringify(Paths.imagecache)}/${imageHash}@${maxCacheSize}x${maxCacheSize}.png` : ""
|
||||||
|
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
@@ -19,44 +18,45 @@ Image {
|
|||||||
sourceSize.width: maxCacheSize
|
sourceSize.width: maxCacheSize
|
||||||
sourceSize.height: maxCacheSize
|
sourceSize.height: maxCacheSize
|
||||||
smooth: true
|
smooth: true
|
||||||
|
|
||||||
onImagePathChanged: {
|
onImagePathChanged: {
|
||||||
if (imagePath) {
|
if (imagePath) {
|
||||||
hashProcess.command = ["sha256sum", Paths.strip(imagePath)]
|
hashProcess.command = ["sha256sum", Paths.strip(imagePath)];
|
||||||
hashProcess.running = true
|
hashProcess.running = true;
|
||||||
} else {
|
} else {
|
||||||
source = ""
|
source = "";
|
||||||
imageHash = ""
|
imageHash = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onCachePathChanged: {
|
onCachePathChanged: {
|
||||||
if (imageHash && cachePath) {
|
if (imageHash && cachePath) {
|
||||||
// Ensure cache directory exists before trying to load from cache
|
// Ensure cache directory exists before trying to load from cache
|
||||||
Paths.mkdir(Paths.imagecache)
|
Paths.mkdir(Paths.imagecache);
|
||||||
source = cachePath
|
source = cachePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
if (source == cachePath && status === Image.Error) {
|
if (source == cachePath && status === Image.Error) {
|
||||||
source = imagePath
|
source = imagePath;
|
||||||
} else if (source == imagePath && status === Image.Ready && imageHash && cachePath) {
|
} else if (source == imagePath && status === Image.Ready && imageHash && cachePath) {
|
||||||
Paths.mkdir(Paths.imagecache)
|
Paths.mkdir(Paths.imagecache);
|
||||||
const grabPath = cachePath
|
const grabPath = cachePath;
|
||||||
if (visible && width > 0 && height > 0 && Window.window && Window.window.visible) {
|
if (visible && width > 0 && height > 0 && Window.window && Window.window.visible)
|
||||||
grabToImage(res => res.saveToFile(grabPath))
|
grabToImage((res) => {
|
||||||
}
|
return res.saveToFile(grabPath);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: hashProcess
|
id: hashProcess
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
root.imageHash = text.split(" ")[0]
|
root.imageHash = text.split(" ")[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,11 +18,10 @@ Rectangle {
|
|||||||
height: 60
|
height: 60
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (!visible && dropdownMenu.visible) {
|
if (!visible && dropdownMenu.visible)
|
||||||
dropdownMenu.close();
|
dropdownMenu.close();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -48,6 +47,7 @@ Rectangle {
|
|||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -69,7 +69,6 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (dropdownMenu.visible) {
|
if (dropdownMenu.visible) {
|
||||||
dropdownMenu.close();
|
dropdownMenu.close();
|
||||||
@@ -85,6 +84,7 @@ Rectangle {
|
|||||||
// Use a Row for the left-aligned content (icon + text)
|
// Use a Row for the left-aligned content (icon + text)
|
||||||
Row {
|
Row {
|
||||||
id: contentRow
|
id: contentRow
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.leftMargin: Theme.spacingM
|
anchors.leftMargin: Theme.spacingM
|
||||||
@@ -108,11 +108,13 @@ Rectangle {
|
|||||||
width: dropdown.width - contentRow.x - expandIcon.width - Theme.spacingM - Theme.spacingS
|
width: dropdown.width - contentRow.x - expandIcon.width - Theme.spacingM - Theme.spacingS
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Anchor the expand icon to the right, outside of the Row
|
// Anchor the expand icon to the right, outside of the Row
|
||||||
DankIcon {
|
DankIcon {
|
||||||
id: expandIcon
|
id: expandIcon
|
||||||
|
|
||||||
name: "expand_more"
|
name: "expand_more"
|
||||||
size: 20
|
size: 20
|
||||||
color: Theme.surfaceVariantText
|
color: Theme.surfaceVariantText
|
||||||
@@ -120,18 +122,21 @@ Rectangle {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.rightMargin: Theme.spacingS
|
anchors.rightMargin: Theme.spacingS
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Popup {
|
Popup {
|
||||||
id: dropdownMenu
|
id: dropdownMenu
|
||||||
|
|
||||||
parent: Overlay.overlay
|
parent: Overlay.overlay
|
||||||
|
|
||||||
width: 180
|
width: 180
|
||||||
height: Math.min(200, root.options.length * 36 + 16)
|
height: Math.min(200, root.options.length * 36 + 16)
|
||||||
|
|
||||||
padding: 0
|
padding: 0
|
||||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||||
background: Rectangle { color: "transparent" }
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: Rectangle {
|
contentItem: Rectangle {
|
||||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 1)
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 1)
|
||||||
@@ -159,14 +164,14 @@ Rectangle {
|
|||||||
anchors.leftMargin: Theme.spacingS
|
anchors.leftMargin: Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
name: root.optionIcons.length > index ? root.optionIcons[index] : ""
|
name: root.optionIcons.length > index ? root.optionIcons[index] : ""
|
||||||
size: 18
|
size: 18
|
||||||
color: root.currentValue === modelData ? Theme.primary : Theme.surfaceVariantText
|
color: root.currentValue === modelData ? Theme.primary : Theme.surfaceVariantText
|
||||||
visible: name !== ""
|
visible: name !== ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: modelData
|
text: modelData
|
||||||
@@ -174,10 +179,12 @@ Rectangle {
|
|||||||
color: root.currentValue === modelData ? Theme.primary : Theme.surfaceText
|
color: root.currentValue === modelData ? Theme.primary : Theme.surfaceText
|
||||||
font.weight: root.currentValue === modelData ? Font.Medium : Font.Normal
|
font.weight: root.currentValue === modelData ? Font.Medium : Font.Normal
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: optionArea
|
id: optionArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -187,9 +194,15 @@ Rectangle {
|
|||||||
dropdownMenu.close();
|
dropdownMenu.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,32 +20,29 @@ ScrollView {
|
|||||||
property real wheelStepSize: 60
|
property real wheelStepSize: 60
|
||||||
property bool hoverUpdatesSelection: true
|
property bool hoverUpdatesSelection: true
|
||||||
property bool keyboardNavigationActive: false
|
property bool keyboardNavigationActive: false
|
||||||
|
|
||||||
signal keyboardNavigationReset()
|
|
||||||
|
|
||||||
|
signal keyboardNavigationReset()
|
||||||
signal itemClicked(int index, var modelData)
|
signal itemClicked(int index, var modelData)
|
||||||
signal itemHovered(int index)
|
signal itemHovered(int index)
|
||||||
|
|
||||||
// Ensure the current item is visible
|
// Ensure the current item is visible
|
||||||
function ensureVisible(index) {
|
function ensureVisible(index) {
|
||||||
if (index < 0 || index >= grid.count) return;
|
if (index < 0 || index >= grid.count)
|
||||||
|
return ;
|
||||||
|
|
||||||
var itemY = Math.floor(index / grid.actualColumns) * grid.cellHeight;
|
var itemY = Math.floor(index / grid.actualColumns) * grid.cellHeight;
|
||||||
var itemBottom = itemY + grid.cellHeight;
|
var itemBottom = itemY + grid.cellHeight;
|
||||||
|
if (itemY < grid.contentY)
|
||||||
if (itemY < grid.contentY) {
|
|
||||||
grid.contentY = itemY;
|
grid.contentY = itemY;
|
||||||
} else if (itemBottom > grid.contentY + grid.height) {
|
else if (itemBottom > grid.contentY + grid.height)
|
||||||
grid.contentY = itemBottom - grid.height;
|
grid.contentY = itemBottom - grid.height;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
if (keyboardNavigationActive) {
|
if (keyboardNavigationActive)
|
||||||
ensureVisible(currentIndex);
|
ensureVisible(currentIndex);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
clip: true
|
clip: true
|
||||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||||
@@ -157,9 +154,9 @@ ScrollView {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
z: 10
|
z: 10
|
||||||
onEntered: {
|
onEntered: {
|
||||||
if (hoverUpdatesSelection && !keyboardNavigationActive) {
|
if (hoverUpdatesSelection && !keyboardNavigationActive)
|
||||||
currentIndex = index;
|
currentIndex = index;
|
||||||
}
|
|
||||||
itemHovered(index);
|
itemHovered(index);
|
||||||
}
|
}
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
|
|||||||
@@ -16,31 +16,29 @@ ScrollView {
|
|||||||
property int itemSpacing: Theme.spacingS
|
property int itemSpacing: Theme.spacingS
|
||||||
property bool hoverUpdatesSelection: true
|
property bool hoverUpdatesSelection: true
|
||||||
property bool keyboardNavigationActive: false
|
property bool keyboardNavigationActive: false
|
||||||
|
|
||||||
signal keyboardNavigationReset()
|
signal keyboardNavigationReset()
|
||||||
signal itemClicked(int index, var modelData)
|
signal itemClicked(int index, var modelData)
|
||||||
signal itemHovered(int index)
|
signal itemHovered(int index)
|
||||||
|
|
||||||
// Ensure the current item is visible
|
// Ensure the current item is visible
|
||||||
function ensureVisible(index) {
|
function ensureVisible(index) {
|
||||||
if (index < 0 || index >= list.count) return;
|
if (index < 0 || index >= list.count)
|
||||||
|
return ;
|
||||||
|
|
||||||
var itemY = index * (itemHeight + itemSpacing);
|
var itemY = index * (itemHeight + itemSpacing);
|
||||||
var itemBottom = itemY + itemHeight;
|
var itemBottom = itemY + itemHeight;
|
||||||
|
if (itemY < list.contentY)
|
||||||
if (itemY < list.contentY) {
|
|
||||||
list.contentY = itemY;
|
list.contentY = itemY;
|
||||||
} else if (itemBottom > list.contentY + list.height) {
|
else if (itemBottom > list.contentY + list.height)
|
||||||
list.contentY = itemBottom - list.height;
|
list.contentY = itemBottom - list.height;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
if (keyboardNavigationActive) {
|
if (keyboardNavigationActive)
|
||||||
ensureVisible(currentIndex);
|
ensureVisible(currentIndex);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
clip: true
|
clip: true
|
||||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||||
@@ -156,9 +154,9 @@ ScrollView {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
z: 10
|
z: 10
|
||||||
onEntered: {
|
onEntered: {
|
||||||
if (hoverUpdatesSelection && !keyboardNavigationActive) {
|
if (hoverUpdatesSelection && !keyboardNavigationActive)
|
||||||
listView.currentIndex = index;
|
listView.currentIndex = index;
|
||||||
}
|
|
||||||
itemHovered(index);
|
itemHovered(index);
|
||||||
}
|
}
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ Item {
|
|||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
@@ -85,15 +87,9 @@ Item {
|
|||||||
visible: sliderMouseArea.containsMouse && slider.enabled
|
visible: sliderMouseArea.containsMouse && slider.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
StyledRect {
|
||||||
id: valueTooltip
|
id: valueTooltip
|
||||||
|
|
||||||
width: tooltipText.contentWidth + Theme.spacingS * 2
|
width: tooltipText.contentWidth + Theme.spacingS * 2
|
||||||
height: tooltipText.contentHeight + Theme.spacingXS * 2
|
height: tooltipText.contentHeight + Theme.spacingXS * 2
|
||||||
radius: Theme.cornerRadiusSmall
|
radius: Theme.cornerRadiusSmall
|
||||||
@@ -105,9 +101,10 @@ Item {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: (sliderMouseArea.containsMouse && slider.showValue) || (slider.isDragging && slider.showValue)
|
visible: (sliderMouseArea.containsMouse && slider.showValue) || (slider.isDragging && slider.showValue)
|
||||||
opacity: visible ? 1 : 0
|
opacity: visible ? 1 : 0
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: tooltipText
|
id: tooltipText
|
||||||
|
|
||||||
text: slider.value + slider.unit
|
text: slider.value + slider.unit
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
@@ -115,14 +112,25 @@ Item {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
font.hintingPreference: Font.PreferFullHinting
|
font.hintingPreference: Font.PreferFullHinting
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -201,7 +209,9 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
@@ -211,6 +221,7 @@ Item {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: slider.rightIcon.length > 0
|
visible: slider.rightIcon.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,11 +38,10 @@ Rectangle {
|
|||||||
readonly property real rightPadding: Theme.spacingM + (showClearButton && text.length > 0 ? 24 + Theme.spacingM : 0)
|
readonly property real rightPadding: Theme.spacingM + (showClearButton && text.length > 0 ? 24 + Theme.spacingM : 0)
|
||||||
property real topPadding: Theme.spacingM
|
property real topPadding: Theme.spacingM
|
||||||
property real bottomPadding: Theme.spacingM
|
property real bottomPadding: Theme.spacingM
|
||||||
|
|
||||||
// Behavior control
|
// Behavior control
|
||||||
property bool ignoreLeftRightKeys: false
|
property bool ignoreLeftRightKeys: false
|
||||||
property var keyForwardTargets: []
|
property var keyForwardTargets: []
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
signal textEdited()
|
signal textEdited()
|
||||||
signal editingFinished()
|
signal editingFinished()
|
||||||
@@ -133,19 +132,16 @@ Rectangle {
|
|||||||
onEditingFinished: root.editingFinished()
|
onEditingFinished: root.editingFinished()
|
||||||
onAccepted: root.accepted()
|
onAccepted: root.accepted()
|
||||||
onActiveFocusChanged: root.focusStateChanged(activeFocus)
|
onActiveFocusChanged: root.focusStateChanged(activeFocus)
|
||||||
|
|
||||||
Keys.forwardTo: root.ignoreLeftRightKeys ? root.keyForwardTargets : []
|
Keys.forwardTo: root.ignoreLeftRightKeys ? root.keyForwardTargets : []
|
||||||
|
|
||||||
Keys.onLeftPressed: function(event) {
|
Keys.onLeftPressed: function(event) {
|
||||||
if (root.ignoreLeftRightKeys) {
|
if (root.ignoreLeftRightKeys)
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onRightPressed: function(event) {
|
Keys.onRightPressed: function(event) {
|
||||||
if (root.ignoreLeftRightKeys) {
|
if (root.ignoreLeftRightKeys)
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|||||||
Reference in New Issue
Block a user