summaryrefslogtreecommitdiff
path: root/examples/gtk3
diff options
context:
space:
mode:
authorAylur <[email protected]>2025-01-23 17:58:38 +0100
committerAylur <[email protected]>2025-01-23 17:58:53 +0100
commit9cadfed0e4e541b8a65f4083800da6bf25c965da (patch)
tree0466d40abf0fd01b931464a3ab3bdd329b17d76f /examples/gtk3
parent9a83bcd2bd33ee95a69069d07c56bedec05c7d02 (diff)
update popover example
Diffstat (limited to 'examples/gtk3')
-rw-r--r--examples/gtk3/js/applauncher/widget/Applauncher.tsx10
-rw-r--r--examples/gtk3/js/popover/Popover.tsx88
-rw-r--r--examples/gtk3/js/popover/app.tsx102
3 files changed, 116 insertions, 84 deletions
diff --git a/examples/gtk3/js/applauncher/widget/Applauncher.tsx b/examples/gtk3/js/applauncher/widget/Applauncher.tsx
index c7bac68..8206250 100644
--- a/examples/gtk3/js/applauncher/widget/Applauncher.tsx
+++ b/examples/gtk3/js/applauncher/widget/Applauncher.tsx
@@ -35,6 +35,7 @@ function AppButton({ app }: { app: Apps.Application }) {
export default function Applauncher() {
const { CENTER } = Gtk.Align
const apps = new Apps.Apps()
+ const width = Variable(1000)
const text = Variable("")
const list = text(text => apps.fuzzy_query(text).slice(0, MAX_ITEMS))
@@ -49,13 +50,16 @@ export default function Applauncher() {
exclusivity={Astal.Exclusivity.IGNORE}
keymode={Astal.Keymode.ON_DEMAND}
application={App}
- onShow={() => text.set("")}
+ onShow={(self) => {
+ text.set("")
+ width.set(self.get_current_monitor().workarea.width)
+ }}
onKeyPressEvent={function (self, event: Gdk.Event) {
if (event.get_keyval()[1] === Gdk.KEY_Escape)
self.hide()
}}>
<box>
- <eventbox widthRequest={4000} expand onClick={hide} />
+ <eventbox widthRequest={width(w => w / 2)} expand onClick={hide} />
<box hexpand={false} vertical>
<eventbox heightRequest={100} onClick={hide} />
<box widthRequest={500} className="Applauncher" vertical>
@@ -81,7 +85,7 @@ export default function Applauncher() {
</box>
<eventbox expand onClick={hide} />
</box>
- <eventbox widthRequest={4000} expand onClick={hide} />
+ <eventbox widthRequest={width(w => w / 2)} expand onClick={hide} />
</box>
</window>
}
diff --git a/examples/gtk3/js/popover/Popover.tsx b/examples/gtk3/js/popover/Popover.tsx
new file mode 100644
index 0000000..29c61e3
--- /dev/null
+++ b/examples/gtk3/js/popover/Popover.tsx
@@ -0,0 +1,88 @@
+import { Astal, Gdk, Gtk, Widget } from "astal/gtk3"
+
+const { TOP, BOTTOM, LEFT, RIGHT } = Astal.WindowAnchor
+
+type PopoverProps = Pick<
+ Widget.WindowProps,
+ | "name"
+ | "namespace"
+ | "className"
+ | "visible"
+ | "child"
+ | "marginBottom"
+ | "marginTop"
+ | "marginLeft"
+ | "marginRight"
+ | "halign"
+ | "valign"
+> & {
+ onClose?(self: Widget.Window): void
+}
+
+export default function Popover({
+ child,
+ visible = false,
+ marginBottom,
+ marginTop,
+ marginLeft,
+ marginRight,
+ halign = Gtk.Align.CENTER,
+ valign = Gtk.Align.CENTER,
+ onClose,
+ ...props
+}: PopoverProps) {
+ return (
+ <window
+ {...props}
+ css="background-color: transparent"
+ keymode={Astal.Keymode.EXCLUSIVE}
+ anchor={TOP | BOTTOM | LEFT | RIGHT}
+ exclusivity={Astal.Exclusivity.IGNORE}
+ onNotifyVisible={(self) => {
+ // instead of anchoring to all sides we set the width explicitly
+ // otherwise label wrapping won't work correctly without setting their width
+ if (self.visible) {
+ self.widthRequest = self.get_current_monitor().workarea.width
+ } else {
+ onClose?.(self)
+ }
+ }}
+ // close when click occurs otside of child
+ onButtonPressEvent={(self, event) => {
+ const [, _x, _y] = event.get_coords()
+ const { x, y, width, height } = self
+ .get_child()!
+ .get_allocation()
+
+ const xOut = _x < x || _x > x + width
+ const yOut = _y < y || _y > y + height
+
+ // clicked outside
+ if (xOut || yOut) {
+ self.visible = false
+ }
+ }}
+ // close when hitting Escape
+ onKeyPressEvent={(self, event: Gdk.Event) => {
+ if (event.get_keyval()[1] === Gdk.KEY_Escape) {
+ self.visible = false
+ }
+ }}
+ >
+ <box
+ // make sure click event does not bubble up
+ onButtonPressEvent={() => true}
+ // child can be positioned with `halign` `valign` and margins
+ expand
+ halign={halign}
+ valign={valign}
+ marginBottom={marginBottom}
+ marginTop={marginTop}
+ marginStart={marginLeft}
+ marginEnd={marginRight}
+ >
+ {child}
+ </box>
+ </window>
+ )
+}
diff --git a/examples/gtk3/js/popover/app.tsx b/examples/gtk3/js/popover/app.tsx
index 6358297..6b0286f 100644
--- a/examples/gtk3/js/popover/app.tsx
+++ b/examples/gtk3/js/popover/app.tsx
@@ -1,75 +1,12 @@
-import { App, Astal, Gdk, Gtk } from "astal/gtk3"
-
-const { TOP, RIGHT, BOTTOM, LEFT } = Astal.WindowAnchor
-
-type PopupProps = {
- child?: unknown
- marginBottom?: number
- marginTop?: number
- marginLeft?: number
- marginRight?: number
- halign?: Gtk.Align
- valign?: Gtk.Align
-}
-
-function Popup({
- child,
- marginBottom,
- marginTop,
- marginLeft,
- marginRight,
- halign = Gtk.Align.CENTER,
- valign = Gtk.Align.CENTER,
-}: PopupProps) {
- return (
- <window
- visible={false}
- css="background-color: transparent"
- keymode={Astal.Keymode.EXCLUSIVE}
- anchor={TOP | RIGHT | BOTTOM | LEFT}
- exclusivity={Astal.Exclusivity.IGNORE}
- // close when click occurs otside of child
- onButtonPressEvent={(self, event) => {
- const [, _x, _y] = event.get_coords()
- const { x, y, width, height } = self
- .get_child()!
- .get_allocation()
-
- const xOut = _x < x || _x > x + width
- const yOut = _y < y || _y > y + height
-
- // clicked outside
- if (xOut || yOut) self.hide()
- }}
- // close when hitting Escape
- onKeyPressEvent={(self, event: Gdk.Event) => {
- if (event.get_keyval()[1] === Gdk.KEY_Escape) {
- self.hide()
- }
- }}
- >
- <box
- className="Popup"
- onButtonPressEvent={() => true} // make sure click event does not bubble up
- // child can be positioned with `halign` `valign` and margins
- expand
- halign={halign}
- valign={valign}
- marginBottom={marginBottom}
- marginTop={marginTop}
- marginStart={marginLeft}
- marginEnd={marginRight}
- >
- {child}
- </box>
- </window>
- )
-}
+import { App, Astal, Gtk } from "astal/gtk3"
+import { Variable } from "astal"
+import Popup from "./Popover"
+const { TOP, RIGHT, LEFT } = Astal.WindowAnchor
App.start({
instanceName: "popup-example",
css: `
- .Popup {
+ .Popup>box {
background-color: @theme_bg_color;
box-shadow: 2px 3px 7px 0 rgba(0,0,0,0.4);
border-radius: 12px;
@@ -77,25 +14,28 @@ App.start({
}
`,
main() {
- const popup = (
- <Popup
- marginTop={36}
- marginRight={60}
- valign={Gtk.Align.START}
- halign={Gtk.Align.END}
- >
- <button onClicked={() => popup.hide()}>
- Click me to close the popup
- </button>
- </Popup>
- )
+ const visible = Variable(false);
+
+ <Popup
+ className="Popup"
+ onClose={() => visible.set(false)}
+ visible={visible()}
+ marginTop={36}
+ marginRight={60}
+ valign={Gtk.Align.START}
+ halign={Gtk.Align.END}
+ >
+ <button onClicked={() => visible.set(false)}>
+ Click me to close the popup
+ </button>
+ </Popup>
return (
<window
anchor={TOP | LEFT | RIGHT}
exclusivity={Astal.Exclusivity.EXCLUSIVE}
>
- <button onClicked={() => popup.show()} halign={Gtk.Align.END}>
+ <button onClicked={() => visible.set(true)} halign={Gtk.Align.END}>
Click to open popup
</button>
</window>