mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
Compare commits
9 Commits
3507c6cec3
...
6735989455
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6735989455 | ||
|
|
db37ac24c7 | ||
|
|
0231270f9e | ||
|
|
b5194aa9e1 | ||
|
|
ea0ffaacb0 | ||
|
|
3b1f084a13 | ||
|
|
39a9e3a89f | ||
|
|
7a7af775c2 | ||
|
|
6ac2a305f7 |
10
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
10
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -42,12 +42,12 @@ body:
|
||||
placeholder: e.g., PikaOS, Void Linux, etc.
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: dms_version
|
||||
- type: textarea
|
||||
id: dms_doctor
|
||||
attributes:
|
||||
label: dms version
|
||||
description: Output of dms version command
|
||||
placeholder: e.g., 1.2.3
|
||||
label: dms doctor -v
|
||||
description: Output of `dms doctor -v` command
|
||||
placeholder: Paste the output of `dms doctor -v` here
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/support_request.yml
vendored
10
.github/ISSUE_TEMPLATE/support_request.yml
vendored
@@ -27,12 +27,12 @@ body:
|
||||
placeholder: Your Linux distribution
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: dms_version
|
||||
- type: textarea
|
||||
id: dms_doctor
|
||||
attributes:
|
||||
label: dms version
|
||||
description: Output of dms version command
|
||||
placeholder: e.g., 1.2.3
|
||||
label: dms doctor -v
|
||||
description: Output of `dms doctor -v` command
|
||||
placeholder: Paste the output of `dms doctor -v` here
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
|
||||
@@ -96,6 +96,28 @@ Singleton {
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
property var launcherPluginOrder: []
|
||||
onLauncherPluginOrderChanged: saveSettings()
|
||||
|
||||
function setLauncherPluginOrder(order) {
|
||||
launcherPluginOrder = order;
|
||||
}
|
||||
|
||||
function getOrderedLauncherPlugins(allPlugins) {
|
||||
if (!launcherPluginOrder || launcherPluginOrder.length === 0)
|
||||
return allPlugins;
|
||||
const orderMap = {};
|
||||
for (let i = 0; i < launcherPluginOrder.length; i++)
|
||||
orderMap[launcherPluginOrder[i]] = i;
|
||||
return allPlugins.slice().sort((a, b) => {
|
||||
const aOrder = orderMap[a.id] ?? 9999;
|
||||
const bOrder = orderMap[b.id] ?? 9999;
|
||||
if (aOrder !== bOrder)
|
||||
return aOrder - bOrder;
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
}
|
||||
|
||||
property alias dankBarLeftWidgetsModel: leftWidgetsModel
|
||||
property alias dankBarCenterWidgetsModel: centerWidgetsModel
|
||||
property alias dankBarRightWidgetsModel: rightWidgetsModel
|
||||
|
||||
@@ -416,7 +416,8 @@ var SPEC = {
|
||||
desktopWidgetGroups: { def: [] },
|
||||
|
||||
builtInPluginSettings: { def: {} },
|
||||
launcherPluginVisibility: { def: {} }
|
||||
launcherPluginVisibility: { def: {} },
|
||||
launcherPluginOrder: { def: [] }
|
||||
};
|
||||
|
||||
function getValidKeys() {
|
||||
|
||||
@@ -176,9 +176,11 @@ Item {
|
||||
pluginViewPreferences = prefs;
|
||||
}
|
||||
|
||||
property int _searchVersion: 0
|
||||
|
||||
Timer {
|
||||
id: searchDebounce
|
||||
interval: 80
|
||||
interval: searchMode === "all" && searchQuery.length > 0 ? 120 : 60
|
||||
onTriggered: root.performSearch()
|
||||
}
|
||||
|
||||
@@ -193,6 +195,7 @@ Item {
|
||||
}
|
||||
|
||||
function setSearchQuery(query) {
|
||||
_searchVersion++;
|
||||
searchQuery = query;
|
||||
searchDebounce.restart();
|
||||
|
||||
@@ -261,6 +264,7 @@ Item {
|
||||
}
|
||||
|
||||
function performSearch() {
|
||||
var currentVersion = _searchVersion;
|
||||
isSearching = true;
|
||||
|
||||
var cachedSections = AppSearchService.getCachedDefaultSections();
|
||||
@@ -430,36 +434,35 @@ Item {
|
||||
allItems = allItems.concat(apps);
|
||||
|
||||
if (searchMode === "all") {
|
||||
if (searchQuery) {
|
||||
var allPluginIds = getVisibleLauncherPluginIds();
|
||||
for (var i = 0; i < allPluginIds.length; i++) {
|
||||
var pluginId = allPluginIds[i];
|
||||
var pItems = getPluginItems(pluginId, searchQuery);
|
||||
allItems = allItems.concat(pItems);
|
||||
}
|
||||
|
||||
var allBuiltInIds = getVisibleBuiltInLauncherIds();
|
||||
for (var i = 0; i < allBuiltInIds.length; i++) {
|
||||
var pluginId = allBuiltInIds[i];
|
||||
var blItems = AppSearchService.getBuiltInLauncherItems(pluginId, searchQuery);
|
||||
for (var j = 0; j < blItems.length; j++) {
|
||||
allItems.push(transformBuiltInLauncherItem(blItems[j], pluginId));
|
||||
var includePlugins = !searchQuery || searchQuery.length >= 2;
|
||||
if (searchQuery && includePlugins) {
|
||||
var allPluginsOrdered = getAllVisiblePluginsOrdered();
|
||||
var maxPerPlugin = 10;
|
||||
for (var i = 0; i < allPluginsOrdered.length; i++) {
|
||||
var plugin = allPluginsOrdered[i];
|
||||
if (plugin.isBuiltIn) {
|
||||
var blItems = AppSearchService.getBuiltInLauncherItems(plugin.id, searchQuery);
|
||||
var blLimit = Math.min(blItems.length, maxPerPlugin);
|
||||
for (var j = 0; j < blLimit; j++)
|
||||
allItems.push(transformBuiltInLauncherItem(blItems[j], plugin.id));
|
||||
} else {
|
||||
var pItems = getPluginItems(plugin.id, searchQuery);
|
||||
if (pItems.length > maxPerPlugin)
|
||||
pItems = pItems.slice(0, maxPerPlugin);
|
||||
allItems = allItems.concat(pItems);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var emptyTriggerPlugins = getEmptyTriggerPlugins();
|
||||
for (var i = 0; i < emptyTriggerPlugins.length; i++) {
|
||||
var pluginId = emptyTriggerPlugins[i];
|
||||
var pItems = getPluginItems(pluginId, searchQuery);
|
||||
allItems = allItems.concat(pItems);
|
||||
}
|
||||
|
||||
var builtInLauncherPlugins = getBuiltInEmptyTriggerLaunchers();
|
||||
for (var i = 0; i < builtInLauncherPlugins.length; i++) {
|
||||
var pluginId = builtInLauncherPlugins[i];
|
||||
var blItems = AppSearchService.getBuiltInLauncherItems(pluginId, searchQuery);
|
||||
for (var j = 0; j < blItems.length; j++) {
|
||||
allItems.push(transformBuiltInLauncherItem(blItems[j], pluginId));
|
||||
} else if (!searchQuery) {
|
||||
var emptyTriggerOrdered = getEmptyTriggerPluginsOrdered();
|
||||
for (var i = 0; i < emptyTriggerOrdered.length; i++) {
|
||||
var plugin = emptyTriggerOrdered[i];
|
||||
if (plugin.isBuiltIn) {
|
||||
var blItems = AppSearchService.getBuiltInLauncherItems(plugin.id, searchQuery);
|
||||
for (var j = 0; j < blItems.length; j++)
|
||||
allItems.push(transformBuiltInLauncherItem(blItems[j], plugin.id));
|
||||
} else {
|
||||
var pItems = getPluginItems(plugin.id, searchQuery);
|
||||
allItems = allItems.concat(pItems);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,17 +472,29 @@ Item {
|
||||
}
|
||||
|
||||
var dynamicDefs = buildDynamicSectionDefs(allItems);
|
||||
|
||||
if (currentVersion !== _searchVersion) {
|
||||
isSearching = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var scoredItems = Scorer.scoreItems(allItems, searchQuery, getFrecencyForItem);
|
||||
var sortAlpha = !searchQuery && SettingsData.sortAppsAlphabetically;
|
||||
sections = Scorer.groupBySection(scoredItems, dynamicDefs, sortAlpha, searchQuery ? 50 : 500);
|
||||
var newSections = Scorer.groupBySection(scoredItems, dynamicDefs, sortAlpha, searchQuery ? 50 : 500);
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
var sid = sections[i].id;
|
||||
if (currentVersion !== _searchVersion) {
|
||||
isSearching = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < newSections.length; i++) {
|
||||
var sid = newSections[i].id;
|
||||
if (collapsedSections[sid] !== undefined) {
|
||||
sections[i].collapsed = collapsedSections[sid];
|
||||
newSections[i].collapsed = collapsedSections[sid];
|
||||
}
|
||||
}
|
||||
|
||||
sections = newSections;
|
||||
flatModel = Scorer.flattenSections(sections);
|
||||
|
||||
if (!AppSearchService.isCacheValid() && !searchQuery && searchMode === "all" && !pluginFilter) {
|
||||
@@ -663,8 +678,16 @@ Item {
|
||||
|
||||
function transformBuiltInLauncherItem(item, pluginId) {
|
||||
var rawIcon = item.icon || "extension";
|
||||
var iconType = detectIconType(rawIcon);
|
||||
var icon = stripIconPrefix(rawIcon);
|
||||
var iconType = item.iconType;
|
||||
if (!iconType) {
|
||||
if (rawIcon.startsWith("material:"))
|
||||
iconType = "material";
|
||||
else if (rawIcon.startsWith("unicode:"))
|
||||
iconType = "unicode";
|
||||
else
|
||||
iconType = "image";
|
||||
}
|
||||
|
||||
return {
|
||||
id: item.action || "",
|
||||
@@ -677,6 +700,7 @@ Item {
|
||||
data: item,
|
||||
pluginId: pluginId,
|
||||
isBuiltInLauncher: true,
|
||||
keywords: item.keywords || [],
|
||||
actions: [],
|
||||
primaryAction: {
|
||||
name: I18n.tr("Open"),
|
||||
@@ -859,9 +883,10 @@ Item {
|
||||
|
||||
function getEmptyTriggerPlugins() {
|
||||
var plugins = PluginService.getPluginsWithEmptyTrigger();
|
||||
return plugins.filter(function (pluginId) {
|
||||
var visible = plugins.filter(function (pluginId) {
|
||||
return SettingsData.getPluginAllowWithoutTrigger(pluginId);
|
||||
});
|
||||
return sortPluginIdsByOrder(visible);
|
||||
}
|
||||
|
||||
function getAllLauncherPluginIds() {
|
||||
@@ -871,9 +896,10 @@ Item {
|
||||
|
||||
function getVisibleLauncherPluginIds() {
|
||||
var launchers = PluginService.getLauncherPlugins();
|
||||
return Object.keys(launchers).filter(function (pluginId) {
|
||||
var visible = Object.keys(launchers).filter(function (pluginId) {
|
||||
return SettingsData.getPluginAllowWithoutTrigger(pluginId);
|
||||
});
|
||||
return sortPluginIdsByOrder(visible);
|
||||
}
|
||||
|
||||
function getAllBuiltInLauncherIds() {
|
||||
@@ -883,9 +909,88 @@ Item {
|
||||
|
||||
function getVisibleBuiltInLauncherIds() {
|
||||
var launchers = AppSearchService.getBuiltInLauncherPlugins();
|
||||
return Object.keys(launchers).filter(function (pluginId) {
|
||||
var visible = Object.keys(launchers).filter(function (pluginId) {
|
||||
return SettingsData.getPluginAllowWithoutTrigger(pluginId);
|
||||
});
|
||||
return sortPluginIdsByOrder(visible);
|
||||
}
|
||||
|
||||
function sortPluginIdsByOrder(pluginIds) {
|
||||
var order = SettingsData.launcherPluginOrder || [];
|
||||
if (order.length === 0)
|
||||
return pluginIds;
|
||||
var orderMap = {};
|
||||
for (var i = 0; i < order.length; i++)
|
||||
orderMap[order[i]] = i;
|
||||
return pluginIds.slice().sort(function (a, b) {
|
||||
var aOrder = orderMap[a] !== undefined ? orderMap[a] : 9999;
|
||||
var bOrder = orderMap[b] !== undefined ? orderMap[b] : 9999;
|
||||
return aOrder - bOrder;
|
||||
});
|
||||
}
|
||||
|
||||
function getAllVisiblePluginsOrdered() {
|
||||
var thirdPartyLaunchers = PluginService.getLauncherPlugins() || {};
|
||||
var builtInLaunchers = AppSearchService.getBuiltInLauncherPlugins() || {};
|
||||
var all = [];
|
||||
for (var id in thirdPartyLaunchers) {
|
||||
if (SettingsData.getPluginAllowWithoutTrigger(id))
|
||||
all.push({
|
||||
id: id,
|
||||
isBuiltIn: false
|
||||
});
|
||||
}
|
||||
for (var id in builtInLaunchers) {
|
||||
if (SettingsData.getPluginAllowWithoutTrigger(id))
|
||||
all.push({
|
||||
id: id,
|
||||
isBuiltIn: true
|
||||
});
|
||||
}
|
||||
var order = SettingsData.launcherPluginOrder || [];
|
||||
if (order.length === 0)
|
||||
return all;
|
||||
var orderMap = {};
|
||||
for (var i = 0; i < order.length; i++)
|
||||
orderMap[order[i]] = i;
|
||||
return all.sort(function (a, b) {
|
||||
var aOrder = orderMap[a.id] !== undefined ? orderMap[a.id] : 9999;
|
||||
var bOrder = orderMap[b.id] !== undefined ? orderMap[b.id] : 9999;
|
||||
return aOrder - bOrder;
|
||||
});
|
||||
}
|
||||
|
||||
function getEmptyTriggerPluginsOrdered() {
|
||||
var thirdParty = PluginService.getPluginsWithEmptyTrigger() || [];
|
||||
var builtIn = AppSearchService.getBuiltInLauncherPluginsWithEmptyTrigger() || [];
|
||||
var all = [];
|
||||
for (var i = 0; i < thirdParty.length; i++) {
|
||||
var id = thirdParty[i];
|
||||
if (SettingsData.getPluginAllowWithoutTrigger(id))
|
||||
all.push({
|
||||
id: id,
|
||||
isBuiltIn: false
|
||||
});
|
||||
}
|
||||
for (var i = 0; i < builtIn.length; i++) {
|
||||
var id = builtIn[i];
|
||||
if (SettingsData.getPluginAllowWithoutTrigger(id))
|
||||
all.push({
|
||||
id: id,
|
||||
isBuiltIn: true
|
||||
});
|
||||
}
|
||||
var order = SettingsData.launcherPluginOrder || [];
|
||||
if (order.length === 0)
|
||||
return all;
|
||||
var orderMap = {};
|
||||
for (var i = 0; i < order.length; i++)
|
||||
orderMap[order[i]] = i;
|
||||
return all.sort(function (a, b) {
|
||||
var aOrder = orderMap[a.id] !== undefined ? orderMap[a.id] : 9999;
|
||||
var bOrder = orderMap[b.id] !== undefined ? orderMap[b.id] : 9999;
|
||||
return aOrder - bOrder;
|
||||
});
|
||||
}
|
||||
|
||||
function getPluginBrowseItems() {
|
||||
@@ -948,9 +1053,10 @@ Item {
|
||||
|
||||
function getBuiltInEmptyTriggerLaunchers() {
|
||||
var plugins = AppSearchService.getBuiltInLauncherPluginsWithEmptyTrigger();
|
||||
return plugins.filter(function (pluginId) {
|
||||
var visible = plugins.filter(function (pluginId) {
|
||||
return SettingsData.getPluginAllowWithoutTrigger(pluginId);
|
||||
});
|
||||
return sortPluginIdsByOrder(visible);
|
||||
}
|
||||
|
||||
function getPluginItems(pluginId, query) {
|
||||
@@ -1088,8 +1194,16 @@ Item {
|
||||
|
||||
function transformPluginItem(item, pluginId) {
|
||||
var rawIcon = item.icon || "extension";
|
||||
var iconType = item.iconType || detectIconType(rawIcon);
|
||||
var icon = stripIconPrefix(rawIcon);
|
||||
var iconType = item.iconType;
|
||||
if (!iconType) {
|
||||
if (rawIcon.startsWith("material:"))
|
||||
iconType = "material";
|
||||
else if (rawIcon.startsWith("unicode:"))
|
||||
iconType = "unicode";
|
||||
else
|
||||
iconType = "image";
|
||||
}
|
||||
|
||||
return {
|
||||
id: item.id || item.name || "",
|
||||
@@ -1101,6 +1215,7 @@ Item {
|
||||
section: "plugin_" + pluginId,
|
||||
data: item,
|
||||
pluginId: pluginId,
|
||||
keywords: item.keywords || [],
|
||||
actions: item.actions || [],
|
||||
primaryAction: item.primaryAction || {
|
||||
name: I18n.tr("Select"),
|
||||
|
||||
@@ -17,6 +17,7 @@ Item {
|
||||
property alias spotlightContent: launcherContent
|
||||
property bool openedFromOverview: false
|
||||
property bool isClosing: false
|
||||
property bool _windowEnabled: true
|
||||
|
||||
readonly property bool useHyprlandFocusGrab: CompositorService.useHyprlandFocusGrab
|
||||
readonly property var effectiveScreen: launcherWindow.screen
|
||||
@@ -197,27 +198,41 @@ Item {
|
||||
Connections {
|
||||
target: Quickshell
|
||||
function onScreensChanged() {
|
||||
if (!launcherWindow.screen)
|
||||
if (Quickshell.screens.length === 0)
|
||||
return;
|
||||
const currentScreenName = launcherWindow.screen.name;
|
||||
let screenStillExists = false;
|
||||
for (let i = 0; i < Quickshell.screens.length; i++) {
|
||||
if (Quickshell.screens[i].name === currentScreenName) {
|
||||
screenStillExists = true;
|
||||
break;
|
||||
|
||||
const screen = launcherWindow.screen;
|
||||
const screenName = screen?.name;
|
||||
|
||||
let needsReset = !screen || !screenName;
|
||||
if (!needsReset) {
|
||||
needsReset = true;
|
||||
for (let i = 0; i < Quickshell.screens.length; i++) {
|
||||
if (Quickshell.screens[i].name === screenName) {
|
||||
needsReset = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (screenStillExists)
|
||||
|
||||
if (!needsReset)
|
||||
return;
|
||||
const newScreen = CompositorService.getFocusedScreen();
|
||||
if (newScreen)
|
||||
launcherWindow.screen = newScreen;
|
||||
|
||||
const newScreen = CompositorService.getFocusedScreen() ?? Quickshell.screens[0];
|
||||
if (!newScreen)
|
||||
return;
|
||||
|
||||
root._windowEnabled = false;
|
||||
launcherWindow.screen = newScreen;
|
||||
Qt.callLater(() => {
|
||||
root._windowEnabled = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
id: launcherWindow
|
||||
visible: true
|
||||
visible: root._windowEnabled
|
||||
color: "transparent"
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
|
||||
@@ -16,6 +16,25 @@ Rectangle {
|
||||
signal clicked
|
||||
signal rightClicked(real mouseX, real mouseY)
|
||||
|
||||
readonly property string iconValue: {
|
||||
if (!item)
|
||||
return "";
|
||||
switch (item.iconType) {
|
||||
case "material":
|
||||
case "nerd":
|
||||
return "material:" + (item.icon || "apps");
|
||||
case "unicode":
|
||||
return "unicode:" + (item.icon || "");
|
||||
case "composite":
|
||||
return item.iconFull || "";
|
||||
case "image":
|
||||
default:
|
||||
return item.icon || "";
|
||||
}
|
||||
}
|
||||
|
||||
readonly property int computedIconSize: Math.min(48, Math.max(32, width * 0.45))
|
||||
|
||||
radius: Theme.cornerRadius
|
||||
color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryPressed : "transparent"
|
||||
|
||||
@@ -25,88 +44,15 @@ Rectangle {
|
||||
spacing: Theme.spacingS
|
||||
width: parent.width - Theme.spacingM
|
||||
|
||||
Item {
|
||||
width: iconSize
|
||||
height: iconSize
|
||||
AppIconRenderer {
|
||||
width: root.computedIconSize
|
||||
height: root.computedIconSize
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
property int iconSize: Math.min(48, Math.max(32, root.width * 0.45))
|
||||
|
||||
Image {
|
||||
id: appIcon
|
||||
anchors.fill: parent
|
||||
visible: root.item?.iconType === "image"
|
||||
asynchronous: true
|
||||
source: root.item?.iconType === "image" ? "image://icon/" + (root.item?.icon || "application-x-executable") : ""
|
||||
sourceSize.width: parent.iconSize
|
||||
sourceSize.height: parent.iconSize
|
||||
fillMode: Image.PreserveAspectFit
|
||||
cache: false
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: root.item?.iconType === "material" || root.item?.iconType === "nerd"
|
||||
name: root.item?.icon ?? "apps"
|
||||
size: parent.iconSize * 0.7
|
||||
color: root.isSelected ? Theme.primary : Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
visible: root.item?.iconType === "unicode"
|
||||
text: root.item?.icon ?? ""
|
||||
font.pixelSize: parent.iconSize * 0.7
|
||||
color: root.isSelected ? Theme.primary : Theme.surfaceText
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
visible: root.item?.iconType === "composite"
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
asynchronous: true
|
||||
source: {
|
||||
if (!root.item || root.item.iconType !== "composite")
|
||||
return "";
|
||||
var iconFull = root.item.iconFull || "";
|
||||
if (iconFull.startsWith("svg+corner:")) {
|
||||
var parts = iconFull.substring(11).split("|");
|
||||
return parts[0] || "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
sourceSize.width: parent.width
|
||||
sourceSize.height: parent.height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
width: 16
|
||||
height: 16
|
||||
radius: 8
|
||||
color: Theme.surfaceContainer
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: {
|
||||
if (!root.item || root.item.iconType !== "composite")
|
||||
return "";
|
||||
var iconFull = root.item.iconFull || "";
|
||||
if (iconFull.startsWith("svg+corner:")) {
|
||||
var parts = iconFull.substring(11).split("|");
|
||||
return parts[1] || "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
size: 12
|
||||
color: root.isSelected ? Theme.primary : Theme.surfaceText
|
||||
}
|
||||
}
|
||||
}
|
||||
iconValue: root.iconValue
|
||||
iconSize: root.computedIconSize
|
||||
fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?"
|
||||
iconColor: root.isSelected ? Theme.primary : Theme.surfaceText
|
||||
materialIconSizeAdjustment: root.computedIconSize * 0.3
|
||||
}
|
||||
|
||||
StyledText {
|
||||
|
||||
@@ -16,6 +16,23 @@ Rectangle {
|
||||
signal clicked
|
||||
signal rightClicked(real mouseX, real mouseY)
|
||||
|
||||
readonly property string iconValue: {
|
||||
if (!item)
|
||||
return "";
|
||||
switch (item.iconType) {
|
||||
case "material":
|
||||
case "nerd":
|
||||
return "material:" + (item.icon || "apps");
|
||||
case "unicode":
|
||||
return "unicode:" + (item.icon || "");
|
||||
case "composite":
|
||||
return item.iconFull || "";
|
||||
case "image":
|
||||
default:
|
||||
return item.icon || "";
|
||||
}
|
||||
}
|
||||
|
||||
width: parent?.width ?? 200
|
||||
height: 52
|
||||
color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryPressed : "transparent"
|
||||
@@ -27,86 +44,14 @@ Rectangle {
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
spacing: Theme.spacingM
|
||||
|
||||
Item {
|
||||
AppIconRenderer {
|
||||
width: 36
|
||||
height: 36
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Image {
|
||||
id: appIcon
|
||||
anchors.fill: parent
|
||||
visible: root.item?.iconType === "image"
|
||||
asynchronous: true
|
||||
source: root.item?.iconType === "image" ? "image://icon/" + (root.item?.icon || "application-x-executable") : ""
|
||||
sourceSize.width: 36
|
||||
sourceSize.height: 36
|
||||
fillMode: Image.PreserveAspectFit
|
||||
cache: false
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: root.item?.iconType === "material" || root.item?.iconType === "nerd"
|
||||
name: root.item?.icon ?? "apps"
|
||||
size: 24
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
visible: root.item?.iconType === "unicode"
|
||||
text: root.item?.icon ?? ""
|
||||
font.pixelSize: 24
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
visible: root.item?.iconType === "composite"
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
asynchronous: true
|
||||
source: {
|
||||
if (!root.item || root.item.iconType !== "composite")
|
||||
return "";
|
||||
var iconFull = root.item.iconFull || "";
|
||||
if (iconFull.startsWith("svg+corner:")) {
|
||||
var parts = iconFull.substring(11).split("|");
|
||||
return parts[0] || "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
sourceSize.width: 36
|
||||
sourceSize.height: 36
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
width: 16
|
||||
height: 16
|
||||
radius: 8
|
||||
color: Theme.surfaceContainer
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: {
|
||||
if (!root.item || root.item.iconType !== "composite")
|
||||
return "";
|
||||
var iconFull = root.item.iconFull || "";
|
||||
if (iconFull.startsWith("svg+corner:")) {
|
||||
var parts = iconFull.substring(11).split("|");
|
||||
return parts[1] || "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
size: 12
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
}
|
||||
}
|
||||
iconValue: root.iconValue
|
||||
iconSize: 36
|
||||
fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?"
|
||||
materialIconSizeAdjustment: 12
|
||||
}
|
||||
|
||||
Column {
|
||||
|
||||
@@ -21,22 +21,30 @@ Rectangle {
|
||||
border.width: isSelected ? 2 : 0
|
||||
border.color: Theme.primary
|
||||
|
||||
readonly property string imageSource: {
|
||||
if (!item?.data)
|
||||
readonly property string iconValue: {
|
||||
if (!item)
|
||||
return "";
|
||||
var data = item.data;
|
||||
if (data.imageUrl)
|
||||
return data.imageUrl;
|
||||
if (data.imagePath)
|
||||
return data.imagePath;
|
||||
if (data.path && isImageFile(data.path))
|
||||
return data.path;
|
||||
return "";
|
||||
if (data?.imageUrl)
|
||||
return "image:" + data.imageUrl;
|
||||
if (data?.imagePath)
|
||||
return "image:" + data.imagePath;
|
||||
if (data?.path && isImageFile(data.path))
|
||||
return "image:" + data.path;
|
||||
switch (item.iconType) {
|
||||
case "material":
|
||||
case "nerd":
|
||||
return "material:" + (item.icon || "image");
|
||||
case "unicode":
|
||||
return "unicode:" + (item.icon || "");
|
||||
case "composite":
|
||||
return item.iconFull || "";
|
||||
case "image":
|
||||
default:
|
||||
return item.icon || "";
|
||||
}
|
||||
}
|
||||
|
||||
readonly property bool useImage: imageSource.length > 0
|
||||
readonly property bool useIconProvider: !useImage && item?.iconType === "image"
|
||||
|
||||
function isImageFile(path) {
|
||||
if (!path)
|
||||
return false;
|
||||
@@ -55,39 +63,12 @@ Rectangle {
|
||||
color: Theme.surfaceContainerHigh
|
||||
clip: true
|
||||
|
||||
CachingImage {
|
||||
AppIconRenderer {
|
||||
anchors.fill: parent
|
||||
visible: root.useImage
|
||||
imagePath: root.imageSource
|
||||
maxCacheSize: 256
|
||||
}
|
||||
|
||||
Image {
|
||||
id: iconImage
|
||||
anchors.fill: parent
|
||||
visible: root.useIconProvider
|
||||
source: root.useIconProvider ? "image://icon/" + (root.item?.icon || "application-x-executable") : ""
|
||||
sourceSize.width: parent.width * 2
|
||||
sourceSize.height: parent.height * 2
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
cache: false
|
||||
asynchronous: true
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: !root.useImage && !root.useIconProvider && root.item?.iconType !== "unicode"
|
||||
name: root.item?.icon ?? "image"
|
||||
size: Math.min(parent.width, parent.height) * 0.4
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
visible: root.item?.iconType === "unicode"
|
||||
text: root.item?.icon ?? ""
|
||||
font.pixelSize: Math.min(parent.width, parent.height) * 0.4
|
||||
color: Theme.surfaceVariantText
|
||||
iconValue: root.iconValue
|
||||
iconSize: Math.min(parent.width, parent.height)
|
||||
fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?"
|
||||
materialIconSizeAdjustment: iconSize * 0.3
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
||||
@@ -200,7 +200,7 @@ Item {
|
||||
}
|
||||
|
||||
onPreviewRequested: {
|
||||
textEditor.togglePreview()
|
||||
textEditor.togglePreview();
|
||||
}
|
||||
|
||||
onEscapePressed: {
|
||||
@@ -362,8 +362,8 @@ Item {
|
||||
DankModal {
|
||||
id: confirmationDialog
|
||||
|
||||
width: 400
|
||||
height: 180
|
||||
modalWidth: 400
|
||||
modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 180
|
||||
shouldBeVisible: false
|
||||
allowStacking: true
|
||||
|
||||
@@ -376,6 +376,7 @@ Item {
|
||||
FocusScope {
|
||||
anchors.fill: parent
|
||||
focus: true
|
||||
implicitHeight: contentColumn.implicitHeight
|
||||
|
||||
Keys.onEscapePressed: event => {
|
||||
confirmationDialog.close();
|
||||
@@ -384,47 +385,31 @@ Item {
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - Theme.spacingM * 2
|
||||
id: contentColumn
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Theme.spacingM
|
||||
spacing: Theme.spacingM
|
||||
|
||||
Row {
|
||||
StyledText {
|
||||
text: I18n.tr("Unsaved Changes")
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.pendingAction === "new" ? I18n.tr("You have unsaved changes. Save before creating a new file?") : root.pendingAction.startsWith("close_tab_") ? I18n.tr("You have unsaved changes. Save before closing this tab?") : root.pendingAction === "load_file" || root.pendingAction === "open" ? I18n.tr("You have unsaved changes. Save before opening a file?") : I18n.tr("You have unsaved changes. Save before continuing?")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceTextMedium
|
||||
width: parent.width
|
||||
|
||||
Column {
|
||||
width: parent.width - 40
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Unsaved Changes")
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.pendingAction === "new" ? I18n.tr("You have unsaved changes. Save before creating a new file?") : root.pendingAction.startsWith("close_tab_") ? I18n.tr("You have unsaved changes. Save before closing this tab?") : root.pendingAction === "load_file" || root.pendingAction === "open" ? I18n.tr("You have unsaved changes. Save before opening a file?") : I18n.tr("You have unsaved changes. Save before continuing?")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceTextMedium
|
||||
width: parent.width
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
iconName: "close"
|
||||
iconSize: Theme.iconSize - 4
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: {
|
||||
confirmationDialog.close();
|
||||
root.confirmationDialogOpen = false;
|
||||
}
|
||||
}
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: 40
|
||||
height: 36
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
@@ -515,6 +500,20 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: Theme.spacingM
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
iconName: "close"
|
||||
iconSize: Theme.iconSize - 4
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: {
|
||||
confirmationDialog.close();
|
||||
root.confirmationDialogOpen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,8 +558,8 @@ Rectangle {
|
||||
visible: !expanded
|
||||
anchors.right: clearButton.visible ? clearButton.left : parent.right
|
||||
anchors.rightMargin: clearButton.visible ? contentSpacing : Theme.spacingL
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: contentSpacing
|
||||
anchors.top: collapsedContent.bottom
|
||||
anchors.topMargin: contentSpacing
|
||||
spacing: contentSpacing
|
||||
|
||||
Repeater {
|
||||
@@ -614,8 +614,8 @@ Rectangle {
|
||||
visible: !expanded && actionCount < 3
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: contentSpacing
|
||||
anchors.top: collapsedContent.bottom
|
||||
anchors.topMargin: contentSpacing
|
||||
width: Math.max(clearText.implicitWidth + Theme.spacingM, compactMode ? 40 : 50)
|
||||
height: actionButtonHeight
|
||||
radius: Theme.spacingXS
|
||||
|
||||
@@ -531,8 +531,8 @@ PanelWindow {
|
||||
Row {
|
||||
anchors.right: clearButton.visible ? clearButton.left : parent.right
|
||||
anchors.rightMargin: clearButton.visible ? contentSpacing : Theme.spacingL
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: contentSpacing
|
||||
anchors.top: notificationContent.bottom
|
||||
anchors.topMargin: contentSpacing
|
||||
spacing: contentSpacing
|
||||
z: 20
|
||||
|
||||
@@ -585,8 +585,8 @@ PanelWindow {
|
||||
visible: actionCount < 3
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingL
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: contentSpacing
|
||||
anchors.top: notificationContent.bottom
|
||||
anchors.topMargin: contentSpacing
|
||||
width: Math.max(clearTextLabel.implicitWidth + Theme.spacingM, compactMode ? 40 : 50)
|
||||
height: actionButtonHeight
|
||||
radius: Theme.spacingXS
|
||||
|
||||
@@ -581,6 +581,7 @@ Item {
|
||||
|
||||
property var allLauncherPlugins: {
|
||||
SettingsData.launcherPluginVisibility;
|
||||
SettingsData.launcherPluginOrder;
|
||||
var plugins = [];
|
||||
var builtIn = AppSearchService.getBuiltInLauncherPlugins() || {};
|
||||
for (var pluginId in builtIn) {
|
||||
@@ -607,109 +608,175 @@ Item {
|
||||
trigger: PluginService.getPluginTrigger(pluginId) || ""
|
||||
});
|
||||
}
|
||||
return plugins.sort((a, b) => a.name.localeCompare(b.name));
|
||||
return SettingsData.getOrderedLauncherPlugins(plugins);
|
||||
}
|
||||
|
||||
function reorderPlugin(fromIndex, toIndex) {
|
||||
if (fromIndex === toIndex)
|
||||
return;
|
||||
var currentOrder = allLauncherPlugins.map(p => p.id);
|
||||
var item = currentOrder.splice(fromIndex, 1)[0];
|
||||
currentOrder.splice(toIndex, 0, item);
|
||||
SettingsData.setLauncherPluginOrder(currentOrder);
|
||||
}
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Control which plugins appear in 'All' mode without requiring a trigger prefix. Disabled plugins will only show when using their trigger.")
|
||||
text: I18n.tr("Control which plugins appear in 'All' mode without requiring a trigger prefix. Drag to reorder.")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Column {
|
||||
id: pluginVisibilityColumn
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Repeater {
|
||||
model: pluginVisibilityCard.allLauncherPlugins
|
||||
|
||||
delegate: Rectangle {
|
||||
id: visibilityDelegate
|
||||
delegate: Item {
|
||||
id: visibilityDelegateItem
|
||||
required property var modelData
|
||||
required property int index
|
||||
|
||||
width: parent.width
|
||||
property bool held: pluginDragArea.pressed
|
||||
property real originalY: y
|
||||
|
||||
width: pluginVisibilityColumn.width
|
||||
height: 52
|
||||
radius: Theme.cornerRadius
|
||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.3)
|
||||
z: held ? 2 : 1
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
Rectangle {
|
||||
id: visibilityDelegate
|
||||
width: parent.width
|
||||
height: 52
|
||||
radius: Theme.cornerRadius
|
||||
color: visibilityDelegateItem.held ? Theme.surfaceHover : Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.3)
|
||||
|
||||
Item {
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 28
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: visibilityDelegate.modelData.iconType !== "unicode"
|
||||
name: visibilityDelegate.modelData.icon
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
Item {
|
||||
width: Theme.iconSize
|
||||
height: Theme.iconSize
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: visibilityDelegateItem.modelData.iconType !== "unicode"
|
||||
name: visibilityDelegateItem.modelData.icon
|
||||
size: Theme.iconSize
|
||||
color: Theme.primary
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
visible: visibilityDelegateItem.modelData.iconType === "unicode"
|
||||
text: visibilityDelegateItem.modelData.icon
|
||||
font.pixelSize: Theme.iconSize
|
||||
color: Theme.primary
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
visible: visibilityDelegate.modelData.iconType === "unicode"
|
||||
text: visibilityDelegate.modelData.icon
|
||||
font.pixelSize: Theme.iconSize
|
||||
color: Theme.primary
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 2
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
text: visibilityDelegateItem.modelData.name
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: visibilityDelegateItem.modelData.isBuiltIn
|
||||
width: dmsBadgeLabel.implicitWidth + Theme.spacingS
|
||||
height: 16
|
||||
radius: 8
|
||||
color: Theme.primaryContainer
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
StyledText {
|
||||
id: dmsBadgeLabel
|
||||
anchors.centerIn: parent
|
||||
text: "DMS"
|
||||
font.pixelSize: Theme.fontSizeSmall - 2
|
||||
color: Theme.primaryText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: visibilityDelegateItem.modelData.trigger ? I18n.tr("Trigger: %1").arg(visibilityDelegateItem.modelData.trigger) : I18n.tr("No trigger")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
DankToggle {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 2
|
||||
|
||||
Row {
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
text: visibilityDelegate.modelData.name
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: visibilityDelegate.modelData.isBuiltIn
|
||||
width: dmsLabel.implicitWidth + Theme.spacingS
|
||||
height: 16
|
||||
radius: 8
|
||||
color: Theme.primaryContainer
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
StyledText {
|
||||
id: dmsLabel
|
||||
anchors.centerIn: parent
|
||||
text: "DMS"
|
||||
font.pixelSize: Theme.fontSizeSmall - 2
|
||||
color: Theme.primaryText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: visibilityDelegate.modelData.trigger ? I18n.tr("Trigger: %1").arg(visibilityDelegate.modelData.trigger) : I18n.tr("No trigger")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
checked: SettingsData.getPluginAllowWithoutTrigger(visibilityDelegateItem.modelData.id)
|
||||
onToggled: function (isChecked) {
|
||||
SettingsData.setPluginAllowWithoutTrigger(visibilityDelegateItem.modelData.id, isChecked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
id: visibilityToggle
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingM
|
||||
MouseArea {
|
||||
id: pluginDragArea
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
width: 28
|
||||
height: parent.height
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.SizeVerCursor
|
||||
drag.target: visibilityDelegateItem.held ? visibilityDelegateItem : undefined
|
||||
drag.axis: Drag.YAxis
|
||||
preventStealing: true
|
||||
|
||||
onPressed: {
|
||||
visibilityDelegateItem.originalY = visibilityDelegateItem.y;
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (!drag.active) {
|
||||
visibilityDelegateItem.y = visibilityDelegateItem.originalY;
|
||||
return;
|
||||
}
|
||||
const spacing = Theme.spacingS;
|
||||
const itemH = visibilityDelegateItem.height + spacing;
|
||||
var newIndex = Math.round(visibilityDelegateItem.y / itemH);
|
||||
newIndex = Math.max(0, Math.min(newIndex, pluginVisibilityCard.allLauncherPlugins.length - 1));
|
||||
pluginVisibilityCard.reorderPlugin(visibilityDelegateItem.index, newIndex);
|
||||
visibilityDelegateItem.y = visibilityDelegateItem.originalY;
|
||||
}
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
x: Theme.spacingXS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SettingsData.getPluginAllowWithoutTrigger(visibilityDelegate.modelData.id)
|
||||
onToggled: function (isChecked) {
|
||||
SettingsData.setPluginAllowWithoutTrigger(visibilityDelegate.modelData.id, isChecked);
|
||||
name: "drag_indicator"
|
||||
size: 18
|
||||
color: Theme.outline
|
||||
opacity: pluginDragArea.containsMouse || pluginDragArea.pressed ? 1 : 0.5
|
||||
}
|
||||
|
||||
Behavior on y {
|
||||
enabled: !pluginDragArea.pressed && !pluginDragArea.drag.active
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,10 @@ Item {
|
||||
readonly property bool isUnicode: iconValue.startsWith("unicode:")
|
||||
readonly property bool isSvgCorner: iconValue.startsWith("svg+corner:")
|
||||
readonly property bool isSvg: !isSvgCorner && iconValue.startsWith("svg:")
|
||||
readonly property bool isImage: iconValue.startsWith("image:")
|
||||
readonly property string materialName: isMaterial ? iconValue.substring(9) : ""
|
||||
readonly property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
|
||||
readonly property string imagePath: isImage ? iconValue.substring(6) : ""
|
||||
readonly property string svgSource: {
|
||||
if (isSvgCorner) {
|
||||
const parts = iconValue.substring(11).split("|");
|
||||
@@ -38,7 +40,7 @@ Item {
|
||||
return "";
|
||||
}
|
||||
readonly property string svgCornerIcon: isSvgCorner ? (iconValue.substring(11).split("|")[1] || "") : ""
|
||||
readonly property string iconPath: isMaterial || isUnicode || isSvg || isSvgCorner ? "" : Quickshell.iconPath(iconValue, true) || DesktopService.resolveIconPath(iconValue)
|
||||
readonly property string iconPath: isMaterial || isUnicode || isSvg || isSvgCorner || isImage ? "" : Quickshell.iconPath(iconValue, true) || DesktopService.resolveIconPath(iconValue)
|
||||
|
||||
visible: iconValue !== undefined && iconValue !== ""
|
||||
|
||||
@@ -66,14 +68,23 @@ Item {
|
||||
visible: root.isSvg || root.isSvgCorner
|
||||
}
|
||||
|
||||
CachingImage {
|
||||
id: cachingImg
|
||||
anchors.fill: parent
|
||||
imagePath: root.imagePath
|
||||
maxCacheSize: root.iconSize * 2
|
||||
visible: root.isImage && status === Image.Ready
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: iconImg
|
||||
|
||||
anchors.fill: parent
|
||||
source: root.iconPath
|
||||
smooth: true
|
||||
backer.sourceSize: Qt.size(root.iconSize, root.iconSize)
|
||||
mipmap: true
|
||||
asynchronous: true
|
||||
visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && root.iconPath !== "" && status === Image.Ready
|
||||
visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && !root.isImage && root.iconPath !== "" && status === Image.Ready
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -84,7 +95,7 @@ Item {
|
||||
anchors.rightMargin: root.fallbackRightMargin
|
||||
anchors.topMargin: root.fallbackTopMargin
|
||||
anchors.bottomMargin: root.fallbackBottomMargin
|
||||
visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && (root.iconPath === "" || iconImg.status !== Image.Ready)
|
||||
visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && !root.isImage && (root.iconPath === "" || iconImg.status !== Image.Ready)
|
||||
color: root.fallbackBackgroundColor
|
||||
radius: Theme.cornerRadius
|
||||
border.width: 0
|
||||
|
||||
Reference in New Issue
Block a user