launcher: math mode
This commit is contained in:
parent
cf072f2f14
commit
35364193e3
4 changed files with 95 additions and 8 deletions
|
|
@ -9,6 +9,10 @@
|
||||||
color: $colour;
|
color: $colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
background-color: color.change($colour, $alpha: 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
.search-bar {
|
.search-bar {
|
||||||
.mode {
|
.mode {
|
||||||
@include lib.border($colour, $width: 2);
|
@include lib.border($colour, $width: 2);
|
||||||
|
|
@ -126,6 +130,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.math {
|
||||||
|
.preview > * {
|
||||||
|
margin-bottom: lib.s(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
.result {
|
||||||
|
@include lib.spacing(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.swatches {
|
.swatches {
|
||||||
@include lib.spacing(3);
|
@include lib.spacing(3);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,9 +121,10 @@ export default class Launcher extends PopupWindow {
|
||||||
this.hook(entry, "changed", () =>
|
this.hook(entry, "changed", () =>
|
||||||
(isAction(entry.get_text()) ? actions : content[mode.get()]).updateContent(entry.get_text())
|
(isAction(entry.get_text()) ? actions : content[mode.get()]).updateContent(entry.get_text())
|
||||||
);
|
);
|
||||||
this.hook(entry, "activate", () =>
|
this.hook(entry, "activate", () => {
|
||||||
(isAction(entry.get_text()) ? actions : content[mode.get()]).handleActivate(entry.get_text())
|
(isAction(entry.get_text()) ? actions : content[mode.get()]).handleActivate(entry.get_text());
|
||||||
);
|
entry.set_text(""); // Clear search on activate
|
||||||
|
});
|
||||||
|
|
||||||
// Clear search on hide if not in math mode or creating a todo
|
// Clear search on hide if not in math mode or creating a todo
|
||||||
this.connect("hide", () => mode.get() !== "math" && !entry.text.startsWith(">todo") && entry.set_text(""));
|
this.connect("hide", () => mode.get() !== "math" && !entry.text.startsWith(">todo") && entry.set_text(""));
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import { Apps as AppsService } from "@/services/apps";
|
import { Apps as AppsService } from "@/services/apps";
|
||||||
|
import MathService, { type HistoryItem } from "@/services/math";
|
||||||
import { getAppCategoryIcon } from "@/utils/icons";
|
import { getAppCategoryIcon } from "@/utils/icons";
|
||||||
import { launch } from "@/utils/system";
|
import { launch } from "@/utils/system";
|
||||||
import { type FlowBox, setupCustomTooltip } from "@/utils/widgets";
|
import { type FlowBox, setupCustomTooltip } from "@/utils/widgets";
|
||||||
import { execAsync, Gio, register } from "astal";
|
import { bind, execAsync, Gio, register, Variable } from "astal";
|
||||||
import { Astal, Gtk, Widget } from "astal/gtk3";
|
import { Astal, Gtk, Widget } from "astal/gtk3";
|
||||||
import { launcher as config } from "config";
|
import { launcher as config } from "config";
|
||||||
import type AstalApps from "gi://AstalApps";
|
import type AstalApps from "gi://AstalApps";
|
||||||
|
|
@ -71,6 +72,28 @@ const FileResult = ({ path }: { path: string }) => (
|
||||||
</Gtk.FlowBoxChild>
|
</Gtk.FlowBoxChild>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const MathResult = ({ icon, equation, result }: HistoryItem) => (
|
||||||
|
<Gtk.FlowBoxChild visible canFocus={false}>
|
||||||
|
<button
|
||||||
|
className="result"
|
||||||
|
cursor="pointer"
|
||||||
|
onClicked={() => {
|
||||||
|
execAsync(["wl-copy", "--", result]).catch(console.error);
|
||||||
|
close();
|
||||||
|
}}
|
||||||
|
setup={self => setupCustomTooltip(self, `${equation} -> ${result}`)}
|
||||||
|
>
|
||||||
|
<box>
|
||||||
|
<label className="icon" label={icon} />
|
||||||
|
<box vertical className="has-sublabel">
|
||||||
|
<label truncate xalign={0} label={equation} />
|
||||||
|
<label truncate xalign={0} label={result} className="sublabel" />
|
||||||
|
</box>
|
||||||
|
</box>
|
||||||
|
</button>
|
||||||
|
</Gtk.FlowBoxChild>
|
||||||
|
);
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
class Apps extends Widget.Box implements LauncherContent {
|
class Apps extends Widget.Box implements LauncherContent {
|
||||||
#content: FlowBox;
|
#content: FlowBox;
|
||||||
|
|
@ -133,16 +156,65 @@ class Files extends Widget.Box implements LauncherContent {
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
class Math extends Widget.Box implements LauncherContent {
|
class Math extends Widget.Box implements LauncherContent {
|
||||||
|
#showResult: Variable<boolean>;
|
||||||
|
#result: Variable<HistoryItem>;
|
||||||
|
#content: FlowBox;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ name: "math", className: "math" });
|
super({ name: "math", className: "math", vertical: true });
|
||||||
|
|
||||||
|
this.#showResult = Variable(false);
|
||||||
|
this.#result = Variable({ equation: "", result: "", icon: "" });
|
||||||
|
this.#content = (<ContentBox />) as FlowBox;
|
||||||
|
|
||||||
|
this.add(
|
||||||
|
<revealer
|
||||||
|
transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
|
||||||
|
transitionDuration={150}
|
||||||
|
revealChild={bind(this.#showResult)}
|
||||||
|
>
|
||||||
|
<box vertical className="preview">
|
||||||
|
<box className="result">
|
||||||
|
<label className="icon" label={bind(this.#result).as(r => r.icon)} />
|
||||||
|
<box vertical>
|
||||||
|
<label xalign={0} label="Result" />
|
||||||
|
<label
|
||||||
|
truncate
|
||||||
|
xalign={0}
|
||||||
|
className="sublabel"
|
||||||
|
label={bind(this.#result).as(r => r.result)}
|
||||||
|
/>
|
||||||
|
</box>
|
||||||
|
</box>
|
||||||
|
<box className="separator" />
|
||||||
|
</box>
|
||||||
|
</revealer>
|
||||||
|
);
|
||||||
|
this.add(
|
||||||
|
<scrollable expand hscroll={Gtk.PolicyType.NEVER}>
|
||||||
|
{this.#content}
|
||||||
|
</scrollable>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateContent(search: string): void {
|
updateContent(search: string): void {
|
||||||
throw new Error("Method not implemented.");
|
this.#showResult.set(search.length > 0);
|
||||||
|
this.#result.set(MathService.get_default().evaluate(search));
|
||||||
|
|
||||||
|
this.#content.foreach(c => c.destroy());
|
||||||
|
for (const item of limitLength(MathService.get_default().history, config.math))
|
||||||
|
this.#content.add(<MathResult {...item} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleActivate(search: string): void {
|
handleActivate(search: string): void {
|
||||||
throw new Error("Method not implemented.");
|
if (!search) return;
|
||||||
|
MathService.get_default().commit();
|
||||||
|
const res = this.#result.get();
|
||||||
|
// Copy and close if not assignment, help or error
|
||||||
|
if (!["equal", "help", "error"].includes(res.icon)) {
|
||||||
|
execAsync(["wl-copy", "--", res.result]).catch(console.error);
|
||||||
|
close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export default class Math extends GObject.Object {
|
||||||
} else if (equation.includes("=")) {
|
} else if (equation.includes("=")) {
|
||||||
const [left, right] = equation.split("=");
|
const [left, right] = equation.split("=");
|
||||||
try {
|
try {
|
||||||
this.#variables[left.trim()] = simplify(right).toString();
|
this.#variables[left.trim()] = simplify(right, this.#variables).toString();
|
||||||
} catch {
|
} catch {
|
||||||
this.#variables[left.trim()] = right.trim();
|
this.#variables[left.trim()] = right.trim();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue