summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-02-28 12:48:42 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-02-28 12:48:42 +1100
commit5cf36b005814ee254271648691513d5361096649 (patch)
treee8dea19f804586b07f6804b9bf2366d7303fb624 /src/modules
parentlauncher: made search bar + mode switcher (diff)
downloadcaelestia-shell-5cf36b005814ee254271648691513d5361096649.tar.gz
caelestia-shell-5cf36b005814ee254271648691513d5361096649.tar.bz2
caelestia-shell-5cf36b005814ee254271648691513d5361096649.zip
launcher: apps mode
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/launcher.tsx82
1 files changed, 72 insertions, 10 deletions
diff --git a/src/modules/launcher.tsx b/src/modules/launcher.tsx
index 356b6d4..b6af58e 100644
--- a/src/modules/launcher.tsx
+++ b/src/modules/launcher.tsx
@@ -1,6 +1,11 @@
+import { Apps as AppsService } from "@/services/apps";
+import { getAppCategoryIcon } from "@/utils/icons";
+import { launch } from "@/utils/system";
+import { FlowBox } from "@/utils/widgets";
import PopupWindow from "@/widgets/popupwindow";
import { bind, register, Variable } from "astal";
-import { Astal, Gtk, Widget } from "astal/gtk3";
+import { App, Astal, Gtk, Widget } from "astal/gtk3";
+import type AstalApps from "gi://AstalApps";
type Mode = "apps" | "files" | "math" | "windows";
@@ -9,25 +14,77 @@ interface ModeContent {
handleActivate(search: string): void;
}
+const close = () => App.get_window("launcher")?.hide();
+
+const getModeIcon = (mode: Mode) => {
+ if (mode === "apps") return "apps";
+ if (mode === "files") return "folder";
+ if (mode === "math") return "calculate";
+ if (mode === "windows") return "select_window";
+ return "search";
+};
+
+const getPrettyMode = (mode: Mode) => {
+ if (mode === "apps") return "Apps";
+ if (mode === "files") return "Files";
+ if (mode === "math") return "Math";
+ if (mode === "windows") return "Windows";
+ return mode;
+};
+
+const AppResult = ({ app }: { app: AstalApps.Application }) => (
+ <Gtk.FlowBoxChild visible canFocus={false}>
+ <button
+ className="result"
+ cursor="pointer"
+ onClicked={() => {
+ launch(app);
+ close();
+ }}
+ >
+ <box>
+ {app.iconName && Astal.Icon.lookup_icon(app.iconName) ? (
+ <icon className="icon" icon={app.iconName} />
+ ) : (
+ <label className="icon" label={getAppCategoryIcon(app)} />
+ )}
+ <label truncate label={app.name} />
+ </box>
+ </button>
+ </Gtk.FlowBoxChild>
+);
+
@register()
class Apps extends Widget.Box implements ModeContent {
+ #content: FlowBox;
+
constructor() {
- super({ name: "apps" });
+ super({ name: "apps", className: "apps" });
+
+ this.#content = (<FlowBox homogeneous valign={Gtk.Align.START} maxChildrenPerLine={2} />) as FlowBox;
+
+ this.add(
+ <scrollable expand hscroll={Gtk.PolicyType.NEVER}>
+ {this.#content}
+ </scrollable>
+ );
}
updateContent(search: string): void {
- throw new Error("Method not implemented.");
+ this.#content.foreach(c => c.destroy());
+ AppsService.fuzzy_query(search).forEach(app => this.#content.add(<AppResult app={app} />));
}
- handleActivate(search: string): void {
- throw new Error("Method not implemented.");
+ handleActivate(): void {
+ this.#content.get_child_at_index(0)?.get_child()?.grab_focus();
+ this.#content.get_child_at_index(0)?.get_child()?.activate();
}
}
@register()
class Files extends Widget.Box implements ModeContent {
constructor() {
- super({ name: "files" });
+ super({ name: "files", className: "files" });
}
updateContent(search: string): void {
@@ -42,7 +99,7 @@ class Files extends Widget.Box implements ModeContent {
@register()
class Math extends Widget.Box implements ModeContent {
constructor() {
- super({ name: "math" });
+ super({ name: "math", className: "math" });
}
updateContent(search: string): void {
@@ -57,7 +114,7 @@ class Math extends Widget.Box implements ModeContent {
@register()
class Windows extends Widget.Box implements ModeContent {
constructor() {
- super({ name: "windows" });
+ super({ name: "windows", className: "windows" });
}
updateContent(search: string): void {
@@ -83,8 +140,12 @@ const ModeSwitcher = ({ mode, modes }: { mode: Variable<Mode>; modes: Mode[] })
className={bind(mode).as(c => `mode ${c === m ? "selected" : ""}`)}
cursor="pointer"
onClicked={() => mode.set(m)}
- label={m}
- />
+ >
+ <box halign={Gtk.Align.CENTER}>
+ <label className="icon" label={getModeIcon(m)} />
+ <label label={getPrettyMode(m)} />
+ </box>
+ </button>
))}
</box>
);
@@ -144,6 +205,7 @@ export default class Launcher extends PopupWindow {
this.mode = mode;
+ content[mode.get()].updateContent(entry.get_text());
this.hook(mode, (_, v: Mode) => {
entry.set_text("");
content[v].updateContent(entry.get_text());