@gjsify/example-gtk-adwaita-storybook 0.53.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-main.js +8093 -3042
- package/dist/gjs.js +15 -10
- package/dist/gjs.node.mjs +10 -5
- package/package.json +5 -5
- package/src/browser/buttons/color-dialog-button.web.ts +42 -0
- package/src/browser/buttons/font-dialog-button.web.ts +42 -0
- package/src/browser/buttons/link-button.web.ts +37 -0
- package/src/browser/buttons/scale-button.web.ts +36 -0
- package/src/browser/buttons/toggle-button.web.ts +35 -0
- package/src/browser/controls/check-button.web.ts +38 -0
- package/src/browser/controls/gtk-spinner.web.ts +39 -0
- package/src/browser/controls/level-bar.web.ts +43 -0
- package/src/browser/controls/password-entry.web.ts +36 -0
- package/src/browser/controls/progress-bar.web.ts +39 -0
- package/src/browser/controls/scale.web.ts +44 -0
- package/src/browser/controls/search-entry.web.ts +49 -0
- package/src/browser/controls/spin-button.web.ts +40 -0
- package/src/browser/controls/switch.web.ts +38 -0
- package/src/browser/drawing/drag-icon.web.ts +112 -0
- package/src/browser/drawing/drawing-area.web.ts +66 -0
- package/src/browser/drawing/gl-area.web.ts +162 -0
- package/src/browser/drawing/graphics-offload.web.ts +74 -0
- package/src/browser/feedback/dialog.web.ts +76 -0
- package/src/browser/feedback/emoji-chooser.web.ts +93 -0
- package/src/browser/feedback/gtk-about-dialog.web.ts +105 -0
- package/src/browser/feedback/page-setup-unix-dialog.web.ts +93 -0
- package/src/browser/feedback/print-unix-dialog.web.ts +111 -0
- package/src/browser/feedback/shortcuts-dialog.web.ts +90 -0
- package/src/browser/layout/application-window.web.ts +94 -0
- package/src/browser/layout/aspect-frame.web.ts +49 -0
- package/src/browser/layout/bin.web.ts +41 -0
- package/src/browser/layout/breakpoint-bin.web.ts +61 -0
- package/src/browser/layout/center-box.web.ts +45 -0
- package/src/browser/layout/clamp-scrollable.web.ts +47 -0
- package/src/browser/layout/expander.web.ts +52 -0
- package/src/browser/layout/fixed.web.ts +51 -0
- package/src/browser/layout/frame.web.ts +40 -0
- package/src/browser/layout/grid.web.ts +46 -0
- package/src/browser/layout/layout-slot.web.ts +60 -0
- package/src/browser/layout/multi-layout-view.web.ts +94 -0
- package/src/browser/layout/overlay.web.ts +57 -0
- package/src/browser/layout/paned.web.ts +69 -0
- package/src/browser/layout/popover-bin.web.ts +54 -0
- package/src/browser/layout/popover-menu.web.ts +48 -0
- package/src/browser/layout/popover.web.ts +61 -0
- package/src/browser/layout/revealer.web.ts +53 -0
- package/src/browser/layout/scrollbar.web.ts +54 -0
- package/src/browser/layout/scrolled-window.web.ts +52 -0
- package/src/browser/layout/separator.web.ts +47 -0
- package/src/browser/layout/viewport.web.ts +51 -0
- package/src/browser/layout/window.web.ts +60 -0
- package/src/browser/media/image.web.ts +39 -0
- package/src/browser/media/inscription.web.ts +52 -0
- package/src/browser/media/media-controls.web.ts +65 -0
- package/src/browser/media/picture.web.ts +56 -0
- package/src/browser/media/video.web.ts +56 -0
- package/src/browser/navigation/popover-menu-bar.web.ts +40 -0
- package/src/browser/presentation/calendar.web.ts +49 -0
- package/src/browser/presentation/column-view.web.ts +45 -0
- package/src/browser/presentation/flow-box.web.ts +52 -0
- package/src/browser/presentation/grid-view.web.ts +37 -0
- package/src/browser/presentation/list-box.web.ts +48 -0
- package/src/browser/presentation/list-view.web.ts +36 -0
- package/src/browser/presentation/tree-expander.web.ts +68 -0
- package/src/browser/presentation/window-handle.web.ts +42 -0
- package/src/browser/rows/preferences-row.web.ts +43 -0
- package/src/browser/stories.ts +158 -0
- package/src/browser/text/editable-label.web.ts +45 -0
- package/src/browser/text/search-bar.web.ts +45 -0
- package/src/browser/text/text-view.web.ts +54 -0
- package/src/browser/text/text.web.ts +48 -0
- package/src/browser/view-switching/notebook.web.ts +67 -0
- package/src/browser/view-switching/stack-sidebar.web.ts +68 -0
- package/src/browser/view-switching/stack-switcher.web.ts +70 -0
- package/src/browser/view-switching/stack.web.ts +72 -0
- package/src/browser/view-switching/tab-bar.web.ts +105 -0
- package/src/browser/view-switching/tab-button.web.ts +52 -0
- package/src/browser/view-switching/tab-overview.web.ts +87 -0
- package/src/browser/view-switching/view-switcher-sidebar.web.ts +77 -0
- package/src/browser/windows/action-bar.web.ts +66 -0
- package/src/browser/windows/gtk-application-window.web.ts +67 -0
- package/src/browser/windows/gtk-header-bar.web.ts +61 -0
- package/src/browser/windows/gtk-window.web.ts +58 -0
- package/src/browser/windows/window-controls.web.ts +54 -0
- package/src/buttons/color-dialog-button.meta.ts +16 -0
- package/src/buttons/color-dialog-button.story.ts +49 -0
- package/src/buttons/font-dialog-button.meta.ts +29 -0
- package/src/buttons/font-dialog-button.story.ts +52 -0
- package/src/buttons/link-button.meta.ts +18 -0
- package/src/buttons/link-button.story.ts +48 -0
- package/src/buttons/scale-button.meta.ts +34 -0
- package/src/buttons/scale-button.story.ts +50 -0
- package/src/buttons/toggle-button.meta.ts +17 -0
- package/src/buttons/toggle-button.story.ts +46 -0
- package/src/controls/check-button.meta.ts +19 -0
- package/src/controls/check-button.story.ts +56 -0
- package/src/controls/gtk-spinner.meta.ts +24 -0
- package/src/controls/gtk-spinner.story.ts +53 -0
- package/src/controls/level-bar.meta.ts +39 -0
- package/src/controls/level-bar.story.ts +58 -0
- package/src/controls/password-entry.meta.ts +18 -0
- package/src/controls/password-entry.story.ts +54 -0
- package/src/controls/progress-bar.meta.ts +20 -0
- package/src/controls/progress-bar.story.ts +53 -0
- package/src/controls/scale.meta.ts +47 -0
- package/src/controls/scale.story.ts +66 -0
- package/src/controls/search-entry.meta.ts +18 -0
- package/src/controls/search-entry.story.ts +57 -0
- package/src/controls/spin-button.meta.ts +40 -0
- package/src/controls/spin-button.story.ts +55 -0
- package/src/controls/switch.meta.ts +18 -0
- package/src/controls/switch.story.ts +50 -0
- package/src/drawing/drag-icon.meta.ts +39 -0
- package/src/drawing/drag-icon.story.ts +117 -0
- package/src/drawing/drawing-area.meta.ts +45 -0
- package/src/drawing/drawing-area.story.ts +78 -0
- package/src/drawing/gl-area.meta.ts +30 -0
- package/src/drawing/gl-area.story.ts +113 -0
- package/src/drawing/graphics-offload.meta.ts +39 -0
- package/src/drawing/graphics-offload.story.ts +73 -0
- package/src/feedback/dialog.meta.ts +25 -0
- package/src/feedback/dialog.story.ts +78 -0
- package/src/feedback/emoji-chooser.meta.ts +10 -0
- package/src/feedback/emoji-chooser.story.ts +98 -0
- package/src/feedback/gtk-about-dialog.meta.ts +29 -0
- package/src/feedback/gtk-about-dialog.story.ts +90 -0
- package/src/feedback/page-setup-unix-dialog.meta.ts +37 -0
- package/src/feedback/page-setup-unix-dialog.story.ts +70 -0
- package/src/feedback/print-unix-dialog.meta.ts +30 -0
- package/src/feedback/print-unix-dialog.story.ts +93 -0
- package/src/feedback/shortcuts-dialog.meta.ts +12 -0
- package/src/feedback/shortcuts-dialog.story.ts +79 -0
- package/src/layout/application-window.meta.ts +16 -0
- package/src/layout/application-window.story.ts +97 -0
- package/src/layout/aspect-frame.meta.ts +19 -0
- package/src/layout/aspect-frame.story.ts +62 -0
- package/src/layout/bin.meta.ts +15 -0
- package/src/layout/bin.story.ts +56 -0
- package/src/layout/breakpoint-bin.meta.ts +38 -0
- package/src/layout/breakpoint-bin.story.ts +62 -0
- package/src/layout/center-box.meta.ts +26 -0
- package/src/layout/center-box.story.ts +54 -0
- package/src/layout/clamp-scrollable.meta.ts +30 -0
- package/src/layout/clamp-scrollable.story.ts +51 -0
- package/src/layout/expander.meta.ts +30 -0
- package/src/layout/expander.story.ts +62 -0
- package/src/layout/fixed.meta.ts +16 -0
- package/src/layout/fixed.story.ts +54 -0
- package/src/layout/frame.meta.ts +24 -0
- package/src/layout/frame.story.ts +51 -0
- package/src/layout/grid.meta.ts +45 -0
- package/src/layout/grid.story.ts +80 -0
- package/src/layout/layout-slot.meta.ts +22 -0
- package/src/layout/layout-slot.story.ts +68 -0
- package/src/layout/multi-layout-view.meta.ts +31 -0
- package/src/layout/multi-layout-view.story.ts +101 -0
- package/src/layout/overlay.meta.ts +42 -0
- package/src/layout/overlay.story.ts +72 -0
- package/src/layout/paned.meta.ts +45 -0
- package/src/layout/paned.story.ts +70 -0
- package/src/layout/popover-bin.meta.ts +29 -0
- package/src/layout/popover-bin.story.ts +66 -0
- package/src/layout/popover-menu.meta.ts +54 -0
- package/src/layout/popover-menu.story.ts +119 -0
- package/src/layout/popover.meta.ts +38 -0
- package/src/layout/popover.story.ts +66 -0
- package/src/layout/revealer.meta.ts +44 -0
- package/src/layout/revealer.story.ts +79 -0
- package/src/layout/scrollbar.meta.ts +33 -0
- package/src/layout/scrollbar.story.ts +61 -0
- package/src/layout/scrolled-window.meta.ts +57 -0
- package/src/layout/scrolled-window.story.ts +74 -0
- package/src/layout/separator.meta.ts +25 -0
- package/src/layout/separator.story.ts +53 -0
- package/src/layout/viewport.meta.ts +19 -0
- package/src/layout/viewport.story.ts +53 -0
- package/src/layout/window.meta.ts +13 -0
- package/src/layout/window.story.ts +66 -0
- package/src/media/image.meta.ts +24 -0
- package/src/media/image.story.ts +48 -0
- package/src/media/inscription.meta.ts +45 -0
- package/src/media/inscription.story.ts +64 -0
- package/src/media/media-controls.meta.ts +30 -0
- package/src/media/media-controls.story.ts +58 -0
- package/src/media/picture.meta.ts +42 -0
- package/src/media/picture.story.ts +81 -0
- package/src/media/video.meta.ts +32 -0
- package/src/media/video.story.ts +57 -0
- package/src/metas.ts +79 -0
- package/src/navigation/popover-menu-bar.meta.ts +51 -0
- package/src/navigation/popover-menu-bar.story.ts +72 -0
- package/src/presentation/calendar.meta.ts +28 -0
- package/src/presentation/calendar.story.ts +64 -0
- package/src/presentation/column-view.meta.ts +30 -0
- package/src/presentation/column-view.story.ts +73 -0
- package/src/presentation/flow-box.meta.ts +51 -0
- package/src/presentation/flow-box.story.ts +72 -0
- package/src/presentation/grid-view.meta.ts +28 -0
- package/src/presentation/grid-view.story.ts +64 -0
- package/src/presentation/list-box.meta.ts +55 -0
- package/src/presentation/list-box.story.ts +68 -0
- package/src/presentation/list-view.meta.ts +38 -0
- package/src/presentation/list-view.story.ts +73 -0
- package/src/presentation/tree-expander.meta.ts +24 -0
- package/src/presentation/tree-expander.story.ts +105 -0
- package/src/presentation/window-handle.meta.ts +27 -0
- package/src/presentation/window-handle.story.ts +53 -0
- package/src/rows/preferences-row.meta.ts +15 -0
- package/src/rows/preferences-row.story.ts +50 -0
- package/src/text/editable-label.meta.ts +17 -0
- package/src/text/editable-label.story.ts +47 -0
- package/src/text/search-bar.meta.ts +17 -0
- package/src/text/search-bar.story.ts +48 -0
- package/src/text/text-view.meta.ts +49 -0
- package/src/text/text-view.story.ts +69 -0
- package/src/text/text.meta.ts +21 -0
- package/src/text/text.story.ts +50 -0
- package/src/view-switching/notebook.meta.ts +44 -0
- package/src/view-switching/notebook.story.ts +77 -0
- package/src/view-switching/stack-sidebar.meta.ts +50 -0
- package/src/view-switching/stack-sidebar.story.ts +85 -0
- package/src/view-switching/stack-switcher.meta.ts +53 -0
- package/src/view-switching/stack-switcher.story.ts +95 -0
- package/src/view-switching/stack.meta.ts +53 -0
- package/src/view-switching/stack.story.ts +95 -0
- package/src/view-switching/tab-bar.meta.ts +22 -0
- package/src/view-switching/tab-bar.story.ts +85 -0
- package/src/view-switching/tab-button.meta.ts +14 -0
- package/src/view-switching/tab-button.story.ts +52 -0
- package/src/view-switching/tab-overview.meta.ts +21 -0
- package/src/view-switching/tab-overview.story.ts +86 -0
- package/src/view-switching/view-switcher-sidebar.meta.ts +42 -0
- package/src/view-switching/view-switcher-sidebar.story.ts +73 -0
- package/src/windows/action-bar.meta.ts +27 -0
- package/src/windows/action-bar.story.ts +65 -0
- package/src/windows/gtk-application-window.meta.ts +27 -0
- package/src/windows/gtk-application-window.story.ts +89 -0
- package/src/windows/gtk-header-bar.meta.ts +39 -0
- package/src/windows/gtk-header-bar.story.ts +76 -0
- package/src/windows/gtk-window.meta.ts +30 -0
- package/src/windows/gtk-window.story.ts +64 -0
- package/src/windows/window-controls.meta.ts +42 -0
- package/src/windows/window-controls.story.ts +61 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Stack story. Imported by the GTK
|
|
2
|
+
// renderer (stack.story.ts) and the browser renderer
|
|
3
|
+
// (browser/view-switching/stack.web.ts) so the two expose identical controls.
|
|
4
|
+
|
|
5
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The three pages both renderers build, as the C would: a name for `visible-child-name`,
|
|
9
|
+
* a short title for the switcher's button, and a body. `attn` marks the page as
|
|
10
|
+
* `needs-attention`, which is what the switcher draws the dot for.
|
|
11
|
+
*/
|
|
12
|
+
export const STACK_PAGES = [
|
|
13
|
+
{ name: 'overview', title: 'Overview', attn: false, body: 'Three pages, one visible at a time.' },
|
|
14
|
+
{ name: 'activity', title: 'Activity', attn: false, body: 'Switching is animated by transition-type.' },
|
|
15
|
+
{ name: 'settings', title: 'Settings', attn: true, body: 'This page wants your attention.' },
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
export const stackMeta: StoryMeta = {
|
|
19
|
+
title: 'View Switching/Stack',
|
|
20
|
+
description:
|
|
21
|
+
'Gtk.Stack — one visible child out of many, with the animated change between them. ' +
|
|
22
|
+
'`transition-type` picks the animation and `transition-duration` its length; `hhomogeneous` and ' +
|
|
23
|
+
'`vhomogeneous` say whether every page is allocated the same size. A Gtk.StackPage is a GObject ' +
|
|
24
|
+
'rather than a widget, so its title, icon and needs-attention live on the page itself.',
|
|
25
|
+
controls: [
|
|
26
|
+
{
|
|
27
|
+
name: 'transitionType',
|
|
28
|
+
label: 'Transition type',
|
|
29
|
+
type: ControlType.SELECT,
|
|
30
|
+
options: [
|
|
31
|
+
{ label: 'None', value: 'none' },
|
|
32
|
+
{ label: 'Crossfade', value: 'crossfade' },
|
|
33
|
+
{ label: 'Slide left / right', value: 'slide-left-right' },
|
|
34
|
+
{ label: 'Slide up / down', value: 'slide-up-down' },
|
|
35
|
+
{ label: 'Over left / right', value: 'over-left-right' },
|
|
36
|
+
{ label: 'Rotate left / right', value: 'rotate-left-right' },
|
|
37
|
+
],
|
|
38
|
+
defaultValue: 'slide-left-right',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'transitionDuration',
|
|
42
|
+
label: 'Duration (ms)',
|
|
43
|
+
type: ControlType.RANGE,
|
|
44
|
+
min: 0,
|
|
45
|
+
max: 600,
|
|
46
|
+
step: 50,
|
|
47
|
+
defaultValue: 200,
|
|
48
|
+
},
|
|
49
|
+
{ name: 'interpolateSize', label: 'Interpolate size', type: ControlType.BOOLEAN, defaultValue: false },
|
|
50
|
+
{ name: 'hhomogeneous', label: 'HHomogeneous', type: ControlType.BOOLEAN, defaultValue: true },
|
|
51
|
+
{ name: 'vhomogeneous', label: 'VHomogeneous', type: ControlType.BOOLEAN, defaultValue: true },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Gtk.Stack — one visible child out of many, animated, with a Gtk.StackSwitcher on top.
|
|
2
|
+
// original implementation.
|
|
3
|
+
|
|
4
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
5
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
6
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
7
|
+
import { STACK_PAGES, stackMeta } from './stack.meta.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The GIR nicks this story offers, as the C enum members they name. A nick with no member
|
|
11
|
+
* here is `none`, which is also the property's default (gtkstack.c:1038-1044).
|
|
12
|
+
*/
|
|
13
|
+
const TRANSITIONS: Readonly<Record<string, Gtk.StackTransitionType>> = {
|
|
14
|
+
none: Gtk.StackTransitionType.NONE,
|
|
15
|
+
crossfade: Gtk.StackTransitionType.CROSSFADE,
|
|
16
|
+
'slide-left-right': Gtk.StackTransitionType.SLIDE_LEFT_RIGHT,
|
|
17
|
+
'slide-up-down': Gtk.StackTransitionType.SLIDE_UP_DOWN,
|
|
18
|
+
'over-left-right': Gtk.StackTransitionType.OVER_LEFT_RIGHT,
|
|
19
|
+
'rotate-left-right': Gtk.StackTransitionType.ROTATE_LEFT_RIGHT,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** Story: a Gtk.Stack of three pages under a Gtk.StackSwitcher. */
|
|
23
|
+
export class StackStory extends StoryWidget {
|
|
24
|
+
private _stack: Gtk.Stack | null = null;
|
|
25
|
+
private _switcher: Gtk.StackSwitcher | null = null;
|
|
26
|
+
|
|
27
|
+
static {
|
|
28
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookStack' }, StackStory);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
constructor() {
|
|
32
|
+
super(StoryWidget.fromMeta(StackStory.getMetadata(), 'Default'));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static getMetadata(): StoryMeta {
|
|
36
|
+
return { ...stackMeta, component: Gtk.Stack.$gtype };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
initialize(): void {
|
|
40
|
+
this._stack = new Gtk.Stack({ vexpand: true, transitionDuration: 200 });
|
|
41
|
+
|
|
42
|
+
for (const page of STACK_PAGES) {
|
|
43
|
+
const label = new Gtk.Label({ label: page.body, vexpand: true });
|
|
44
|
+
label.add_css_class('title-2');
|
|
45
|
+
const box = new Gtk.Box({
|
|
46
|
+
orientation: Gtk.Orientation.VERTICAL,
|
|
47
|
+
halign: Gtk.Align.CENTER,
|
|
48
|
+
valign: Gtk.Align.CENTER,
|
|
49
|
+
spacing: 6,
|
|
50
|
+
});
|
|
51
|
+
box.append(new Gtk.Label({ label: page.title, cssClasses: ['title-4'] }));
|
|
52
|
+
box.append(label);
|
|
53
|
+
// `add_titled` is the C's own three-argument form (gtkstack.c:1644-1663); the
|
|
54
|
+
// page's `needs-attention` is set afterwards because it is a page PROPERTY,
|
|
55
|
+
// not an argument.
|
|
56
|
+
const info = this._stack.add_titled(box, page.name, page.title);
|
|
57
|
+
info.needs_attention = page.attn;
|
|
58
|
+
info.use_underline = true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
this._switcher = new Gtk.StackSwitcher({ stack: this._stack, halign: Gtk.Align.CENTER });
|
|
62
|
+
|
|
63
|
+
const root = new Gtk.Box({
|
|
64
|
+
orientation: Gtk.Orientation.VERTICAL,
|
|
65
|
+
spacing: 12,
|
|
66
|
+
widthRequest: 480,
|
|
67
|
+
heightRequest: 320,
|
|
68
|
+
});
|
|
69
|
+
root.append(this._switcher);
|
|
70
|
+
root.append(this._stack);
|
|
71
|
+
|
|
72
|
+
this._apply();
|
|
73
|
+
this.addContent(root);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
updateArgs(_args: StoryArgs): void {
|
|
77
|
+
this._apply();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private _apply(): void {
|
|
81
|
+
if (!this._stack) return;
|
|
82
|
+
// The ORDER is the C's own: `transition-type` FIRST, because a new type is what
|
|
83
|
+
// `set_visible_child` consults when it resolves a two-way nick through
|
|
84
|
+
// `get_simple_transition_type` (gtkstack.c:1546-1561).
|
|
85
|
+
this._stack.transition_type = TRANSITIONS[this.args.transitionType as string] ?? Gtk.StackTransitionType.NONE;
|
|
86
|
+
this._stack.transition_duration = this.args.transitionDuration as number;
|
|
87
|
+
this._stack.interpolate_size = this.args.interpolateSize as boolean;
|
|
88
|
+
this._stack.hhomogeneous = this.args.hhomogeneous as boolean;
|
|
89
|
+
this._stack.vhomogeneous = this.args.vhomogeneous as boolean;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
GObject.type_ensure(StackStory.$gtype);
|
|
94
|
+
|
|
95
|
+
export const StackStories: StoryModule = { stories: [StackStory] };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Tab Bar story. Imported by both the GTK
|
|
2
|
+
// renderer (tab-bar.story.ts) and the browser renderer
|
|
3
|
+
// (browser/view-switching/tab-bar.web.ts) so the two expose identical controls.
|
|
4
|
+
//
|
|
5
|
+
// The controls are the bar's own five: the three booleans it carries and the two action
|
|
6
|
+
// widgets, which are the only parts of `AdwTabBar` a story can show on its own — everything
|
|
7
|
+
// else is read from the tab view underneath it.
|
|
8
|
+
|
|
9
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
10
|
+
|
|
11
|
+
export const tabBarMeta: StoryMeta = {
|
|
12
|
+
title: 'View Switching/Tab Bar',
|
|
13
|
+
description:
|
|
14
|
+
'Adw.TabBar — the tab bar as a widget of its own, bound to an Adw.TabView through its `view`: one chip per page, an action widget on either side, and a strip that can autohide or expand its chips.',
|
|
15
|
+
controls: [
|
|
16
|
+
{ name: 'autohide', label: 'Autohide', type: ControlType.BOOLEAN, defaultValue: false },
|
|
17
|
+
{ name: 'expandTabs', label: 'Expand tabs', type: ControlType.BOOLEAN, defaultValue: false },
|
|
18
|
+
{ name: 'inverted', label: 'Inverted', type: ControlType.BOOLEAN, defaultValue: false },
|
|
19
|
+
{ name: 'startAction', label: 'Start action', type: ControlType.BOOLEAN, defaultValue: true },
|
|
20
|
+
{ name: 'endAction', label: 'End action', type: ControlType.BOOLEAN, defaultValue: true },
|
|
21
|
+
],
|
|
22
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Adw.TabBar — the tab bar as its own widget, bound to an Adw.TabView through `view`, with
|
|
2
|
+
// a start and an end action widget beside the chips. original implementation.
|
|
3
|
+
|
|
4
|
+
import Adw from 'gi://Adw?version=1';
|
|
5
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
6
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
7
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
8
|
+
import { tabBarMeta } from './tab-bar.meta.js';
|
|
9
|
+
|
|
10
|
+
const TABS: ReadonlyArray<{ title: string; body: string }> = [
|
|
11
|
+
{ title: 'Overview', body: 'A summary of everything at a glance.' },
|
|
12
|
+
{ title: 'Details', body: 'The specifics, broken down line by line.' },
|
|
13
|
+
{ title: 'History', body: 'A log of every change made so far.' },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
/** Story: an AdwTabBar over an AdwTabView, with the bar's five properties on controls. */
|
|
17
|
+
export class TabBarStory extends StoryWidget {
|
|
18
|
+
private _bar: Adw.TabBar | null = null;
|
|
19
|
+
private _startAction: Gtk.Button | null = null;
|
|
20
|
+
private _endAction: Gtk.Button | null = null;
|
|
21
|
+
|
|
22
|
+
static {
|
|
23
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookTabBar' }, TabBarStory);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
super(StoryWidget.fromMeta(TabBarStory.getMetadata(), 'Default'));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static getMetadata(): StoryMeta {
|
|
31
|
+
return { ...tabBarMeta, component: Adw.TabBar.$gtype };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
initialize(): void {
|
|
35
|
+
const view = new Adw.TabView({ vexpand: true });
|
|
36
|
+
for (const tab of TABS) {
|
|
37
|
+
const page = view.append(
|
|
38
|
+
new Adw.StatusPage({ iconName: 'view-paged-symbolic', title: tab.title, description: tab.body }),
|
|
39
|
+
);
|
|
40
|
+
page.title = tab.title;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// The two action widgets are `GtkWidget`-typed PROPERTIES, so they are widgets of the
|
|
44
|
+
// caller's rather than children: `AdwTabBar` puts each in an `AdwBin` beside the box.
|
|
45
|
+
this._startAction = new Gtk.Button({
|
|
46
|
+
iconName: 'list-add-symbolic',
|
|
47
|
+
tooltipText: 'New page',
|
|
48
|
+
cssClasses: ['flat'],
|
|
49
|
+
});
|
|
50
|
+
this._endAction = new Gtk.Button({
|
|
51
|
+
iconName: 'view-more-symbolic',
|
|
52
|
+
tooltipText: 'Menu',
|
|
53
|
+
cssClasses: ['flat'],
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const bar = new Adw.TabBar({ view });
|
|
57
|
+
this._bar = bar;
|
|
58
|
+
|
|
59
|
+
const root = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, widthRequest: 480, heightRequest: 320 });
|
|
60
|
+
root.append(bar);
|
|
61
|
+
root.append(view);
|
|
62
|
+
this.addContent(root);
|
|
63
|
+
this._apply();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
updateArgs(_args: StoryArgs): void {
|
|
67
|
+
this._apply();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private _apply(): void {
|
|
71
|
+
const bar = this._bar;
|
|
72
|
+
if (bar === null) return;
|
|
73
|
+
bar.autohide = this.args.autohide as boolean;
|
|
74
|
+
bar.expandTabs = this.args.expandTabs as boolean;
|
|
75
|
+
bar.inverted = this.args.inverted as boolean;
|
|
76
|
+
// `null` is how C removes an action widget, and it is what the element's own
|
|
77
|
+
// `startActionWidget = null` mirrors.
|
|
78
|
+
bar.startActionWidget = (this.args.startAction as boolean) ? this._startAction : null;
|
|
79
|
+
bar.endActionWidget = (this.args.endAction as boolean) ? this._endAction : null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
GObject.type_ensure(TabBarStory.$gtype);
|
|
84
|
+
|
|
85
|
+
export const TabBarStories: StoryModule = { stories: [TabBarStory] };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Tab Button story.
|
|
2
|
+
|
|
3
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
4
|
+
|
|
5
|
+
export const tabButtonMeta: StoryMeta = {
|
|
6
|
+
title: 'View Switching/Tab Button',
|
|
7
|
+
description:
|
|
8
|
+
'Adw.TabButton — a button that shows how many pages an Adw.TabView holds, and a dot when a page you are ' +
|
|
9
|
+
'not looking at needs attention. From ten pages the number shrinks; at a hundred it becomes a glyph.',
|
|
10
|
+
controls: [
|
|
11
|
+
{ name: 'pages', label: 'Pages', type: ControlType.RANGE, min: 0, max: 100, step: 1, defaultValue: 3 },
|
|
12
|
+
{ name: 'needsAttention', label: 'Last page needs attention', type: ControlType.BOOLEAN, defaultValue: false },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Adw.TabButton — the page counter for an Adw.TabView.
|
|
2
|
+
// original implementation.
|
|
3
|
+
|
|
4
|
+
import Adw from 'gi://Adw?version=1';
|
|
5
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
6
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
7
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
8
|
+
import { tabButtonMeta } from './tab-button.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: an Adw.TabButton bound to a view whose page count the control sets. */
|
|
11
|
+
export class TabButtonStory extends StoryWidget {
|
|
12
|
+
private _view: Adw.TabView | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookTabButton' }, TabButtonStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(TabButtonStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...tabButtonMeta, component: Adw.TabButton.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
// The view is the counter's data source and is never shown.
|
|
28
|
+
this._view = new Adw.TabView();
|
|
29
|
+
const button = new Adw.TabButton({ view: this._view, halign: Gtk.Align.CENTER });
|
|
30
|
+
this._apply();
|
|
31
|
+
this.addContent(button);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
updateArgs(_args: StoryArgs): void {
|
|
35
|
+
this._apply();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private _apply(): void {
|
|
39
|
+
const view = this._view;
|
|
40
|
+
if (!view) return;
|
|
41
|
+
const wanted = this.args.pages as number;
|
|
42
|
+
while (view.nPages < wanted) view.append(new Gtk.Box()).title = `Page ${view.nPages}`;
|
|
43
|
+
while (view.nPages > wanted) view.close_page(view.get_nth_page(view.nPages - 1));
|
|
44
|
+
for (let i = 0; i < view.nPages; i++) {
|
|
45
|
+
view.get_nth_page(i).needsAttention = (this.args.needsAttention as boolean) && i === view.nPages - 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
GObject.type_ensure(TabButtonStory.$gtype);
|
|
51
|
+
|
|
52
|
+
export const TabButtonStories: StoryModule = { stories: [TabButtonStory] };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Tab Overview story. Imported by both
|
|
2
|
+
// the GTK renderer (tab-overview.story.ts) and the browser renderer
|
|
3
|
+
// (browser/view-switching/tab-overview.web.ts) so the two expose identical controls.
|
|
4
|
+
//
|
|
5
|
+
// The controls are the overview's own booleans, because everything else about it is
|
|
6
|
+
// driven by the tab view underneath: opening it, whether search is available, whether
|
|
7
|
+
// the new-tab button is there and whether the thumbnails run inverted.
|
|
8
|
+
|
|
9
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
10
|
+
|
|
11
|
+
export const tabOverviewMeta: StoryMeta = {
|
|
12
|
+
title: 'View Switching/Tab Overview',
|
|
13
|
+
description:
|
|
14
|
+
'Adw.TabOverview — a grid of tab thumbnails over an Adw.TabView; open it to see every page at once, search them and close or unpin them.',
|
|
15
|
+
controls: [
|
|
16
|
+
{ name: 'open', label: 'Open', type: ControlType.BOOLEAN, defaultValue: true },
|
|
17
|
+
{ name: 'enableSearch', label: 'Enable search', type: ControlType.BOOLEAN, defaultValue: true },
|
|
18
|
+
{ name: 'enableNewTab', label: 'Enable new tab', type: ControlType.BOOLEAN, defaultValue: false },
|
|
19
|
+
{ name: 'inverted', label: 'Inverted', type: ControlType.BOOLEAN, defaultValue: false },
|
|
20
|
+
],
|
|
21
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Adw.TabOverview — a grid of tab thumbnails over an Adw.TabView. original implementation.
|
|
2
|
+
|
|
3
|
+
import Adw from 'gi://Adw?version=1';
|
|
4
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
5
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
6
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
7
|
+
import { tabOverviewMeta } from './tab-overview.meta.js';
|
|
8
|
+
|
|
9
|
+
const TABS: ReadonlyArray<{ title: string; body: string }> = [
|
|
10
|
+
{ title: 'Overview', body: 'A summary of everything at a glance.' },
|
|
11
|
+
{ title: 'Details', body: 'The specifics, broken down line by line.' },
|
|
12
|
+
{ title: 'History', body: 'A log of every change made so far.' },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
/** Story: Adw.TabOverview over an Adw.TabView with three pages, one of them pinned. */
|
|
16
|
+
export class TabOverviewStory extends StoryWidget {
|
|
17
|
+
private _overview: Adw.TabOverview | null = null;
|
|
18
|
+
|
|
19
|
+
static {
|
|
20
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookTabOverview' }, TabOverviewStory);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
constructor() {
|
|
24
|
+
super(StoryWidget.fromMeta(TabOverviewStory.getMetadata(), 'Default'));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static getMetadata(): StoryMeta {
|
|
28
|
+
return { ...tabOverviewMeta, component: Adw.TabOverview.$gtype };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
initialize(): void {
|
|
32
|
+
const view = new Adw.TabView({ vexpand: true });
|
|
33
|
+
for (const [index, tab] of TABS.entries()) {
|
|
34
|
+
const status = new Adw.StatusPage({
|
|
35
|
+
iconName: 'view-paged-symbolic',
|
|
36
|
+
title: tab.title,
|
|
37
|
+
description: tab.body,
|
|
38
|
+
vexpand: true,
|
|
39
|
+
});
|
|
40
|
+
const page = view.append(status);
|
|
41
|
+
page.title = tab.title;
|
|
42
|
+
// One PINNED page, so the overview has a pinned grid above the ordinary
|
|
43
|
+
// one — the two-grid arrangement `AdwTabOverview` builds its template with.
|
|
44
|
+
if (index === 0) view.set_page_pinned(page, true);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const overview = new Adw.TabOverview({
|
|
48
|
+
view,
|
|
49
|
+
child: view,
|
|
50
|
+
widthRequest: 480,
|
|
51
|
+
heightRequest: 340,
|
|
52
|
+
});
|
|
53
|
+
this._overview = overview;
|
|
54
|
+
|
|
55
|
+
// Without a `create-tab` handler the new-tab button cannot work: C warns
|
|
56
|
+
// ("AdwTabOverview::create-tab handler must not return NULL") when one is
|
|
57
|
+
// missing, so the story connects one and the button is usable.
|
|
58
|
+
overview.connect('create-tab', () => {
|
|
59
|
+
const page = view.append(
|
|
60
|
+
new Adw.StatusPage({ iconName: 'view-paged-symbolic', title: 'New Page', vexpand: true }),
|
|
61
|
+
);
|
|
62
|
+
page.title = 'New Page';
|
|
63
|
+
return page;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
this.addContent(overview);
|
|
67
|
+
this._apply();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
updateArgs(_args: StoryArgs): void {
|
|
71
|
+
this._apply();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private _apply(): void {
|
|
75
|
+
const overview = this._overview;
|
|
76
|
+
if (!overview) return;
|
|
77
|
+
overview.enableSearch = this.args.enableSearch as boolean;
|
|
78
|
+
overview.enableNewTab = this.args.enableNewTab as boolean;
|
|
79
|
+
overview.inverted = this.args.inverted as boolean;
|
|
80
|
+
overview.open = this.args.open as boolean;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
GObject.type_ensure(TabOverviewStory.$gtype);
|
|
85
|
+
|
|
86
|
+
export const TabOverviewStories: StoryModule = { stories: [TabOverviewStory] };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the View Switcher Sidebar story. Imported by
|
|
2
|
+
// both the GTK renderer (view-switcher-sidebar.story.ts) and the browser renderer
|
|
3
|
+
// (browser/view-switching/view-switcher-sidebar.web.ts) so the two expose identical
|
|
4
|
+
// controls.
|
|
5
|
+
//
|
|
6
|
+
// The pages are the story's content, so they live here: both renderers must build the
|
|
7
|
+
// same stack — the same sections, the same badge and the same unread dot — or the two
|
|
8
|
+
// panes are not comparable.
|
|
9
|
+
|
|
10
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
11
|
+
|
|
12
|
+
/** One page of the story's stack. */
|
|
13
|
+
export interface ViewSwitcherSidebarPage {
|
|
14
|
+
name: string;
|
|
15
|
+
title: string;
|
|
16
|
+
icon: string;
|
|
17
|
+
/** Section heading, and a flag only on the page that OPENS it. */
|
|
18
|
+
sectionTitle?: string;
|
|
19
|
+
/** `AdwViewStackPage:badge-number`. */
|
|
20
|
+
badgeNumber?: number;
|
|
21
|
+
/** `AdwViewStackPage:needs-attention`. */
|
|
22
|
+
needsAttention?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const VIEW_SWITCHER_SIDEBAR_PAGES: readonly ViewSwitcherSidebarPage[] = [
|
|
26
|
+
{ name: 'inbox', title: 'Inbox', icon: 'mail-unread-symbolic', sectionTitle: 'Mail', badgeNumber: 3 },
|
|
27
|
+
{ name: 'starred', title: 'Starred', icon: 'starred-symbolic' },
|
|
28
|
+
{ name: 'drafts', title: 'Drafts', icon: 'document-edit-symbolic' },
|
|
29
|
+
// One line per page, deliberately: `check-storybook-category-order` reads every line
|
|
30
|
+
// that STARTS with `title:` as a story title, and a wrapped page entry puts one
|
|
31
|
+
// there. `name` first keeps the key off the start of the line.
|
|
32
|
+
{ name: 'sent', title: 'Sent', icon: 'mail-send-symbolic', sectionTitle: 'Older', needsAttention: true },
|
|
33
|
+
{ name: 'archive', title: 'Archive', icon: 'folder-symbolic' },
|
|
34
|
+
{ name: 'trash', title: 'Trash', icon: 'user-trash-symbolic' },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
export const viewSwitcherSidebarMeta: StoryMeta = {
|
|
38
|
+
title: 'View Switching/View Switcher Sidebar',
|
|
39
|
+
description:
|
|
40
|
+
'Adw.ViewSwitcherSidebar — an Adw.Sidebar driven by an Adw.ViewStack, which is the one Adw switcher whose rows can be grouped into sections and carry an unread dot or a badge. `page` collapses it into a page of boxed lists.',
|
|
41
|
+
controls: [{ name: 'mode', label: 'Page mode', type: ControlType.BOOLEAN, defaultValue: false }],
|
|
42
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Adw.ViewSwitcherSidebar — an Adw.Sidebar driven by an Adw.ViewStack, beside the stack
|
|
2
|
+
// it controls. original implementation.
|
|
3
|
+
|
|
4
|
+
import Adw from 'gi://Adw?version=1';
|
|
5
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
6
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
7
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
8
|
+
import { VIEW_SWITCHER_SIDEBAR_PAGES, viewSwitcherSidebarMeta } from './view-switcher-sidebar.meta.js';
|
|
9
|
+
|
|
10
|
+
/** Story: an Adw.ViewSwitcherSidebar with two sections over a six-page Adw.ViewStack. */
|
|
11
|
+
export class ViewSwitcherSidebarStory extends StoryWidget {
|
|
12
|
+
private _switcher: Adw.ViewSwitcherSidebar | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookViewSwitcherSidebar' }, ViewSwitcherSidebarStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(ViewSwitcherSidebarStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...viewSwitcherSidebarMeta, component: Adw.ViewSwitcherSidebar.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
const stack = new Adw.ViewStack({ vexpand: true });
|
|
28
|
+
for (const spec of VIEW_SWITCHER_SIDEBAR_PAGES) {
|
|
29
|
+
const content = new Adw.StatusPage({
|
|
30
|
+
iconName: spec.icon,
|
|
31
|
+
title: spec.title,
|
|
32
|
+
vexpand: true,
|
|
33
|
+
});
|
|
34
|
+
stack.add_titled(content, spec.name, spec.title);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// The page properties come BEFORE the switcher exists: `set_stack` populates the
|
|
38
|
+
// sidebar once, and the only signals it later follows are the page list's and the
|
|
39
|
+
// selection's — a section or a badge set afterwards reaches nothing.
|
|
40
|
+
const pages = stack.get_pages();
|
|
41
|
+
for (let i = 0; i < pages.get_n_items(); i++) {
|
|
42
|
+
const page = pages.get_item(i) as Adw.ViewStackPage;
|
|
43
|
+
const spec = VIEW_SWITCHER_SIDEBAR_PAGES.find((candidate) => candidate.name === page.name);
|
|
44
|
+
if (!spec?.sectionTitle) continue;
|
|
45
|
+
page.startsSection = true;
|
|
46
|
+
page.sectionTitle = spec.sectionTitle;
|
|
47
|
+
if (spec.badgeNumber) page.badgeNumber = spec.badgeNumber;
|
|
48
|
+
if (spec.needsAttention) page.needsAttention = true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const switcher = new Adw.ViewSwitcherSidebar({ stack });
|
|
52
|
+
this._switcher = switcher;
|
|
53
|
+
|
|
54
|
+
const box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, widthRequest: 480, heightRequest: 340 });
|
|
55
|
+
box.append(switcher);
|
|
56
|
+
box.append(stack);
|
|
57
|
+
this.addContent(box);
|
|
58
|
+
this._apply();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
updateArgs(_args: StoryArgs): void {
|
|
62
|
+
this._apply();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private _apply(): void {
|
|
66
|
+
if (!this._switcher) return;
|
|
67
|
+
this._switcher.mode = (this.args.mode as boolean) ? Adw.SidebarMode.PAGE : Adw.SidebarMode.SIDEBAR;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
GObject.type_ensure(ViewSwitcherSidebarStory.$gtype);
|
|
72
|
+
|
|
73
|
+
export const ViewSwitcherSidebarStories: StoryModule = { stories: [ViewSwitcherSidebarStory] };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Shared, renderer-agnostic metadata for the Action Bar story. Imported by the GTK
|
|
2
|
+
// renderer (action-bar.story.ts) and the browser renderer
|
|
3
|
+
// (browser/windows/action-bar.web.ts), so both expose identical controls.
|
|
4
|
+
|
|
5
|
+
import { ControlType, type StoryMeta } from '@gjsify/stories';
|
|
6
|
+
|
|
7
|
+
export const actionBarMeta: StoryMeta = {
|
|
8
|
+
title: 'Windows/Action Bar',
|
|
9
|
+
description:
|
|
10
|
+
"Gtk.ActionBar — GTK's bottom bar, and the one libadwaita styles but does not own " +
|
|
11
|
+
'(`actionbar > revealer > box`). `start` appends and `end` PREPENDS, so the first end ' +
|
|
12
|
+
'child sits nearest the edge; `center` is a real placement with no property behind it, ' +
|
|
13
|
+
'because GtkBuilder refuses `center-widget`; and `revealed` slides the whole bar away.',
|
|
14
|
+
controls: [
|
|
15
|
+
{ name: 'revealed', label: 'Revealed', type: ControlType.BOOLEAN, defaultValue: true },
|
|
16
|
+
{
|
|
17
|
+
name: 'center',
|
|
18
|
+
label: 'Centre',
|
|
19
|
+
type: ControlType.SELECT,
|
|
20
|
+
options: [
|
|
21
|
+
{ label: 'A label', value: 'label' },
|
|
22
|
+
{ label: 'Nothing', value: 'none' },
|
|
23
|
+
],
|
|
24
|
+
defaultValue: 'label',
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Gtk.ActionBar — GTK's bottom bar of packed widgets, with `revealed` and a centre widget.
|
|
2
|
+
// original implementation.
|
|
3
|
+
|
|
4
|
+
import Gtk from 'gi://Gtk?version=4.0';
|
|
5
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
6
|
+
import { type StoryArgs, type StoryMeta, type StoryModule, StoryWidget } from '@gjsify/storybook';
|
|
7
|
+
import { actionBarMeta } from './action-bar.meta.js';
|
|
8
|
+
|
|
9
|
+
/** Story: a Gtk.ActionBar with both ends packed and a centre widget driven by args. */
|
|
10
|
+
export class ActionBarStory extends StoryWidget {
|
|
11
|
+
private _bar: Gtk.ActionBar | null = null;
|
|
12
|
+
private _centre: Gtk.Label | null = null;
|
|
13
|
+
|
|
14
|
+
static {
|
|
15
|
+
GObject.registerClass({ GTypeName: 'AdwStorybookActionBar' }, ActionBarStory);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super(StoryWidget.fromMeta(ActionBarStory.getMetadata(), 'Default'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static getMetadata(): StoryMeta {
|
|
23
|
+
return { ...actionBarMeta, component: Gtk.ActionBar.$gtype };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
initialize(): void {
|
|
27
|
+
this._bar = new Gtk.ActionBar();
|
|
28
|
+
|
|
29
|
+
// `pack_end` PREPENDS (gtkactionbar.c:262-277), so the button added LAST sits
|
|
30
|
+
// nearest the edge.
|
|
31
|
+
const save = new Gtk.Button({ icon_name: 'document-save-symbolic' });
|
|
32
|
+
save.add_css_class('flat');
|
|
33
|
+
this._bar.pack_end(save);
|
|
34
|
+
const open = new Gtk.Button({ icon_name: 'document-open-symbolic' });
|
|
35
|
+
open.add_css_class('flat');
|
|
36
|
+
this._bar.pack_end(open);
|
|
37
|
+
const print = new Gtk.Button({ icon_name: 'document-print-symbolic' });
|
|
38
|
+
print.add_css_class('flat');
|
|
39
|
+
this._bar.pack_start(print);
|
|
40
|
+
|
|
41
|
+
this._centre = new Gtk.Label({ label: 'notes.md' });
|
|
42
|
+
|
|
43
|
+
const column = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 8 });
|
|
44
|
+
column.append(new Gtk.Label({ label: 'The bar below is Gtk.ActionBar.', css_classes: ['dimmed'] }));
|
|
45
|
+
column.append(this._bar);
|
|
46
|
+
this.addContent(column);
|
|
47
|
+
this._apply();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
updateArgs(_args: StoryArgs): void {
|
|
51
|
+
this._apply();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private _apply(): void {
|
|
55
|
+
if (!this._bar) return;
|
|
56
|
+
this._bar.revealed = this.args.revealed as boolean;
|
|
57
|
+
// `gtk_action_bar_set_center_widget` (:306-...) takes a widget or NULL, and NULL
|
|
58
|
+
// clears the centre rather than replacing it with an empty label.
|
|
59
|
+
this._bar.set_center_widget((this.args.center as string) === 'label' ? this._centre : null);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
GObject.type_ensure(ActionBarStory.$gtype);
|
|
64
|
+
|
|
65
|
+
export const ActionBarStories: StoryModule = { stories: [ActionBarStory] };
|