Skip to content

Commit

Permalink
update popover example
Browse files Browse the repository at this point in the history
  • Loading branch information
Aylur committed Jan 23, 2025
1 parent 9a83bcd commit 9cadfed
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 84 deletions.
10 changes: 7 additions & 3 deletions examples/gtk3/js/applauncher/widget/Applauncher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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>
Expand All @@ -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>
}
88 changes: 88 additions & 0 deletions examples/gtk3/js/popover/Popover.tsx
Original file line number Diff line number Diff line change
@@ -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>
)
}
102 changes: 21 additions & 81 deletions examples/gtk3/js/popover/app.tsx
Original file line number Diff line number Diff line change
@@ -1,101 +1,41 @@
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;
padding: 12px;
}
`,
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>
Expand Down

0 comments on commit 9cadfed

Please sign in to comment.