diff options
Diffstat (limited to 'examples/gtk3/js/popover')
-rw-r--r-- | examples/gtk3/js/popover/Popover.tsx | 18 | ||||
-rw-r--r-- | examples/gtk3/js/popover/Popover2.tsx | 66 | ||||
-rw-r--r-- | examples/gtk3/js/popover/app.tsx | 54 |
3 files changed, 117 insertions, 21 deletions
diff --git a/examples/gtk3/js/popover/Popover.tsx b/examples/gtk3/js/popover/Popover.tsx index 29c61e3..38ea01e 100644 --- a/examples/gtk3/js/popover/Popover.tsx +++ b/examples/gtk3/js/popover/Popover.tsx @@ -19,9 +19,17 @@ type PopoverProps = Pick< onClose?(self: Widget.Window): void } +/** + * Full screen window widget where you can space the child widget + * using margins and alignment properties. + * + * NOTE: Child widgets will assume they can span across the full window width + * this means that setting `wrap` or `ellipsize` on labels for example will not work + * without explicitly setting its `max_width_chars` property. + * For a workaround see Popover2.tsx + */ export default function Popover({ child, - visible = false, marginBottom, marginTop, marginLeft, @@ -39,13 +47,7 @@ export default function Popover({ 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) - } + if (!self.visible) onClose?.(self) }} // close when click occurs otside of child onButtonPressEvent={(self, event) => { diff --git a/examples/gtk3/js/popover/Popover2.tsx b/examples/gtk3/js/popover/Popover2.tsx new file mode 100644 index 0000000..e058079 --- /dev/null +++ b/examples/gtk3/js/popover/Popover2.tsx @@ -0,0 +1,66 @@ +import { Astal, Gdk, Widget } from "astal/gtk3" +import Variable from "astal/variable" + +type Popover2Props = Pick< + Widget.WindowProps, + | "name" + | "namespace" + | "className" + | "visible" + | "child" +> & { + onClose?(self: Widget.Window): void +} + +/** + * Full screen window where the child is positioned to center. + * + * NOTE: Workaround for the label wrap issue by padding the window + * with eventboxes and only anchoring to TOP | BOTTOM. + */ +export default function Popover2({ + child, + onClose, + ...props +}: Popover2Props) { + let win: Widget.Window + + const width = Variable(1000) + const hide = () => (win.visible = false) + + return ( + <window + {...props} + setup={self => win = self} + css="background-color: transparent" + keymode={Astal.Keymode.EXCLUSIVE} + anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM} + 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) { + width.set(self.get_current_monitor().workarea.width) + } else { + onClose?.(self) + } + }} + // close when hitting Escape + onKeyPressEvent={(self, event: Gdk.Event) => { + if (event.get_keyval()[1] === Gdk.KEY_Escape) { + self.visible = false + } + }} + > + <box> + <eventbox widthRequest={width(w => w / 2)} expand onClick={hide} /> + <box hexpand={false} vertical> + <eventbox expand onClick={hide} /> + {child} + <eventbox expand onClick={hide} /> + </box> + <eventbox widthRequest={width(w => w / 2)} expand onClick={hide} /> + </box> + </window> + ) +} diff --git a/examples/gtk3/js/popover/app.tsx b/examples/gtk3/js/popover/app.tsx index 6b0286f..5386b66 100644 --- a/examples/gtk3/js/popover/app.tsx +++ b/examples/gtk3/js/popover/app.tsx @@ -1,12 +1,15 @@ import { App, Astal, Gtk } from "astal/gtk3" import { Variable } from "astal" -import Popup from "./Popover" +import Popover from "./Popover" +import Popover2 from "./Popover2" const { TOP, RIGHT, LEFT } = Astal.WindowAnchor +const lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean quis semper risus." + App.start({ instanceName: "popup-example", css: ` - .Popup>box { + .popup { background-color: @theme_bg_color; box-shadow: 2px 3px 7px 0 rgba(0,0,0,0.4); border-radius: 12px; @@ -14,30 +17,55 @@ App.start({ } `, main() { - const visible = Variable(false); + const visible1 = Variable(false); + const visible2 = Variable(false); - <Popup + const _popover1 = <Popover className="Popup" - onClose={() => visible.set(false)} - visible={visible()} + onClose={() => visible1.set(false)} + visible={visible1()} 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> + <box className="popup" vertical> + {/* maxWidthChars is needed to make wrap work */} + <label label={lorem} wrap maxWidthChars={8} /> + <button onClicked={() => visible1.set(false)}> + Click me to close the popup + </button> + </box> + </Popover> + + + const _popover2 = <Popover2 + className="Popup" + onClose={() => visible2.set(false)} + visible={visible2()} + > + <box className="popup" vertical> + {/* maxWidthChars is needed, wrap will work as intended */} + <label label={lorem} wrap /> + <button onClicked={() => visible2.set(false)}> + Click me to close the popup + </button> + </box> + </Popover2> return ( <window anchor={TOP | LEFT | RIGHT} exclusivity={Astal.Exclusivity.EXCLUSIVE} > - <button onClicked={() => visible.set(true)} halign={Gtk.Align.END}> - Click to open popup - </button> + <box halign={Gtk.Align.END}> + <button onClicked={() => visible2.set(true)} halign={Gtk.Align.END}> + Click to open popover2 + </button> + <button onClicked={() => visible1.set(true)} halign={Gtk.Align.END}> + Click to open popover + </button> + </box> </window> ) }, |