1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-14 17:52:10 -04:00

widgets: make dank icon picker a popup

This commit is contained in:
bbedward
2025-12-09 13:40:51 -05:00
parent 566d617508
commit 993f14a31f

View File

@@ -1,8 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Effects import QtQuick.Effects
import Quickshell
import Quickshell.Wayland
import qs.Common import qs.Common
import qs.Widgets import qs.Widgets
@@ -10,7 +8,7 @@ Rectangle {
id: root id: root
property string currentIcon: "" property string currentIcon: ""
property string iconType: "icon" // "icon" or "text" property string iconType: "icon"
signal iconSelected(string iconName, string iconType) signal iconSelected(string iconName, string iconType)
@@ -18,40 +16,73 @@ Rectangle {
height: 32 height: 32
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: Theme.surfaceContainer color: Theme.surfaceContainer
border.color: dropdownLoader.active ? Theme.primary : Theme.outline border.color: iconPopup.visible ? Theme.primary : Theme.outline
border.width: 1 border.width: 1
property var iconCategories: [{ property var iconCategories: [
{
"name": I18n.tr("Numbers"), "name": I18n.tr("Numbers"),
"icons": ["looks_one", "looks_two", "looks_3", "looks_4", "looks_5", "looks_6", "filter_1", "filter_2", "filter_3", "filter_4", "filter_5", "filter_6", "filter_7", "filter_8", "filter_9", "filter_9_plus", "plus_one", "exposure_plus_1", "exposure_plus_2"] "icons": ["looks_one", "looks_two", "looks_3", "looks_4", "looks_5", "looks_6", "filter_1", "filter_2", "filter_3", "filter_4", "filter_5", "filter_6", "filter_7", "filter_8", "filter_9", "filter_9_plus", "plus_one", "exposure_plus_1", "exposure_plus_2"]
}, { },
{
"name": I18n.tr("Workspace"), "name": I18n.tr("Workspace"),
"icons": ["work", "laptop", "desktop_windows", "folder", "view_module", "dashboard", "apps", "grid_view"] "icons": ["work", "laptop", "desktop_windows", "folder", "view_module", "dashboard", "apps", "grid_view"]
}, { },
{
"name": I18n.tr("Development"), "name": I18n.tr("Development"),
"icons": ["code", "terminal", "bug_report", "build", "engineering", "integration_instructions", "data_object", "schema", "api", "webhook"] "icons": ["code", "terminal", "bug_report", "build", "engineering", "integration_instructions", "data_object", "schema", "api", "webhook"]
}, { },
{
"name": I18n.tr("Communication"), "name": I18n.tr("Communication"),
"icons": ["chat", "mail", "forum", "message", "video_call", "call", "contacts", "group", "notifications", "campaign"] "icons": ["chat", "mail", "forum", "message", "video_call", "call", "contacts", "group", "notifications", "campaign"]
}, { },
{
"name": I18n.tr("Media"), "name": I18n.tr("Media"),
"icons": ["music_note", "headphones", "mic", "videocam", "photo", "movie", "library_music", "album", "radio", "volume_up"] "icons": ["music_note", "headphones", "mic", "videocam", "photo", "movie", "library_music", "album", "radio", "volume_up"]
}, { },
{
"name": I18n.tr("System"), "name": I18n.tr("System"),
"icons": ["memory", "storage", "developer_board", "monitor", "keyboard", "mouse", "battery_std", "wifi", "bluetooth", "security", "settings"] "icons": ["memory", "storage", "developer_board", "monitor", "keyboard", "mouse", "battery_std", "wifi", "bluetooth", "security", "settings"]
}, { },
{
"name": I18n.tr("Navigation"), "name": I18n.tr("Navigation"),
"icons": ["home", "arrow_forward", "arrow_back", "expand_more", "expand_less", "menu", "close", "search", "filter_list", "sort"] "icons": ["home", "arrow_forward", "arrow_back", "expand_more", "expand_less", "menu", "close", "search", "filter_list", "sort"]
}, { },
{
"name": I18n.tr("Actions"), "name": I18n.tr("Actions"),
"icons": ["add", "remove", "edit", "delete", "save", "download", "upload", "share", "content_copy", "content_paste", "content_cut", "undo", "redo"] "icons": ["add", "remove", "edit", "delete", "save", "download", "upload", "share", "content_copy", "content_paste", "content_cut", "undo", "redo"]
}, { },
{
"name": I18n.tr("Status"), "name": I18n.tr("Status"),
"icons": ["check", "error", "warning", "info", "done", "pending", "schedule", "update", "sync", "offline_bolt"] "icons": ["check", "error", "warning", "info", "done", "pending", "schedule", "update", "sync", "offline_bolt"]
}, { },
{
"name": I18n.tr("Fun"), "name": I18n.tr("Fun"),
"icons": ["celebration", "cake", "star", "favorite", "pets", "sports_esports", "local_fire_department", "bolt", "auto_awesome", "diamond"] "icons": ["celebration", "cake", "star", "favorite", "pets", "sports_esports", "local_fire_department", "bolt", "auto_awesome", "diamond"]
}] }
]
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (iconPopup.visible) {
iconPopup.close();
return;
}
const pos = root.mapToItem(Overlay.overlay, 0, 0);
const popupHeight = 500;
const overlayHeight = Overlay.overlay?.height ?? 800;
iconPopup.x = pos.x;
if (pos.y + root.height + popupHeight + 4 > overlayHeight) {
iconPopup.y = pos.y - popupHeight - 4;
} else {
iconPopup.y = pos.y + root.height + 4;
}
iconPopup.open();
}
}
Row { Row {
anchors.left: parent.left anchors.left: parent.left
@@ -73,18 +104,11 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 160 width: 160
elide: Text.ElideRight elide: Text.ElideRight
MouseArea {
anchors.fill: parent
onClicked: {
dropdownLoader.active = !dropdownLoader.active
}
}
} }
} }
DankIcon { DankIcon {
name: dropdownLoader.active ? "expand_less" : "expand_more" name: iconPopup.visible ? "expand_less" : "expand_more"
size: 16 size: 16
color: Theme.outline color: Theme.outline
anchors.right: parent.right anchors.right: parent.right
@@ -92,80 +116,24 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Loader { Popup {
id: dropdownLoader id: iconPopup
active: false
asynchronous: true
sourceComponent: PanelWindow { parent: Overlay.overlay
id: dropdownPopup
visible: true
implicitWidth: 320
implicitHeight: Math.min(500, dropdownContent.implicitHeight + 32)
color: "transparent"
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
anchors {
top: true
left: true
right: true
bottom: true
}
// Top area - above popup
MouseArea {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: popupContainer.y
onClicked: {
dropdownLoader.active = false
}
}
// Bottom area - below popup
MouseArea {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: popupContainer.bottom
anchors.bottom: parent.bottom
onClicked: {
dropdownLoader.active = false
}
}
// Left area - left of popup
MouseArea {
anchors.left: parent.left
anchors.top: popupContainer.top
anchors.bottom: popupContainer.bottom
width: popupContainer.x
onClicked: {
dropdownLoader.active = false
}
}
// Right area - right of popup
MouseArea {
anchors.right: parent.right
anchors.top: popupContainer.top
anchors.bottom: popupContainer.bottom
anchors.left: popupContainer.right
onClicked: {
dropdownLoader.active = false
}
}
Rectangle {
id: popupContainer
width: 320 width: 320
height: Math.min(500, dropdownContent.implicitHeight + 32) height: Math.min(500, dropdownContent.implicitHeight + 32)
x: Math.max(16, Math.min(root.mapToItem(null, 0, 0).x, parent.width - width - 16)) padding: 0
y: Math.max(16, Math.min(root.mapToItem(null, 0, root.height + 4).y, parent.height - height - 16)) modal: true
radius: Theme.cornerRadius dim: false
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
background: Rectangle {
color: "transparent"
}
contentItem: Rectangle {
color: Theme.surface color: Theme.surface
radius: Theme.cornerRadius
layer.enabled: true layer.enabled: true
layer.effect: MultiEffect { layer.effect: MultiEffect {
@@ -176,7 +144,6 @@ Rectangle {
shadowVerticalOffset: 4 shadowVerticalOffset: 4
} }
// Close button
Rectangle { Rectangle {
width: 24 width: 24
height: 24 height: 24
@@ -200,9 +167,7 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: iconPopup.close()
dropdownLoader.active = false
}
} }
} }
@@ -218,11 +183,11 @@ Rectangle {
width: parent.width width: parent.width
spacing: Theme.spacingM spacing: Theme.spacingM
// Icon categories
Repeater { Repeater {
model: root.iconCategories model: root.iconCategories
Column { Column {
required property var modelData
width: parent.width width: parent.width
spacing: Theme.spacingS spacing: Theme.spacingS
@@ -241,6 +206,7 @@ Rectangle {
model: modelData.icons model: modelData.icons
Rectangle { Rectangle {
required property string modelData
width: 36 width: 36
height: 36 height: 36
radius: Theme.cornerRadius radius: Theme.cornerRadius
@@ -249,9 +215,9 @@ Rectangle {
border.width: 2 border.width: 2
DankIcon { DankIcon {
name: modelData name: parent.modelData
size: 20 size: 20
color: root.currentIcon === modelData ? Theme.primary : Theme.surfaceText color: root.currentIcon === parent.modelData ? Theme.primary : Theme.surfaceText
anchors.centerIn: parent anchors.centerIn: parent
} }
@@ -261,8 +227,8 @@ Rectangle {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
root.iconSelected(modelData, "icon") root.iconSelected(parent.modelData, "icon");
dropdownLoader.active = false iconPopup.close();
} }
} }
@@ -281,11 +247,10 @@ Rectangle {
} }
} }
} }
}
function setIcon(iconName, type) { function setIcon(iconName, type) {
root.iconType = type root.iconType = type;
root.iconType = "icon" root.iconType = "icon";
root.currentIcon = iconName root.currentIcon = iconName;
} }
} }