overview: fancier search bar

This commit is contained in:
end-4
2025-10-30 22:20:06 +01:00
parent db79ecd636
commit dbd12d3e92
5 changed files with 156 additions and 93 deletions
@@ -0,0 +1,111 @@
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
import Qt5Compat.GraphicalEffects
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
RowLayout {
id: root
spacing: 6
property bool animateWidth: false
property alias searchInput: searchInput
property string searchingText
function focus() {
searchInput.forceActiveFocus();
}
enum SearchPrefixType { Action, App, Clipboard, Emojis, Math, ShellCommand, WebSearch, DefaultSearch }
property var searchPrefixType: {
if (root.searchingText.startsWith(Config.options.search.prefix.action)) return SearchBar.SearchPrefixType.Action;
if (root.searchingText.startsWith(Config.options.search.prefix.app)) return SearchBar.SearchPrefixType.App;
if (root.searchingText.startsWith(Config.options.search.prefix.clipboard)) return SearchBar.SearchPrefixType.Clipboard;
if (root.searchingText.startsWith(Config.options.search.prefix.emojis)) return SearchBar.SearchPrefixType.Emojis;
if (root.searchingText.startsWith(Config.options.search.prefix.math)) return SearchBar.SearchPrefixType.Math;
if (root.searchingText.startsWith(Config.options.search.prefix.shellCommand)) return SearchBar.SearchPrefixType.ShellCommand;
if (root.searchingText.startsWith(Config.options.search.prefix.webSearch)) return SearchBar.SearchPrefixType.WebSearch;
return SearchBar.SearchPrefixType.DefaultSearch;
}
MaterialShapeWrappedMaterialSymbol {
id: searchIcon
Layout.alignment: Qt.AlignVCenter
iconSize: Appearance.font.pixelSize.huge
shape: switch(root.searchPrefixType) {
case SearchBar.SearchPrefixType.Action: return MaterialShape.Shape.Pill;
case SearchBar.SearchPrefixType.App: return MaterialShape.Shape.Clover4Leaf;
case SearchBar.SearchPrefixType.Clipboard: return MaterialShape.Shape.Gem;
case SearchBar.SearchPrefixType.Emojis: return MaterialShape.Shape.Sunny;
case SearchBar.SearchPrefixType.Math: return MaterialShape.Shape.PuffyDiamond;
case SearchBar.SearchPrefixType.ShellCommand: return MaterialShape.Shape.PixelCircle;
case SearchBar.SearchPrefixType.WebSearch: return MaterialShape.Shape.SoftBurst;
default: return MaterialShape.Shape.Cookie7Sided;
}
text: switch (root.searchPrefixType) {
case SearchBar.SearchPrefixType.Action: return "settings_suggest";
case SearchBar.SearchPrefixType.App: return "apps";
case SearchBar.SearchPrefixType.Clipboard: return "content_paste_search";
case SearchBar.SearchPrefixType.Emojis: return "add_reaction";
case SearchBar.SearchPrefixType.Math: return "calculate";
case SearchBar.SearchPrefixType.ShellCommand: return "terminal";
case SearchBar.SearchPrefixType.WebSearch: return "travel_explore";
case SearchBar.SearchPrefixType.DefaultSearch: return "search";
default: return "search";
}
}
ToolbarTextField { // Search box
id: searchInput
Layout.alignment: Qt.AlignVCenter
focus: GlobalStates.overviewOpen
padding: 15
font.pixelSize: Appearance.font.pixelSize.small
placeholderText: Translation.tr("Search, calculate or run")
implicitWidth: root.searchingText == "" ? Appearance.sizes.searchWidthCollapsed : Appearance.sizes.searchWidth
Behavior on implicitWidth {
id: searchWidthBehavior
enabled: root.animateWidth
NumberAnimation {
duration: 300
easing.type: Appearance.animation.elementMove.type
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
}
}
onTextChanged: root.searchingText = text
onAccepted: {
if (appResults.count > 0) {
// Get the first visible delegate and trigger its click
let firstItem = appResults.itemAtIndex(0);
if (firstItem && firstItem.clicked) {
firstItem.clicked();
}
}
}
// background: null
cursorDelegate: Rectangle {
width: 1
color: searchInput.activeFocus ? Appearance.colors.colPrimary : "transparent"
radius: 1
}
}
IconToolbarButton {
onClicked: {
GlobalStates.overviewOpen = false;
Hyprland.dispatch("global quickshell:regionSearch")
}
text: "image_search"
}
}