mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-07-31 08:44:45 +00:00
widgets/krunner: Modernize design to match app drawer, and add section headers
This MR: - Caps the maximum width of delegates and centers them - Makes the search widget style match the app drawer search bar - Adds section headers - Uses rounded delegates
This commit is contained in:
parent
fdf2ad87f6
commit
c396555509
1 changed files with 84 additions and 78 deletions
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import QtQuick.Controls as Controls
|
import QtQuick.Controls as QQC2
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
import org.kde.plasma.core as PlasmaCore
|
import org.kde.plasma.core as PlasmaCore
|
||||||
|
|
@ -18,8 +18,9 @@ import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
import org.kde.milou as Milou
|
import org.kde.milou as Milou
|
||||||
import org.kde.kirigami 2.19 as Kirigami
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
|
||||||
Item {
|
MouseArea {
|
||||||
id: root
|
id: root
|
||||||
|
onClicked: root.requestedClose()
|
||||||
|
|
||||||
function requestFocus() {
|
function requestFocus() {
|
||||||
queryField.forceActiveFocus();
|
queryField.forceActiveFocus();
|
||||||
|
|
@ -31,71 +32,62 @@ Item {
|
||||||
|
|
||||||
signal requestedClose()
|
signal requestedClose()
|
||||||
|
|
||||||
|
Keys.onPressed: (event) => {
|
||||||
|
if (event.key === Qt.Key_Escape) {
|
||||||
|
root.requestedClose();
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: column
|
id: column
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Controls.Control {
|
Kirigami.SearchField {
|
||||||
Layout.fillWidth: true
|
id: queryField
|
||||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
|
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
|
||||||
|
Layout.fillWidth: true
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.topMargin: Kirigami.Units.gridUnit
|
Layout.topMargin: Kirigami.Units.gridUnit
|
||||||
Layout.leftMargin: Kirigami.Units.gridUnit
|
Layout.leftMargin: Kirigami.Units.gridUnit
|
||||||
Layout.rightMargin: Kirigami.Units.gridUnit
|
Layout.rightMargin: Kirigami.Units.gridUnit
|
||||||
|
|
||||||
leftPadding: Kirigami.Units.smallSpacing
|
background: Rectangle {
|
||||||
rightPadding: Kirigami.Units.smallSpacing
|
radius: Kirigami.Units.cornerRadius
|
||||||
topPadding: Kirigami.Units.smallSpacing
|
color: Qt.rgba(255, 255, 255, (queryField.hovered || queryField.focus) ? 0.2 : 0.1)
|
||||||
bottomPadding: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
background: Item {
|
Behavior on color { ColorAnimation {} }
|
||||||
|
|
||||||
// shadow for search window
|
|
||||||
MultiEffect {
|
|
||||||
anchors.fill: parent
|
|
||||||
source: rectBackground
|
|
||||||
blurMax: 16
|
|
||||||
shadowEnabled: true
|
|
||||||
shadowVerticalOffset: 1
|
|
||||||
shadowOpacity: 0.15
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: rectBackground
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Kirigami.Theme.backgroundColor
|
|
||||||
radius: Kirigami.Units.cornerRadius
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: RowLayout {
|
Kirigami.Theme.inherit: false
|
||||||
Item {
|
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
|
||||||
implicitHeight: queryField.height
|
|
||||||
implicitWidth: height
|
topPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
|
||||||
Kirigami.Icon {
|
bottomPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Math.round(Kirigami.Units.smallSpacing)
|
placeholderText: i18nc("@info:placeholder", "Search…")
|
||||||
source: "start-here-symbolic"
|
placeholderTextColor: Qt.rgba(255, 255, 255, 0.8)
|
||||||
}
|
color: 'white'
|
||||||
}
|
inputMethodHints: Qt.ImhNoPredictiveText // don't need to press "enter" to update text
|
||||||
PlasmaComponents.TextField {
|
|
||||||
id: queryField
|
font.weight: Font.Bold
|
||||||
Layout.fillWidth: true
|
|
||||||
placeholderText: i18n("Search…")
|
KeyNavigation.down: listView
|
||||||
inputMethodHints: Qt.ImhNoPredictiveText // don't need to press "enter" to update text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Controls.ScrollView {
|
QQC2.ScrollView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: listView.contentHeight > availableHeight
|
Layout.fillHeight: listView.contentHeight > availableHeight
|
||||||
|
|
||||||
|
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
|
||||||
|
Layout.leftMargin: Kirigami.Units.gridUnit
|
||||||
|
Layout.rightMargin: Kirigami.Units.gridUnit
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
Milou.ResultsListView {
|
Milou.ResultsListView {
|
||||||
id: listView
|
id: listView
|
||||||
queryString: queryField.text
|
queryString: queryField.text
|
||||||
clip: true
|
clip: true
|
||||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
|
||||||
|
|
||||||
highlight: activeFocus ? highlightComponent : null
|
highlight: activeFocus ? highlightComponent : null
|
||||||
Component {
|
Component {
|
||||||
|
|
@ -112,11 +104,53 @@ Item {
|
||||||
queryField.cursorPosition = cursorPosition
|
queryField.cursorPosition = cursorPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section.delegate: QQC2.Control {
|
||||||
|
id: sectionHeader
|
||||||
|
required property string section
|
||||||
|
|
||||||
|
topPadding: Kirigami.Units.smallSpacing
|
||||||
|
bottomPadding: Kirigami.Units.smallSpacing
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
|
||||||
|
contentItem: Kirigami.Heading {
|
||||||
|
opacity: 0.7
|
||||||
|
level: 5
|
||||||
|
type: Kirigami.Heading.Primary
|
||||||
|
text: sectionHeader.section
|
||||||
|
elide: Text.ElideRight
|
||||||
|
color: 'white'
|
||||||
|
|
||||||
|
// we override the Primary type's font weight (DemiBold) for Bold for contrast with small text
|
||||||
|
font.weight: Font.Bold
|
||||||
|
Accessible.ignored: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
delegate: MouseArea {
|
delegate: MouseArea {
|
||||||
id: delegate
|
id: delegate
|
||||||
height: rowLayout.height
|
height: rowLayout.height
|
||||||
width: listView.width
|
width: listView.width
|
||||||
|
|
||||||
|
// Go to search bar if this we press up with the first item selected
|
||||||
|
KeyNavigation.up: model.index === 0 ? queryField : null
|
||||||
|
|
||||||
|
// Close search view if we press down with last item selected
|
||||||
|
Keys.onPressed: (event) => {
|
||||||
|
if (event.key === Qt.Key_Down && (model.index === listView.count - 1)) {
|
||||||
|
root.requestedClose();
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by ResultsListView to determine next tab action
|
||||||
|
function activateNextAction() {
|
||||||
|
queryField.forceActiveFocus();
|
||||||
|
queryField.selectAll();
|
||||||
|
listView.currentIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
listView.currentIndex = model.index;
|
listView.currentIndex = model.index;
|
||||||
listView.runCurrentIndex();
|
listView.runCurrentIndex();
|
||||||
|
|
@ -125,18 +159,10 @@ Item {
|
||||||
}
|
}
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
function activateNextAction() {
|
|
||||||
queryField.forceActiveFocus();
|
|
||||||
queryField.selectAll();
|
|
||||||
listView.currentIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: delegate.pressed ? Qt.rgba(255, 255, 255, 0.2) : (delegate.containsMouse ? Qt.rgba(255, 255, 255, 0.05) : "transparent")
|
radius: Kirigami.Units.cornerRadius
|
||||||
Behavior on color {
|
color: delegate.pressed ? Qt.rgba(255, 255, 255, 0.3) : (delegate.containsMouse ? Qt.rgba(255, 255, 255, 0.1) : "transparent")
|
||||||
ColorAnimation { duration: Kirigami.Units.shortDuration }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -146,8 +172,8 @@ Item {
|
||||||
top: parent.top
|
top: parent.top
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
leftMargin: Kirigami.Units.gridUnit
|
leftMargin: Kirigami.Units.largeSpacing
|
||||||
rightMargin: Kirigami.Units.gridUnit
|
rightMargin: Kirigami.Units.largeSpacing
|
||||||
}
|
}
|
||||||
|
|
||||||
Kirigami.Icon {
|
Kirigami.Icon {
|
||||||
|
|
@ -190,34 +216,14 @@ Item {
|
||||||
font.pointSize: Math.round(Kirigami.Theme.defaultFont.pointSize * 0.8)
|
font.pointSize: Math.round(Kirigami.Theme.defaultFont.pointSize * 0.8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: actionsRepeater
|
|
||||||
model: typeof actions !== "undefined" ? actions : []
|
|
||||||
|
|
||||||
Controls.ToolButton {
|
|
||||||
icon: modelData.icon || ""
|
|
||||||
visible: modelData.visible || true
|
|
||||||
enabled: modelData.enabled || true
|
|
||||||
|
|
||||||
Accessible.role: Accessible.Button
|
|
||||||
Accessible.name: modelData.text
|
|
||||||
checkable: checked
|
|
||||||
checked: delegate.activeAction === index
|
|
||||||
focus: delegate.activeAction === index
|
|
||||||
onClicked: delegate.ListView.view.runAction(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
onClicked: root.requestedClose()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue