Files
illogical-impulse/dots/.config/quickshell/ii/modules/overview/SearchBar.qml
T
2025-11-06 22:59:09 +01:00

153 lines
6.2 KiB
QML

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 forceFocus() {
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.topMargin: 4
Layout.bottomMargin: 4
implicitHeight: 40
focus: GlobalStates.overviewOpen
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();
}
}
}
}
IconToolbarButton {
Layout.topMargin: 4
Layout.bottomMargin: 4
onClicked: {
GlobalStates.overviewOpen = false;
Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "region", "search"]);
}
text: "image_search"
StyledToolTip {
text: Translation.tr("Google Lens")
}
}
IconToolbarButton {
id: songRecButton
Layout.topMargin: 4
Layout.bottomMargin: 4
Layout.rightMargin: 4
toggled: SongRec.running
onClicked: SongRec.toggleRunning()
text: "music_cast"
StyledToolTip {
text: Translation.tr("Recognize music")
}
colText: toggled ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSurfaceVariant
background: MaterialShape {
RotationAnimation on rotation {
running: songRecButton.toggled
duration: 12000
easing.type: Easing.Linear
loops: Animation.Infinite
from: 0
to: 360
}
shape: {
if (songRecButton.down) {
return songRecButton.toggled ? MaterialShape.Shape.Circle : MaterialShape.Shape.Square
} else {
return songRecButton.toggled ? MaterialShape.Shape.SoftBurst : MaterialShape.Shape.Circle
}
}
color: {
if (songRecButton.toggled) {
return songRecButton.hovered ? Appearance.colors.colPrimaryHover : Appearance.colors.colPrimary
} else {
return songRecButton.hovered ? Appearance.colors.colSurfaceContainerHigh : ColorUtils.transparentize(Appearance.colors.colSurfaceContainerHigh)
}
}
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
}
}