mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-16 16:24:00 -04:00
144 lines
5.0 KiB
QML
144 lines
5.0 KiB
QML
import QtQuick
|
|
import qs.Common
|
|
import qs.DCommon.Widgets
|
|
|
|
DSearchField {
|
|
id: root
|
|
|
|
property string mode: "all"
|
|
property bool showModes: false
|
|
property string pluginName: ""
|
|
property string pluginIcon: ""
|
|
property bool pluginIconVisible: true
|
|
property bool flat: false
|
|
readonly property var modes: [
|
|
{
|
|
"label": I18n.tr("All"),
|
|
"mode": "all"
|
|
},
|
|
{
|
|
"label": I18n.tr("Apps", "launcher mode tab, short for applications"),
|
|
"mode": "apps"
|
|
},
|
|
{
|
|
"label": I18n.tr("Files"),
|
|
"mode": "files"
|
|
},
|
|
{
|
|
"label": I18n.tr("Plugins"),
|
|
"mode": "plugins"
|
|
}
|
|
]
|
|
readonly property int modeIndex: Math.max(0, modes.findIndex(entry => entry.mode === root.mode))
|
|
signal modeSelected(string mode)
|
|
|
|
function revealMode() {
|
|
const chip = chips.children.find(child => child.index === root.modeIndex);
|
|
if (!chip)
|
|
return;
|
|
const left = chip.x;
|
|
const right = left + chip.width;
|
|
const maxX = Math.max(0, modeViewport.contentWidth - modeViewport.width);
|
|
if (left < modeViewport.contentX) {
|
|
modeViewport.contentX = Math.max(0, left);
|
|
return;
|
|
}
|
|
if (right > modeViewport.contentX + modeViewport.width)
|
|
modeViewport.contentX = Math.min(maxX, right - modeViewport.width);
|
|
}
|
|
|
|
onModeIndexChanged: revealTimer.restart()
|
|
|
|
Timer {
|
|
id: revealTimer
|
|
interval: 0
|
|
onTriggered: root.revealMode()
|
|
}
|
|
|
|
height: LauncherMetrics.pillHeight
|
|
textColor: Theme.onSurface
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
backgroundColor: flat ? "transparent" : Theme.chipSurface
|
|
normalBorderColor: flat ? "transparent" : Theme.outlineVariant
|
|
leadingContent: pluginName ? pluginBadge : null
|
|
rightAccessoryWidth: modeViewport.visible ? modeViewport.width + Theme.spacingS : 0
|
|
|
|
Component {
|
|
id: pluginBadge
|
|
|
|
Rectangle {
|
|
implicitWidth: pluginLabel.implicitWidth + (root.pluginIconVisible ? Theme.chipIconSize + Theme.spacingS : 0) + Theme.spacingM * 2
|
|
width: Math.min(implicitWidth, Math.max(0, root.width - root.contentPadding - LauncherMetrics.minSearchWidth - root.accessorySize - Theme.spacingS * 3))
|
|
height: Theme.buttonHeightXS
|
|
radius: Theme.fullRadius(width, height)
|
|
color: Theme.primaryContainer
|
|
clip: true
|
|
|
|
DIcon {
|
|
id: pluginIconGlyph
|
|
visible: root.pluginIconVisible
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: Theme.spacingM
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
name: root.pluginIcon || "extension"
|
|
size: Theme.chipIconSize
|
|
color: Theme.onPrimaryContainer
|
|
}
|
|
|
|
StyledText {
|
|
id: pluginLabel
|
|
anchors.left: root.pluginIconVisible ? pluginIconGlyph.right : parent.left
|
|
anchors.leftMargin: root.pluginIconVisible ? Theme.spacingS : Theme.spacingM
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: Theme.spacingM
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: root.pluginName
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
font.weight: Theme.fontWeightMedium
|
|
color: Theme.onPrimaryContainer
|
|
wrapMode: Text.NoWrap
|
|
elide: I18n.isRtl ? Text.ElideLeft : Text.ElideRight
|
|
maximumLineCount: 1
|
|
}
|
|
}
|
|
}
|
|
|
|
DFlickable {
|
|
id: modeViewport
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: Theme.spacingM
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: Math.min(chips.implicitWidth, Math.max(0, root.width - LauncherMetrics.minSearchWidth - root.leftPadding - root.accessorySize - Theme.spacingS * 3))
|
|
height: LauncherMetrics.modeChipHeight
|
|
visible: root.showModes && !root.pluginName && width > 0
|
|
onWidthChanged: revealTimer.restart()
|
|
contentWidth: chips.implicitWidth
|
|
contentHeight: height
|
|
flickableDirection: Flickable.HorizontalFlick
|
|
clip: true
|
|
|
|
DFilterChips {
|
|
id: chips
|
|
width: implicitWidth
|
|
flow: Flow.TopToBottom
|
|
height: chipHeight
|
|
chipHeight: LauncherMetrics.modeChipHeight
|
|
chipRadius: Theme.fullRadius(chipHeight, chipHeight)
|
|
spacing: Theme.spacingXS
|
|
model: root.modes
|
|
Binding on currentIndex {
|
|
value: root.modeIndex
|
|
restoreMode: Binding.RestoreNone
|
|
}
|
|
showCheck: false
|
|
chipPadding: Theme.spacingM
|
|
activeFocusOnTab: false
|
|
onPositioningComplete: revealTimer.restart()
|
|
onSelectionChanged: index => {
|
|
root.modeSelected(root.modes[index].mode);
|
|
root.forceActiveFocus();
|
|
}
|
|
}
|
|
}
|
|
}
|