mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 14:59:27 -05:00
waffles: start: more search progress
This commit is contained in:
@@ -64,7 +64,7 @@ Singleton {
|
||||
property color bg0: "#1C1C1C"
|
||||
property color bg0Border: "#404040"
|
||||
property color bg1Base: "#2C2C2C"
|
||||
property color bg1: "#a8a8a8"
|
||||
property color bg1: '#9f9f9f'
|
||||
property color bg1Hover: "#b3b3b3"
|
||||
property color bg1Active: '#727272'
|
||||
property color bg1Border: '#bebebe'
|
||||
@@ -125,6 +125,7 @@ Singleton {
|
||||
property color accentUnfocused: root.dark ? root.darkColors.accentUnfocused : root.lightColors.accentUnfocused
|
||||
property color accentFg: ColorUtils.isDark(accent) ? "#FFFFFF" : "#000000"
|
||||
property color selection: Appearance.colors.colPrimaryContainer
|
||||
property color selectionFg: Appearance.colors.colOnPrimaryContainer
|
||||
}
|
||||
|
||||
radius: QtObject {
|
||||
|
||||
@@ -44,6 +44,7 @@ WButton {
|
||||
radius: Looks.radius.medium
|
||||
color: root.color
|
||||
Behavior on color {
|
||||
enabled: root.animateChoiceHighlight
|
||||
animation: Looks.transition.color.createObject(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,17 +14,18 @@ Menu {
|
||||
property bool downDirection: false
|
||||
property bool hasIcons: false // TODO: implement
|
||||
|
||||
implicitWidth: background.implicitWidth + root.padding * 2
|
||||
implicitHeight: background.implicitHeight + root.padding * 2
|
||||
implicitWidth: background.implicitWidth + margins * 2
|
||||
implicitHeight: background.implicitHeight + margins * 2
|
||||
margins: 10
|
||||
padding: 3
|
||||
property real sourceEdgeMargin: -implicitHeight
|
||||
clip: true
|
||||
|
||||
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "sourceEdgeMargin"
|
||||
from: -root.implicitHeight
|
||||
to: root.padding
|
||||
to: root.margins
|
||||
duration: 200
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn
|
||||
@@ -33,7 +34,7 @@ Menu {
|
||||
exit: Transition {
|
||||
NumberAnimation {
|
||||
property: "sourceEdgeMargin"
|
||||
from: root.padding
|
||||
from: root.margins
|
||||
to: -root.implicitHeight
|
||||
duration: 150
|
||||
easing.type: Easing.BezierSpline
|
||||
@@ -41,43 +42,55 @@ Menu {
|
||||
}
|
||||
}
|
||||
|
||||
background: WPane {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: root.downDirection ? parent.top : undefined
|
||||
bottom: root.downDirection ? undefined : parent.bottom
|
||||
margins: root.padding
|
||||
topMargin: root.downDirection ? root.sourceEdgeMargin : root.padding
|
||||
bottomMargin: root.downDirection ? root.padding : root.sourceEdgeMargin
|
||||
}
|
||||
contentItem: Rectangle {
|
||||
color: Looks.colors.bg1Base
|
||||
implicitWidth: menuListView.implicitWidth + root.padding * 2
|
||||
implicitHeight: root.contentItem.implicitHeight + root.padding * 2
|
||||
background: Item {
|
||||
id: bgItem
|
||||
implicitWidth: bgPane.implicitWidth
|
||||
implicitHeight: bgPane.implicitHeight
|
||||
WPane {
|
||||
id: bgPane
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: root.downDirection ? parent.top : undefined
|
||||
bottom: root.downDirection ? undefined : parent.bottom
|
||||
margins: root.margins
|
||||
topMargin: root.downDirection ? root.sourceEdgeMargin : root.margins
|
||||
bottomMargin: root.downDirection ? root.margins : root.sourceEdgeMargin
|
||||
}
|
||||
contentItem: Rectangle {
|
||||
color: Looks.colors.bg1Base
|
||||
implicitWidth: menuListView.implicitWidth + root.padding * 2
|
||||
implicitHeight: root.contentItem.implicitHeight + root.padding * 2
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: ListView {
|
||||
id: menuListView
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: root.downDirection ? parent.top : undefined
|
||||
bottom: root.downDirection ? undefined : parent.bottom
|
||||
margins: root.padding * 2
|
||||
topMargin: root.downDirection ? root.sourceEdgeMargin : root.padding
|
||||
bottomMargin: root.downDirection ? root.padding : root.sourceEdgeMargin
|
||||
}
|
||||
implicitHeight: contentHeight
|
||||
implicitWidth: Array.from({
|
||||
length: count
|
||||
}, (_, i) => itemAtIndex(i)?.implicitWidth ?? 0).reduce((a, b) => a > b ? a : b)
|
||||
contentItem: Item {
|
||||
implicitWidth: menuListView.implicitWidth
|
||||
implicitHeight: menuListView.implicitHeight
|
||||
ListView {
|
||||
id: menuListView
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: root.downDirection ? parent.top : undefined
|
||||
bottom: root.downDirection ? undefined : parent.bottom
|
||||
margins: root.margins // ????
|
||||
topMargin: root.downDirection ? root.sourceEdgeMargin : root.margins
|
||||
bottomMargin: root.downDirection ? root.margins : root.sourceEdgeMargin
|
||||
}
|
||||
implicitHeight: contentHeight
|
||||
implicitWidth: Array.from({
|
||||
length: count
|
||||
}, (_, i) => itemAtIndex(i)?.implicitWidth ?? 0).reduce((a, b) => a > b ? a : b)
|
||||
|
||||
model: root.contentModel
|
||||
model: root.contentModel
|
||||
}
|
||||
}
|
||||
|
||||
delegate: WMenuItem {
|
||||
id: menuItemDelegate
|
||||
width: ListView.view?.width
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,17 @@ WButton {
|
||||
id: root
|
||||
|
||||
property alias iconName: iconContent.icon
|
||||
property alias iconSize: iconContent.implicitSize
|
||||
property alias monochrome: iconContent.monochrome
|
||||
implicitWidth: 40
|
||||
implicitHeight: 40
|
||||
|
||||
contentItem: FluentIcon {
|
||||
id: iconContent
|
||||
anchors.centerIn: parent
|
||||
implicitSize: 18
|
||||
icon: root.iconName
|
||||
contentItem: Item {
|
||||
FluentIcon {
|
||||
id: iconContent
|
||||
anchors.centerIn: parent
|
||||
implicitSize: 18
|
||||
icon: root.iconName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,5 @@ TextInput {
|
||||
}
|
||||
|
||||
selectionColor: Looks.colors.selection
|
||||
selectedTextColor: Looks.colors.selectionFg
|
||||
}
|
||||
|
||||
@@ -12,26 +12,36 @@ import qs.modules.waffle.looks
|
||||
FooterRectangle {
|
||||
id: root
|
||||
|
||||
property real horizontalPadding: 32
|
||||
property real verticalPadding: 16
|
||||
property bool searching: text.length > 0
|
||||
property alias text: searchInput.text
|
||||
implicitHeight: outline.implicitHeight + verticalPadding * 2
|
||||
|
||||
Component.onCompleted: searchInput.forceActiveFocus()
|
||||
|
||||
focus: true
|
||||
color: searching ? Looks.colors.bgPanelBody : Looks.colors.bgPanelFooter
|
||||
|
||||
implicitWidth: 832 // TODO: Make sizes naturally inferred
|
||||
implicitHeight: 63
|
||||
Behavior on horizontalPadding {
|
||||
enabled: Config.options.waffles.tweaks.smootherSearchBar
|
||||
animation: Looks.transition.move.createObject(this)
|
||||
}
|
||||
Behavior on verticalPadding {
|
||||
enabled: Config.options.waffles.tweaks.smootherSearchBar
|
||||
animation: Looks.transition.move.createObject(this)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: outline
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 32
|
||||
rightMargin: 32
|
||||
topMargin: 16
|
||||
bottomMargin: 15
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: root.horizontalPadding
|
||||
rightMargin: root.horizontalPadding
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
implicitHeight: 32
|
||||
color: "transparent"
|
||||
radius: height / 2
|
||||
border.width: 1
|
||||
|
||||
@@ -12,5 +12,25 @@ import qs.modules.waffle.looks
|
||||
BodyRectangle {
|
||||
id: root
|
||||
|
||||
|
||||
property string searchText: LauncherSearch.query
|
||||
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: 2
|
||||
leftMargin: 24
|
||||
rightMargin: 24
|
||||
}
|
||||
spacing: 12
|
||||
|
||||
TagStrip {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
}
|
||||
|
||||
SearchResults {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import qs.modules.waffle.looks
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common
|
||||
import qs.services
|
||||
import qs
|
||||
import Quickshell
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
|
||||
function focusFirstItem() {
|
||||
resultList.currentIndex = 0;
|
||||
}
|
||||
|
||||
ResultList {
|
||||
id: resultList
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
ResultPreview {
|
||||
Layout.preferredWidth: 386
|
||||
Layout.leftMargin: 1
|
||||
Layout.rightMargin: 1
|
||||
}
|
||||
|
||||
component ResultList: ListView {
|
||||
section {
|
||||
criteria: ViewSection.FullString
|
||||
property: "type"
|
||||
}
|
||||
clip: true
|
||||
spacing: 4
|
||||
model: ScriptModel {
|
||||
values: {
|
||||
// TODO: categorize and have max per category
|
||||
LauncherSearch.results.slice(0, 10)
|
||||
}
|
||||
onValuesChanged: {
|
||||
root.focusFirstItem();
|
||||
}
|
||||
}
|
||||
delegate: WSearchResultButton {
|
||||
required property int index
|
||||
required property var modelData
|
||||
entry: modelData
|
||||
firstEntry: index === 0
|
||||
width: ListView.view?.width
|
||||
}
|
||||
}
|
||||
|
||||
component ResultPreview: Rectangle {
|
||||
Layout.fillHeight: true
|
||||
color: Looks.colors.bg1
|
||||
radius: Looks.radius.large
|
||||
}
|
||||
}
|
||||
@@ -14,26 +14,43 @@ WBarAttachedPanelContent {
|
||||
id: root
|
||||
|
||||
property bool searching: false
|
||||
property string searchText: ""
|
||||
property string searchText: LauncherSearch.query
|
||||
|
||||
contentItem: WPane {
|
||||
contentItem: WPanelPageColumn {
|
||||
SearchBar {
|
||||
focus: true
|
||||
Layout.fillWidth: true
|
||||
implicitWidth: 832 // TODO: Make sizes naturally inferred
|
||||
horizontalPadding: root.searching ? 24 : 32
|
||||
// verticalPadding: root.searching ? 32 : 16 // TODO: make this not nuke the panel
|
||||
Synchronizer on searching {
|
||||
property alias target: root.searching
|
||||
}
|
||||
Synchronizer on text {
|
||||
property alias source: root.searchText
|
||||
text: root.searchText
|
||||
onTextChanged: {
|
||||
LauncherSearch.query = text;
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: pageContentLoader
|
||||
Item {
|
||||
implicitHeight: root.searching ? 736 : 736 // TODO: Make sizes naturally inferred
|
||||
Layout.fillWidth: true
|
||||
source: root.searching ? "SearchPageContent.qml" : "StartPageContent.qml"
|
||||
Loader {
|
||||
id: pageContentLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: root.searching ? searchPageComp : startPageComp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Component {
|
||||
id: searchPageComp
|
||||
SearchPageContent {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: startPageComp
|
||||
StartPageContent {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ WPanelPageColumn {
|
||||
WPanelSeparator {}
|
||||
|
||||
BodyRectangle {
|
||||
implicitHeight: 736 // TODO: Make sizes naturally inferred
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
WPanelSeparator {}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
RowLayout {
|
||||
WPanelIconButton {
|
||||
implicitWidth: 36
|
||||
implicitHeight: 36
|
||||
iconSize: 24
|
||||
iconName: "arrow-left"
|
||||
onClicked: LauncherSearch.query = ""
|
||||
}
|
||||
ListView {
|
||||
id: tagListView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
orientation: Qt.Horizontal
|
||||
spacing: 4
|
||||
model: [
|
||||
{
|
||||
name: Translation.tr("All"),
|
||||
prefix: ""
|
||||
},
|
||||
{
|
||||
name: Translation.tr("Apps"),
|
||||
prefix: Config.options.search.prefix.app
|
||||
},
|
||||
{
|
||||
name: Translation.tr("Actions"),
|
||||
prefix: Config.options.search.prefix.action
|
||||
},
|
||||
{
|
||||
name: Translation.tr("Clipboard"),
|
||||
prefix: Config.options.search.prefix.clipboard
|
||||
},
|
||||
{
|
||||
name: Translation.tr("Emojis"),
|
||||
prefix: Config.options.search.prefix.emojis
|
||||
},
|
||||
{
|
||||
name: Translation.tr("Math"),
|
||||
prefix: Config.options.search.prefix.math
|
||||
},
|
||||
{
|
||||
name: Translation.tr("Commands"),
|
||||
prefix: Config.options.search.prefix.shellCommand
|
||||
},
|
||||
{
|
||||
name: Translation.tr("Web"),
|
||||
prefix: Config.options.search.prefix.webSearch
|
||||
},
|
||||
]
|
||||
delegate: WBorderedButton {
|
||||
id: tagButton
|
||||
required property var modelData
|
||||
border.width: 1
|
||||
radius: height / 2
|
||||
implicitWidth: tagButtonText.implicitWidth + 12 * 2
|
||||
implicitHeight: 32
|
||||
checked: {
|
||||
if (modelData.prefix != "") {
|
||||
return LauncherSearch.query.startsWith(modelData.prefix);
|
||||
} else {
|
||||
return !tagListView.model.some(i => (i.prefix != "" && LauncherSearch.query.startsWith(i.prefix)))
|
||||
}
|
||||
}
|
||||
contentItem: Item {
|
||||
WText {
|
||||
id: tagButtonText
|
||||
anchors.centerIn: parent
|
||||
color: tagButton.fgColor
|
||||
text: tagButton.modelData.name
|
||||
font.pixelSize: Looks.font.pixelSize.large
|
||||
}
|
||||
}
|
||||
onClicked: LauncherSearch.ensurePrefix(tagButton.modelData.prefix)
|
||||
}
|
||||
}
|
||||
WPanelIconButton {
|
||||
implicitWidth: 36
|
||||
implicitHeight: 36
|
||||
iconSize: 24
|
||||
iconName: "more-horizontal"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.models
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
WChoiceButton {
|
||||
id: root
|
||||
|
||||
required property LauncherSearchResult entry
|
||||
property bool firstEntry: false
|
||||
|
||||
checked: focus
|
||||
animateChoiceHighlight: false
|
||||
implicitWidth: contentLayout.implicitWidth + leftPadding + rightPadding
|
||||
implicitHeight: contentLayout.implicitHeight + topPadding + bottomPadding
|
||||
|
||||
onClicked: {
|
||||
GlobalStates.searchOpen = false
|
||||
root.entry.execute()
|
||||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
id: contentLayout
|
||||
spacing: 8
|
||||
|
||||
EntryIcon {}
|
||||
EntryNameColumn {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
component EntryIcon: Item {
|
||||
implicitWidth: 24
|
||||
implicitHeight: 24
|
||||
Loader {
|
||||
anchors.centerIn: parent
|
||||
active: root.entry.iconType === LauncherSearchResult.IconType.System
|
||||
sourceComponent: WAppIcon {
|
||||
implicitSize: 24
|
||||
tryCustomIcon: false
|
||||
iconName: root.entry.iconName
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
anchors.centerIn: parent
|
||||
active: root.entry.iconType === LauncherSearchResult.IconType.Text
|
||||
sourceComponent: WText {
|
||||
text: root.entry.iconName
|
||||
font.pixelSize: 24
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component EntryNameColumn: ColumnLayout {
|
||||
spacing: 4
|
||||
|
||||
WText {
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.Wrap
|
||||
text: root.entry.name
|
||||
font.pixelSize: Looks.font.pixelSize.large
|
||||
maximumLineCount: 2
|
||||
}
|
||||
|
||||
WText {
|
||||
Layout.fillWidth: true
|
||||
visible: root.firstEntry
|
||||
text: root.entry.type
|
||||
color: Looks.colors.accentUnfocused
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user