1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-28 23:42:51 -05:00

use loader pattern

This commit is contained in:
bbedward
2025-08-12 20:01:27 -04:00
parent a76f0de18e
commit 1037f010ed

View File

@@ -19,7 +19,7 @@ Rectangle {
height: 32 height: 32
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: Theme.surfaceContainer color: Theme.surfaceContainer
border.color: dropdownPopup.visible ? Theme.primary : (mouseArea.containsMouse ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.5)) border.color: dropdownLoader.active ? Theme.primary : (mouseArea.containsMouse ? Theme.outline : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.5))
border.width: 1 border.width: 1
property var iconCategories: [ property var iconCategories: [
@@ -66,11 +66,7 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: { onClicked: {
if (dropdownPopup.visible) { dropdownLoader.active = !dropdownLoader.active
dropdownPopup.visible = false
} else {
dropdownPopup.visible = true
}
} }
} }
@@ -102,7 +98,7 @@ Rectangle {
} }
DankIcon { DankIcon {
name: dropdownPopup.visible ? "expand_less" : "expand_more" name: dropdownLoader.active ? "expand_less" : "expand_more"
size: 16 size: 16
color: Theme.outline color: Theme.outline
anchors.right: parent.right anchors.right: parent.right
@@ -110,200 +106,206 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
PanelWindow { Loader {
id: dropdownPopup id: dropdownLoader
active: false
asynchronous: true
visible: false sourceComponent: PanelWindow {
implicitWidth: 320 id: dropdownPopup
implicitHeight: Math.min(500, dropdownContent.implicitHeight + 32)
color: "transparent"
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
anchors { visible: true
top: true implicitWidth: 320
left: true implicitHeight: Math.min(500, dropdownContent.implicitHeight + 32)
right: true color: "transparent"
bottom: true WlrLayershell.layer: WlrLayershell.Overlay
} WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
// Click outside to close anchors {
MouseArea { top: true
anchors.fill: parent left: true
onClicked: dropdownPopup.visible = false right: true
} bottom: true
Rectangle {
width: 320
height: Math.min(500, dropdownContent.implicitHeight + 32)
x: {
// Get the root picker's position relative to the screen
var pickerPos = root.mapToItem(null, 0, 0)
return Math.max(16, Math.min(pickerPos.x, parent.width - width - 16))
} }
y: {
// Position below the picker button
var pickerPos = root.mapToItem(null, 0, root.height + 4)
return Math.max(16, Math.min(pickerPos.y, parent.height - height - 16))
}
radius: Theme.cornerRadius
color: Theme.surface
border.color: Theme.outline
border.width: 1
// Prevent this from closing the dropdown when clicked // Click outside to close
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
// Don't propagate clicks to parent onClicked: dropdownLoader.active = false
} }
layer.enabled: true Rectangle {
layer.effect: MultiEffect { width: 320
shadowEnabled: true height: Math.min(500, dropdownContent.implicitHeight + 32)
shadowColor: Theme.shadowDark x: {
shadowBlur: 0.8 // Get the root picker's position relative to the screen
shadowHorizontalOffset: 0 var pickerPos = root.mapToItem(null, 0, 0)
shadowVerticalOffset: 4 return Math.max(16, Math.min(pickerPos.x, parent.width - width - 16))
} }
y: {
// Position below the picker button
var pickerPos = root.mapToItem(null, 0, root.height + 4)
return Math.max(16, Math.min(pickerPos.y, parent.height - height - 16))
}
radius: Theme.cornerRadius
color: Theme.surface
border.color: Theme.outline
border.width: 1
DankFlickable { // Prevent this from closing the dropdown when clicked
anchors.fill: parent MouseArea {
anchors.margins: Theme.spacingS anchors.fill: parent
contentHeight: dropdownContent.height // Don't propagate clicks to parent
clip: true }
Column { layer.enabled: true
id: dropdownContent layer.effect: MultiEffect {
width: parent.width shadowEnabled: true
spacing: Theme.spacingM shadowColor: Theme.shadowDark
shadowBlur: 0.8
shadowHorizontalOffset: 0
shadowVerticalOffset: 4
}
// Custom text section DankFlickable {
Rectangle { anchors.fill: parent
anchors.margins: Theme.spacingS
contentHeight: dropdownContent.height
clip: true
Column {
id: dropdownContent
width: parent.width width: parent.width
height: customTextSection.implicitHeight + Theme.spacingS * 2 spacing: Theme.spacingM
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
Column { // Custom text section
id: customTextSection Rectangle {
anchors.fill: parent width: parent.width
anchors.margins: Theme.spacingS height: customTextSection.implicitHeight + Theme.spacingS * 2
spacing: Theme.spacingS radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
StyledText { Column {
text: "Custom Text" id: customTextSection
font.pixelSize: Theme.fontSizeSmall anchors.fill: parent
font.weight: Font.Medium anchors.margins: Theme.spacingS
color: Theme.surfaceText spacing: Theme.spacingS
}
Rectangle { StyledText {
width: parent.width text: "Custom Text"
height: 28 font.pixelSize: Theme.fontSizeSmall
radius: Theme.cornerRadius font.weight: Font.Medium
color: Theme.surfaceContainer color: Theme.surfaceText
border.color: customTextInput.activeFocus ? Theme.primary : Theme.outline }
border.width: 1
Row { Rectangle {
anchors.left: parent.left width: parent.width
anchors.verticalCenter: parent.verticalCenter height: 28
anchors.leftMargin: Theme.spacingS radius: Theme.cornerRadius
spacing: Theme.spacingS color: Theme.surfaceContainer
border.color: customTextInput.activeFocus ? Theme.primary : Theme.outline
border.width: 1
DankIcon { Row {
name: "text_fields" anchors.left: parent.left
size: 14
color: Theme.outline
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} anchors.leftMargin: Theme.spacingS
spacing: Theme.spacingS
TextInput { DankIcon {
id: customTextInput name: "text_fields"
anchors.verticalCenter: parent.verticalCenter size: 14
width: 200 color: Theme.outline
text: root.iconType === "text" ? root.currentText : "" anchors.verticalCenter: parent.verticalCenter
font.pixelSize: Theme.fontSizeSmall }
color: Theme.surfaceText
selectByMouse: true
onEditingFinished: { TextInput {
var trimmedText = text.trim() id: customTextInput
if (trimmedText) { anchors.verticalCenter: parent.verticalCenter
root.iconSelected(trimmedText, "text") width: 200
dropdownPopup.visible = false text: root.iconType === "text" ? root.currentText : ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
selectByMouse: true
onEditingFinished: {
var trimmedText = text.trim()
if (trimmedText) {
root.iconSelected(trimmedText, "text")
dropdownLoader.active = false
}
} }
} }
} }
}
StyledText { StyledText {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Theme.spacingS + 14 + Theme.spacingS anchors.leftMargin: Theme.spacingS + 14 + Theme.spacingS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: "1-2 characters" text: "1-2 characters"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.outline color: Theme.outline
opacity: 0.6 opacity: 0.6
visible: customTextInput.text === "" visible: customTextInput.text === ""
}
} }
} }
} }
}
// Icon categories // Icon categories
Repeater { Repeater {
model: root.iconCategories model: root.iconCategories
Column { Column {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: modelData.name
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText
}
Flow {
width: parent.width width: parent.width
spacing: 4 spacing: Theme.spacingS
Repeater { StyledText {
model: modelData.icons text: modelData.name
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.surfaceText
}
Rectangle { Flow {
width: 36 width: parent.width
height: 36 spacing: 4
radius: Theme.cornerRadius
color: iconMouseArea.containsMouse ? Theme.primaryHover : "transparent"
border.color: root.currentIcon === modelData ? Theme.primary : "transparent"
border.width: 2
DankIcon { Repeater {
name: modelData model: modelData.icons
size: 20
color: root.currentIcon === modelData ? Theme.primary : Theme.surfaceText
anchors.centerIn: parent
}
MouseArea { Rectangle {
id: iconMouseArea width: 36
anchors.fill: parent height: 36
hoverEnabled: true radius: Theme.cornerRadius
cursorShape: Qt.PointingHandCursor color: iconMouseArea.containsMouse ? Theme.primaryHover : "transparent"
onClicked: { border.color: root.currentIcon === modelData ? Theme.primary : "transparent"
root.iconSelected(modelData, "icon") border.width: 2
dropdownPopup.visible = false
DankIcon {
name: modelData
size: 20
color: root.currentIcon === modelData ? Theme.primary : Theme.surfaceText
anchors.centerIn: parent
} }
}
Behavior on color { MouseArea {
ColorAnimation { id: iconMouseArea
duration: Theme.shortDuration anchors.fill: parent
easing.type: Theme.standardEasing hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.iconSelected(modelData, "icon")
dropdownLoader.active = false
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
} }
} }
} }