@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.
Files changed (243) hide show
  1. package/dist/browser-main.js +8093 -3042
  2. package/dist/gjs.js +15 -10
  3. package/dist/gjs.node.mjs +10 -5
  4. package/package.json +5 -5
  5. package/src/browser/buttons/color-dialog-button.web.ts +42 -0
  6. package/src/browser/buttons/font-dialog-button.web.ts +42 -0
  7. package/src/browser/buttons/link-button.web.ts +37 -0
  8. package/src/browser/buttons/scale-button.web.ts +36 -0
  9. package/src/browser/buttons/toggle-button.web.ts +35 -0
  10. package/src/browser/controls/check-button.web.ts +38 -0
  11. package/src/browser/controls/gtk-spinner.web.ts +39 -0
  12. package/src/browser/controls/level-bar.web.ts +43 -0
  13. package/src/browser/controls/password-entry.web.ts +36 -0
  14. package/src/browser/controls/progress-bar.web.ts +39 -0
  15. package/src/browser/controls/scale.web.ts +44 -0
  16. package/src/browser/controls/search-entry.web.ts +49 -0
  17. package/src/browser/controls/spin-button.web.ts +40 -0
  18. package/src/browser/controls/switch.web.ts +38 -0
  19. package/src/browser/drawing/drag-icon.web.ts +112 -0
  20. package/src/browser/drawing/drawing-area.web.ts +66 -0
  21. package/src/browser/drawing/gl-area.web.ts +162 -0
  22. package/src/browser/drawing/graphics-offload.web.ts +74 -0
  23. package/src/browser/feedback/dialog.web.ts +76 -0
  24. package/src/browser/feedback/emoji-chooser.web.ts +93 -0
  25. package/src/browser/feedback/gtk-about-dialog.web.ts +105 -0
  26. package/src/browser/feedback/page-setup-unix-dialog.web.ts +93 -0
  27. package/src/browser/feedback/print-unix-dialog.web.ts +111 -0
  28. package/src/browser/feedback/shortcuts-dialog.web.ts +90 -0
  29. package/src/browser/layout/application-window.web.ts +94 -0
  30. package/src/browser/layout/aspect-frame.web.ts +49 -0
  31. package/src/browser/layout/bin.web.ts +41 -0
  32. package/src/browser/layout/breakpoint-bin.web.ts +61 -0
  33. package/src/browser/layout/center-box.web.ts +45 -0
  34. package/src/browser/layout/clamp-scrollable.web.ts +47 -0
  35. package/src/browser/layout/expander.web.ts +52 -0
  36. package/src/browser/layout/fixed.web.ts +51 -0
  37. package/src/browser/layout/frame.web.ts +40 -0
  38. package/src/browser/layout/grid.web.ts +46 -0
  39. package/src/browser/layout/layout-slot.web.ts +60 -0
  40. package/src/browser/layout/multi-layout-view.web.ts +94 -0
  41. package/src/browser/layout/overlay.web.ts +57 -0
  42. package/src/browser/layout/paned.web.ts +69 -0
  43. package/src/browser/layout/popover-bin.web.ts +54 -0
  44. package/src/browser/layout/popover-menu.web.ts +48 -0
  45. package/src/browser/layout/popover.web.ts +61 -0
  46. package/src/browser/layout/revealer.web.ts +53 -0
  47. package/src/browser/layout/scrollbar.web.ts +54 -0
  48. package/src/browser/layout/scrolled-window.web.ts +52 -0
  49. package/src/browser/layout/separator.web.ts +47 -0
  50. package/src/browser/layout/viewport.web.ts +51 -0
  51. package/src/browser/layout/window.web.ts +60 -0
  52. package/src/browser/media/image.web.ts +39 -0
  53. package/src/browser/media/inscription.web.ts +52 -0
  54. package/src/browser/media/media-controls.web.ts +65 -0
  55. package/src/browser/media/picture.web.ts +56 -0
  56. package/src/browser/media/video.web.ts +56 -0
  57. package/src/browser/navigation/popover-menu-bar.web.ts +40 -0
  58. package/src/browser/presentation/calendar.web.ts +49 -0
  59. package/src/browser/presentation/column-view.web.ts +45 -0
  60. package/src/browser/presentation/flow-box.web.ts +52 -0
  61. package/src/browser/presentation/grid-view.web.ts +37 -0
  62. package/src/browser/presentation/list-box.web.ts +48 -0
  63. package/src/browser/presentation/list-view.web.ts +36 -0
  64. package/src/browser/presentation/tree-expander.web.ts +68 -0
  65. package/src/browser/presentation/window-handle.web.ts +42 -0
  66. package/src/browser/rows/preferences-row.web.ts +43 -0
  67. package/src/browser/stories.ts +158 -0
  68. package/src/browser/text/editable-label.web.ts +45 -0
  69. package/src/browser/text/search-bar.web.ts +45 -0
  70. package/src/browser/text/text-view.web.ts +54 -0
  71. package/src/browser/text/text.web.ts +48 -0
  72. package/src/browser/view-switching/notebook.web.ts +67 -0
  73. package/src/browser/view-switching/stack-sidebar.web.ts +68 -0
  74. package/src/browser/view-switching/stack-switcher.web.ts +70 -0
  75. package/src/browser/view-switching/stack.web.ts +72 -0
  76. package/src/browser/view-switching/tab-bar.web.ts +105 -0
  77. package/src/browser/view-switching/tab-button.web.ts +52 -0
  78. package/src/browser/view-switching/tab-overview.web.ts +87 -0
  79. package/src/browser/view-switching/view-switcher-sidebar.web.ts +77 -0
  80. package/src/browser/windows/action-bar.web.ts +66 -0
  81. package/src/browser/windows/gtk-application-window.web.ts +67 -0
  82. package/src/browser/windows/gtk-header-bar.web.ts +61 -0
  83. package/src/browser/windows/gtk-window.web.ts +58 -0
  84. package/src/browser/windows/window-controls.web.ts +54 -0
  85. package/src/buttons/color-dialog-button.meta.ts +16 -0
  86. package/src/buttons/color-dialog-button.story.ts +49 -0
  87. package/src/buttons/font-dialog-button.meta.ts +29 -0
  88. package/src/buttons/font-dialog-button.story.ts +52 -0
  89. package/src/buttons/link-button.meta.ts +18 -0
  90. package/src/buttons/link-button.story.ts +48 -0
  91. package/src/buttons/scale-button.meta.ts +34 -0
  92. package/src/buttons/scale-button.story.ts +50 -0
  93. package/src/buttons/toggle-button.meta.ts +17 -0
  94. package/src/buttons/toggle-button.story.ts +46 -0
  95. package/src/controls/check-button.meta.ts +19 -0
  96. package/src/controls/check-button.story.ts +56 -0
  97. package/src/controls/gtk-spinner.meta.ts +24 -0
  98. package/src/controls/gtk-spinner.story.ts +53 -0
  99. package/src/controls/level-bar.meta.ts +39 -0
  100. package/src/controls/level-bar.story.ts +58 -0
  101. package/src/controls/password-entry.meta.ts +18 -0
  102. package/src/controls/password-entry.story.ts +54 -0
  103. package/src/controls/progress-bar.meta.ts +20 -0
  104. package/src/controls/progress-bar.story.ts +53 -0
  105. package/src/controls/scale.meta.ts +47 -0
  106. package/src/controls/scale.story.ts +66 -0
  107. package/src/controls/search-entry.meta.ts +18 -0
  108. package/src/controls/search-entry.story.ts +57 -0
  109. package/src/controls/spin-button.meta.ts +40 -0
  110. package/src/controls/spin-button.story.ts +55 -0
  111. package/src/controls/switch.meta.ts +18 -0
  112. package/src/controls/switch.story.ts +50 -0
  113. package/src/drawing/drag-icon.meta.ts +39 -0
  114. package/src/drawing/drag-icon.story.ts +117 -0
  115. package/src/drawing/drawing-area.meta.ts +45 -0
  116. package/src/drawing/drawing-area.story.ts +78 -0
  117. package/src/drawing/gl-area.meta.ts +30 -0
  118. package/src/drawing/gl-area.story.ts +113 -0
  119. package/src/drawing/graphics-offload.meta.ts +39 -0
  120. package/src/drawing/graphics-offload.story.ts +73 -0
  121. package/src/feedback/dialog.meta.ts +25 -0
  122. package/src/feedback/dialog.story.ts +78 -0
  123. package/src/feedback/emoji-chooser.meta.ts +10 -0
  124. package/src/feedback/emoji-chooser.story.ts +98 -0
  125. package/src/feedback/gtk-about-dialog.meta.ts +29 -0
  126. package/src/feedback/gtk-about-dialog.story.ts +90 -0
  127. package/src/feedback/page-setup-unix-dialog.meta.ts +37 -0
  128. package/src/feedback/page-setup-unix-dialog.story.ts +70 -0
  129. package/src/feedback/print-unix-dialog.meta.ts +30 -0
  130. package/src/feedback/print-unix-dialog.story.ts +93 -0
  131. package/src/feedback/shortcuts-dialog.meta.ts +12 -0
  132. package/src/feedback/shortcuts-dialog.story.ts +79 -0
  133. package/src/layout/application-window.meta.ts +16 -0
  134. package/src/layout/application-window.story.ts +97 -0
  135. package/src/layout/aspect-frame.meta.ts +19 -0
  136. package/src/layout/aspect-frame.story.ts +62 -0
  137. package/src/layout/bin.meta.ts +15 -0
  138. package/src/layout/bin.story.ts +56 -0
  139. package/src/layout/breakpoint-bin.meta.ts +38 -0
  140. package/src/layout/breakpoint-bin.story.ts +62 -0
  141. package/src/layout/center-box.meta.ts +26 -0
  142. package/src/layout/center-box.story.ts +54 -0
  143. package/src/layout/clamp-scrollable.meta.ts +30 -0
  144. package/src/layout/clamp-scrollable.story.ts +51 -0
  145. package/src/layout/expander.meta.ts +30 -0
  146. package/src/layout/expander.story.ts +62 -0
  147. package/src/layout/fixed.meta.ts +16 -0
  148. package/src/layout/fixed.story.ts +54 -0
  149. package/src/layout/frame.meta.ts +24 -0
  150. package/src/layout/frame.story.ts +51 -0
  151. package/src/layout/grid.meta.ts +45 -0
  152. package/src/layout/grid.story.ts +80 -0
  153. package/src/layout/layout-slot.meta.ts +22 -0
  154. package/src/layout/layout-slot.story.ts +68 -0
  155. package/src/layout/multi-layout-view.meta.ts +31 -0
  156. package/src/layout/multi-layout-view.story.ts +101 -0
  157. package/src/layout/overlay.meta.ts +42 -0
  158. package/src/layout/overlay.story.ts +72 -0
  159. package/src/layout/paned.meta.ts +45 -0
  160. package/src/layout/paned.story.ts +70 -0
  161. package/src/layout/popover-bin.meta.ts +29 -0
  162. package/src/layout/popover-bin.story.ts +66 -0
  163. package/src/layout/popover-menu.meta.ts +54 -0
  164. package/src/layout/popover-menu.story.ts +119 -0
  165. package/src/layout/popover.meta.ts +38 -0
  166. package/src/layout/popover.story.ts +66 -0
  167. package/src/layout/revealer.meta.ts +44 -0
  168. package/src/layout/revealer.story.ts +79 -0
  169. package/src/layout/scrollbar.meta.ts +33 -0
  170. package/src/layout/scrollbar.story.ts +61 -0
  171. package/src/layout/scrolled-window.meta.ts +57 -0
  172. package/src/layout/scrolled-window.story.ts +74 -0
  173. package/src/layout/separator.meta.ts +25 -0
  174. package/src/layout/separator.story.ts +53 -0
  175. package/src/layout/viewport.meta.ts +19 -0
  176. package/src/layout/viewport.story.ts +53 -0
  177. package/src/layout/window.meta.ts +13 -0
  178. package/src/layout/window.story.ts +66 -0
  179. package/src/media/image.meta.ts +24 -0
  180. package/src/media/image.story.ts +48 -0
  181. package/src/media/inscription.meta.ts +45 -0
  182. package/src/media/inscription.story.ts +64 -0
  183. package/src/media/media-controls.meta.ts +30 -0
  184. package/src/media/media-controls.story.ts +58 -0
  185. package/src/media/picture.meta.ts +42 -0
  186. package/src/media/picture.story.ts +81 -0
  187. package/src/media/video.meta.ts +32 -0
  188. package/src/media/video.story.ts +57 -0
  189. package/src/metas.ts +79 -0
  190. package/src/navigation/popover-menu-bar.meta.ts +51 -0
  191. package/src/navigation/popover-menu-bar.story.ts +72 -0
  192. package/src/presentation/calendar.meta.ts +28 -0
  193. package/src/presentation/calendar.story.ts +64 -0
  194. package/src/presentation/column-view.meta.ts +30 -0
  195. package/src/presentation/column-view.story.ts +73 -0
  196. package/src/presentation/flow-box.meta.ts +51 -0
  197. package/src/presentation/flow-box.story.ts +72 -0
  198. package/src/presentation/grid-view.meta.ts +28 -0
  199. package/src/presentation/grid-view.story.ts +64 -0
  200. package/src/presentation/list-box.meta.ts +55 -0
  201. package/src/presentation/list-box.story.ts +68 -0
  202. package/src/presentation/list-view.meta.ts +38 -0
  203. package/src/presentation/list-view.story.ts +73 -0
  204. package/src/presentation/tree-expander.meta.ts +24 -0
  205. package/src/presentation/tree-expander.story.ts +105 -0
  206. package/src/presentation/window-handle.meta.ts +27 -0
  207. package/src/presentation/window-handle.story.ts +53 -0
  208. package/src/rows/preferences-row.meta.ts +15 -0
  209. package/src/rows/preferences-row.story.ts +50 -0
  210. package/src/text/editable-label.meta.ts +17 -0
  211. package/src/text/editable-label.story.ts +47 -0
  212. package/src/text/search-bar.meta.ts +17 -0
  213. package/src/text/search-bar.story.ts +48 -0
  214. package/src/text/text-view.meta.ts +49 -0
  215. package/src/text/text-view.story.ts +69 -0
  216. package/src/text/text.meta.ts +21 -0
  217. package/src/text/text.story.ts +50 -0
  218. package/src/view-switching/notebook.meta.ts +44 -0
  219. package/src/view-switching/notebook.story.ts +77 -0
  220. package/src/view-switching/stack-sidebar.meta.ts +50 -0
  221. package/src/view-switching/stack-sidebar.story.ts +85 -0
  222. package/src/view-switching/stack-switcher.meta.ts +53 -0
  223. package/src/view-switching/stack-switcher.story.ts +95 -0
  224. package/src/view-switching/stack.meta.ts +53 -0
  225. package/src/view-switching/stack.story.ts +95 -0
  226. package/src/view-switching/tab-bar.meta.ts +22 -0
  227. package/src/view-switching/tab-bar.story.ts +85 -0
  228. package/src/view-switching/tab-button.meta.ts +14 -0
  229. package/src/view-switching/tab-button.story.ts +52 -0
  230. package/src/view-switching/tab-overview.meta.ts +21 -0
  231. package/src/view-switching/tab-overview.story.ts +86 -0
  232. package/src/view-switching/view-switcher-sidebar.meta.ts +42 -0
  233. package/src/view-switching/view-switcher-sidebar.story.ts +73 -0
  234. package/src/windows/action-bar.meta.ts +27 -0
  235. package/src/windows/action-bar.story.ts +65 -0
  236. package/src/windows/gtk-application-window.meta.ts +27 -0
  237. package/src/windows/gtk-application-window.story.ts +89 -0
  238. package/src/windows/gtk-header-bar.meta.ts +39 -0
  239. package/src/windows/gtk-header-bar.story.ts +76 -0
  240. package/src/windows/gtk-window.meta.ts +30 -0
  241. package/src/windows/gtk-window.story.ts +64 -0
  242. package/src/windows/window-controls.meta.ts +42 -0
  243. package/src/windows/window-controls.story.ts +61 -0
@@ -0,0 +1,58 @@
1
+ // Gtk.LevelBar — a level over a real interval, continuous or in blocks.
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 { levelBarMeta } from './level-bar.meta.js';
8
+
9
+ /** Story: a Gtk.LevelBar with interval, mode, orientation and `inverted` bound to args. */
10
+ export class LevelBarStory extends StoryWidget {
11
+ private _box: Gtk.Box | null = null;
12
+ private _bar: Gtk.LevelBar | null = null;
13
+
14
+ static {
15
+ GObject.registerClass({ GTypeName: 'AdwStorybookLevelBar' }, LevelBarStory);
16
+ }
17
+
18
+ constructor() {
19
+ super(StoryWidget.fromMeta(LevelBarStory.getMetadata(), 'Default'));
20
+ }
21
+
22
+ static getMetadata(): StoryMeta {
23
+ return { ...levelBarMeta, component: Gtk.LevelBar.$gtype };
24
+ }
25
+
26
+ initialize(): void {
27
+ this._bar = new Gtk.LevelBar();
28
+ // A horizontal bar has no intrinsic width of its own, so the story gives it one;
29
+ // the vertical one needs a HEIGHT instead, and the box is what decides which.
30
+ this._box = new Gtk.Box({ halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER });
31
+ this._box.append(this._bar);
32
+ this._apply();
33
+ this.addContent(this._box);
34
+ }
35
+
36
+ updateArgs(_args: StoryArgs): void {
37
+ this._apply();
38
+ }
39
+
40
+ private _apply(): void {
41
+ if (!this._bar) return;
42
+ const vertical = this.args.orientation === 'vertical';
43
+ this._bar.orientation = vertical ? Gtk.Orientation.VERTICAL : Gtk.Orientation.HORIZONTAL;
44
+ this._bar.widthRequest = vertical ? 0 : 200;
45
+ this._bar.heightRequest = vertical ? 120 : 0;
46
+ // The ORDER is the C's: a new `max-value` drags `value` down and clamps every
47
+ // offset into the new interval (gtklevelbar.c:1229-1234), so `value` goes second.
48
+ this._bar.max_value = this.args.maxValue as number;
49
+ this._bar.mode =
50
+ (this.args.mode as string) === 'discrete' ? Gtk.LevelBarMode.DISCRETE : Gtk.LevelBarMode.CONTINUOUS;
51
+ this._bar.value = this.args.value as number;
52
+ this._bar.inverted = this.args.inverted as boolean;
53
+ }
54
+ }
55
+
56
+ GObject.type_ensure(LevelBarStory.$gtype);
57
+
58
+ export const LevelBarStories: StoryModule = { stories: [LevelBarStory] };
@@ -0,0 +1,18 @@
1
+ // Shared, renderer-agnostic metadata for the Password Entry story. Imported by the GTK
2
+ // renderer (password-entry.story.ts) and the browser renderer
3
+ // (browser/controls/password-entry.web.ts), so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const passwordEntryMeta: StoryMeta = {
8
+ title: 'Controls/Password Entry',
9
+ description:
10
+ 'Gtk.PasswordEntry — a field for a secret: masked, no copy, a Caps Lock warning while it has focus, ' +
11
+ 'and show-peek-icon for a button that reveals it for one look. Adw.PasswordEntryRow is the ' +
12
+ 'boxed-list row built on it. Press the peek button, or Caps Lock on the keyboard, to see both states.',
13
+ controls: [
14
+ { name: 'showPeekIcon', label: 'Show peek icon', type: ControlType.BOOLEAN, defaultValue: true },
15
+ { name: 'placeholderText', label: 'Placeholder', type: ControlType.TEXT, defaultValue: 'Password' },
16
+ { name: 'disabled', label: 'Disabled', type: ControlType.BOOLEAN, defaultValue: false },
17
+ ],
18
+ };
@@ -0,0 +1,54 @@
1
+ // Gtk.PasswordEntry — the masked field, its peek button and its Caps Lock warning.
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 { passwordEntryMeta } from './password-entry.meta.js';
8
+
9
+ /**
10
+ * Story: a Gtk.PasswordEntry with its peek button, its placeholder and its sensitivity.
11
+ *
12
+ * The two states a reader cannot reach from a control are reached from the keyboard and the
13
+ * mouse instead, which is where they live in C as well: the reveal is the peek button
14
+ * (`gtk_password_entry_toggle_peek`) and the Caps Lock warning is read off the device
15
+ * (`gdk_device_get_caps_lock_state`), with no `Gtk.PasswordEntry` property behind either.
16
+ */
17
+ export class PasswordEntryStory extends StoryWidget {
18
+ private _entry: Gtk.PasswordEntry | null = null;
19
+
20
+ static {
21
+ GObject.registerClass({ GTypeName: 'AdwStorybookPasswordEntry' }, PasswordEntryStory);
22
+ }
23
+
24
+ constructor() {
25
+ super(StoryWidget.fromMeta(PasswordEntryStory.getMetadata(), 'Default'));
26
+ }
27
+
28
+ static getMetadata(): StoryMeta {
29
+ return { ...passwordEntryMeta, component: Gtk.PasswordEntry.$gtype };
30
+ }
31
+
32
+ initialize(): void {
33
+ this._entry = new Gtk.PasswordEntry({ showPeekIcon: true, widthRequest: 240, halign: Gtk.Align.CENTER });
34
+ this._apply();
35
+ this.addContent(this._entry);
36
+ }
37
+
38
+ updateArgs(_args: StoryArgs): void {
39
+ this._apply();
40
+ }
41
+
42
+ private _apply(): void {
43
+ if (!this._entry) return;
44
+ this._entry.show_peek_icon = this.args.showPeekIcon as boolean;
45
+ this._entry.placeholder_text = this.args.placeholderText as string;
46
+ // `sensitive`, not `editable`: a sensitive widget greys out, which is what the
47
+ // browser rendering spells `disabled` — the same divergence the Entry story records.
48
+ this._entry.sensitive = !(this.args.disabled as boolean);
49
+ }
50
+ }
51
+
52
+ GObject.type_ensure(PasswordEntryStory.$gtype);
53
+
54
+ export const PasswordEntryStories: StoryModule = { stories: [PasswordEntryStory] };
@@ -0,0 +1,20 @@
1
+ // Shared, renderer-agnostic metadata for the Progress Bar story. Imported by the GTK
2
+ // renderer (progress-bar.story.ts) and the browser renderer
3
+ // (browser/controls/progress-bar.web.ts), so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const progressBarMeta: StoryMeta = {
8
+ title: 'Controls/Progress Bar',
9
+ description:
10
+ 'Gtk.ProgressBar — how much of a long operation is done. `fraction` is 0…1, `pulsing` is the ' +
11
+ 'indeterminate mode where the app knows it is busy but not how far along it is, and `osd` is ' +
12
+ "libadwaita's hairline variant for under a header bar. Adw.Spinner is the size-less sibling.",
13
+ controls: [
14
+ { name: 'fraction', label: 'Fraction', type: ControlType.RANGE, min: 0, max: 1, step: 0.05, defaultValue: 0.4 },
15
+ { name: 'pulsing', label: 'Pulsing (indeterminate)', type: ControlType.BOOLEAN, defaultValue: false },
16
+ { name: 'showText', label: 'Show text', type: ControlType.BOOLEAN, defaultValue: true },
17
+ { name: 'inverted', label: 'Inverted', type: ControlType.BOOLEAN, defaultValue: false },
18
+ { name: 'osd', label: 'OSD (hairline)', type: ControlType.BOOLEAN, defaultValue: false },
19
+ ],
20
+ };
@@ -0,0 +1,53 @@
1
+ // Gtk.ProgressBar — determinate progress, indeterminate pulse, and the .osd variant.
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 { progressBarMeta } from './progress-bar.meta.js';
8
+
9
+ /** Story: a Gtk.ProgressBar with fraction, pulse, text and the `.osd` style class. */
10
+ export class ProgressBarStory extends StoryWidget {
11
+ private _box: Gtk.Box | null = null;
12
+ private _bar: Gtk.ProgressBar | null = null;
13
+
14
+ static {
15
+ GObject.registerClass({ GTypeName: 'AdwStorybookProgressBar' }, ProgressBarStory);
16
+ }
17
+
18
+ constructor() {
19
+ super(StoryWidget.fromMeta(ProgressBarStory.getMetadata(), 'Default'));
20
+ }
21
+
22
+ static getMetadata(): StoryMeta {
23
+ return { ...progressBarMeta, component: Gtk.ProgressBar.$gtype };
24
+ }
25
+
26
+ initialize(): void {
27
+ this._bar = new Gtk.ProgressBar();
28
+ this._box = new Gtk.Box({ spacing: 12, halign: Gtk.Align.CENTER });
29
+ this._box.append(this._bar);
30
+ this._apply();
31
+ this.addContent(this._box);
32
+ }
33
+
34
+ updateArgs(_args: StoryArgs): void {
35
+ this._apply();
36
+ }
37
+
38
+ private _apply(): void {
39
+ if (!this._bar) return;
40
+ // Order is GTK's: setting `fraction` LEAVES activity mode (gtkprogressbar.c:791),
41
+ // `pulse()` enters it, so a pulsing bar is the one that was pulsed last.
42
+ if (this.args.pulsing as boolean) this._bar.pulse();
43
+ else this._bar.set_fraction(this.args.fraction as number);
44
+ this._bar.show_text = this.args.showText as boolean;
45
+ this._bar.inverted = this.args.inverted as boolean;
46
+ if (this.args.osd as boolean) this._bar.add_css_class('osd');
47
+ else this._bar.remove_css_class('osd');
48
+ }
49
+ }
50
+
51
+ GObject.type_ensure(ProgressBarStory.$gtype);
52
+
53
+ export const ProgressBarStories: StoryModule = { stories: [ProgressBarStory] };
@@ -0,0 +1,47 @@
1
+ // Shared, renderer-agnostic metadata for the Scale story. Imported by the GTK
2
+ // renderer (scale.story.ts) and the browser renderer (browser/controls/scale.web.ts),
3
+ // so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const scaleMeta: StoryMeta = {
8
+ title: 'Controls/Scale',
9
+ description:
10
+ 'Gtk.Scale — a slider. Gtk.Scale extends Gtk.Range, which is abstract: the range itself has no tag, ' +
11
+ 'its adjustment, value, inverted and fill level are this widget’s properties. draw-value shows the ' +
12
+ 'number beside the knob at the value-pos you name, and the .value style class dims it.',
13
+ controls: [
14
+ {
15
+ name: 'orientation',
16
+ label: 'Orientation',
17
+ type: ControlType.SELECT,
18
+ options: [
19
+ { label: 'Horizontal', value: 'horizontal' },
20
+ { label: 'Vertical', value: 'vertical' },
21
+ ],
22
+ defaultValue: 'horizontal',
23
+ },
24
+ {
25
+ name: 'valuePos',
26
+ label: 'Value position',
27
+ type: ControlType.SELECT,
28
+ options: [
29
+ { label: 'Top', value: 'top' },
30
+ { label: 'Bottom', value: 'bottom' },
31
+ { label: 'Left', value: 'left' },
32
+ { label: 'Right', value: 'right' },
33
+ ],
34
+ defaultValue: 'top',
35
+ },
36
+ { name: 'drawValue', label: 'Draw value', type: ControlType.BOOLEAN, defaultValue: true },
37
+ { name: 'digits', label: 'Digits', type: ControlType.NUMBER, defaultValue: 0 },
38
+ { name: 'inverted', label: 'Inverted', type: ControlType.BOOLEAN, defaultValue: false },
39
+ { name: 'hasOrigin', label: 'Has origin', type: ControlType.BOOLEAN, defaultValue: true },
40
+ {
41
+ name: 'value',
42
+ label: 'Value',
43
+ type: ControlType.NUMBER,
44
+ defaultValue: 40,
45
+ },
46
+ ],
47
+ };
@@ -0,0 +1,66 @@
1
+ // Gtk.Scale — the slider, with its adjustment, its value text and the properties that
2
+ // shape both.
3
+ // original implementation.
4
+
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 { scaleMeta } from './scale.meta.js';
9
+
10
+ /** Story: a Gtk.Scale over 0…100, with the value text, the digits and the origin bound to args. */
11
+ export class ScaleStory extends StoryWidget {
12
+ private _scale: Gtk.Scale | null = null;
13
+ private _adjustment: Gtk.Adjustment | null = null;
14
+
15
+ static {
16
+ GObject.registerClass({ GTypeName: 'AdwStorybookScale' }, ScaleStory);
17
+ }
18
+
19
+ constructor() {
20
+ super(StoryWidget.fromMeta(ScaleStory.getMetadata(), 'Default'));
21
+ }
22
+
23
+ static getMetadata(): StoryMeta {
24
+ return { ...scaleMeta, component: Gtk.Scale.$gtype };
25
+ }
26
+
27
+ initialize(): void {
28
+ this._adjustment = new Gtk.Adjustment({ value: 40, lower: 0, upper: 100, stepIncrement: 1, pageIncrement: 10 });
29
+ this._scale = new Gtk.Scale({
30
+ adjustment: this._adjustment,
31
+ digits: 0,
32
+ drawValue: true,
33
+ widthRequest: 260,
34
+ valign: Gtk.Align.CENTER,
35
+ });
36
+ this._apply();
37
+ this.addContent(this._scale);
38
+ }
39
+
40
+ updateArgs(_args: StoryArgs): void {
41
+ this._apply();
42
+ }
43
+
44
+ private _apply(): void {
45
+ if (!this._scale || !this._adjustment) return;
46
+ this._scale.orientation =
47
+ this.args.orientation === 'vertical' ? Gtk.Orientation.VERTICAL : Gtk.Orientation.HORIZONTAL;
48
+ // `Gtk.PositionType` is an enum, so the nick the meta offers is translated here.
49
+ const positions: Record<string, Gtk.PositionType> = {
50
+ top: Gtk.PositionType.TOP,
51
+ bottom: Gtk.PositionType.BOTTOM,
52
+ left: Gtk.PositionType.LEFT,
53
+ right: Gtk.PositionType.RIGHT,
54
+ };
55
+ this._scale.value_pos = positions[this.args.valuePos as string] ?? Gtk.PositionType.TOP;
56
+ this._scale.draw_value = this.args.drawValue as boolean;
57
+ this._scale.digits = this.args.digits as number;
58
+ this._scale.inverted = this.args.inverted as boolean;
59
+ this._scale.has_origin = this.args.hasOrigin as boolean;
60
+ this._adjustment.set_value(this.args.value as number);
61
+ }
62
+ }
63
+
64
+ GObject.type_ensure(ScaleStory.$gtype);
65
+
66
+ export const ScaleStories: StoryModule = { stories: [ScaleStory] };
@@ -0,0 +1,18 @@
1
+ // Shared, renderer-agnostic metadata for the Search Entry story. Imported by the GTK
2
+ // renderer (search-entry.story.ts) and the browser renderer
3
+ // (browser/controls/search-entry.web.ts), so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const searchEntryMeta: StoryMeta = {
8
+ title: 'Controls/Search Entry',
9
+ description:
10
+ 'Gtk.SearchEntry — a field for typing a query. A search glyph leads while it is empty and a clear ' +
11
+ 'button follows once it is not, and search-changed waits out search-delay so a filter is not driven ' +
12
+ 'by every keystroke. Escape is stop-search, Ctrl+G is next-match.',
13
+ controls: [
14
+ { name: 'searchDelay', label: 'Search delay (ms)', type: ControlType.NUMBER, defaultValue: 150 },
15
+ { name: 'placeholderText', label: 'Placeholder', type: ControlType.TEXT, defaultValue: 'Search…' },
16
+ { name: 'disabled', label: 'Disabled', type: ControlType.BOOLEAN, defaultValue: false },
17
+ ],
18
+ };
@@ -0,0 +1,57 @@
1
+ // Gtk.SearchEntry — the query field, its clear button and its delayed search-changed.
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 { searchEntryMeta } from './search-entry.meta.js';
8
+
9
+ /** Story: a Gtk.SearchEntry with its placeholder, its search delay and the last signal it emitted. */
10
+ export class SearchEntryStory extends StoryWidget {
11
+ private _entry: Gtk.SearchEntry | null = null;
12
+ private _label: Gtk.Label | null = null;
13
+ private _handler = 0;
14
+
15
+ static {
16
+ GObject.registerClass({ GTypeName: 'AdwStorybookSearchEntry' }, SearchEntryStory);
17
+ }
18
+
19
+ constructor() {
20
+ super(StoryWidget.fromMeta(SearchEntryStory.getMetadata(), 'Default'));
21
+ }
22
+
23
+ static getMetadata(): StoryMeta {
24
+ return { ...searchEntryMeta, component: Gtk.SearchEntry.$gtype };
25
+ }
26
+
27
+ initialize(): void {
28
+ this._entry = new Gtk.SearchEntry({ widthRequest: 260, halign: Gtk.Align.CENTER });
29
+ this._label = new Gtk.Label({ label: 'search-changed has not fired yet' });
30
+ // The signal is the reason the widget exists, so the story shows that it fires —
31
+ // and at what delay, which is the control above it.
32
+ this._handler = this._entry.connect('search-changed', () => {
33
+ if (this._label) this._label.label = `search-changed: "${this._entry?.text ?? ''}"`;
34
+ });
35
+ this._apply();
36
+ const box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 12 });
37
+ box.append(this._entry);
38
+ box.append(this._label);
39
+ this.addContent(box);
40
+ }
41
+
42
+ updateArgs(_args: StoryArgs): void {
43
+ this._apply();
44
+ }
45
+
46
+ private _apply(): void {
47
+ if (!this._entry) return;
48
+ this._entry.search_delay = this.args.searchDelay as number;
49
+ this._entry.placeholder_text = this.args.placeholderText as string;
50
+ // `sensitive`, not `editable`, for the same reason the Password Entry story gives.
51
+ this._entry.sensitive = !(this.args.disabled as boolean);
52
+ }
53
+ }
54
+
55
+ GObject.type_ensure(SearchEntryStory.$gtype);
56
+
57
+ export const SearchEntryStories: StoryModule = { stories: [SearchEntryStory] };
@@ -0,0 +1,40 @@
1
+ // Shared, renderer-agnostic metadata for the Spin Button story. Imported by the GTK
2
+ // renderer (spin-button.story.ts) and the browser renderer
3
+ // (browser/controls/spin-button.web.ts), so both expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const spinButtonMeta: StoryMeta = {
8
+ title: 'Controls/Spin Button',
9
+ description:
10
+ 'Gtk.SpinButton — a number field with an arrow either side of it. The range is a Gtk.Adjustment, the ' +
11
+ 'typed value is clamped into it (or left alone, under update-policy if-valid), and numeric refuses ' +
12
+ 'anything that is not a number. Adw.SpinRow is the boxed-list row that wraps this same widget.',
13
+ controls: [
14
+ {
15
+ name: 'orientation',
16
+ label: 'Orientation',
17
+ type: ControlType.SELECT,
18
+ options: [
19
+ { label: 'Horizontal', value: 'horizontal' },
20
+ { label: 'Vertical', value: 'vertical' },
21
+ ],
22
+ defaultValue: 'horizontal',
23
+ },
24
+ { name: 'digits', label: 'Digits', type: ControlType.NUMBER, defaultValue: 0 },
25
+ { name: 'numeric', label: 'Numeric', type: ControlType.BOOLEAN, defaultValue: false },
26
+ { name: 'snapToTicks', label: 'Snap to ticks', type: ControlType.BOOLEAN, defaultValue: false },
27
+ { name: 'wrap', label: 'Wrap', type: ControlType.BOOLEAN, defaultValue: false },
28
+ {
29
+ name: 'updatePolicy',
30
+ label: 'Update policy',
31
+ type: ControlType.SELECT,
32
+ options: [
33
+ { label: 'Always', value: 'always' },
34
+ { label: 'If valid', value: 'if-valid' },
35
+ ],
36
+ defaultValue: 'always',
37
+ },
38
+ { name: 'value', label: 'Value', type: ControlType.NUMBER, defaultValue: 5 },
39
+ ],
40
+ };
@@ -0,0 +1,55 @@
1
+ // Gtk.SpinButton — the number field with its two arrows.
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 { spinButtonMeta } from './spin-button.meta.js';
8
+
9
+ /** Story: a Gtk.SpinButton over 0…10, with its numeric/snap/wrap/policy switches bound to args. */
10
+ export class SpinButtonStory extends StoryWidget {
11
+ private _spin: Gtk.SpinButton | null = null;
12
+ private _adjustment: Gtk.Adjustment | null = null;
13
+
14
+ static {
15
+ GObject.registerClass({ GTypeName: 'AdwStorybookSpinButton' }, SpinButtonStory);
16
+ }
17
+
18
+ constructor() {
19
+ super(StoryWidget.fromMeta(SpinButtonStory.getMetadata(), 'Default'));
20
+ }
21
+
22
+ static getMetadata(): StoryMeta {
23
+ return { ...spinButtonMeta, component: Gtk.SpinButton.$gtype };
24
+ }
25
+
26
+ initialize(): void {
27
+ this._adjustment = new Gtk.Adjustment({ value: 5, lower: 0, upper: 10, stepIncrement: 1, pageIncrement: 2 });
28
+ this._spin = new Gtk.SpinButton({ adjustment: this._adjustment, digits: 0, halign: Gtk.Align.CENTER });
29
+ this._apply();
30
+ this.addContent(this._spin);
31
+ }
32
+
33
+ updateArgs(_args: StoryArgs): void {
34
+ this._apply();
35
+ }
36
+
37
+ private _apply(): void {
38
+ if (!this._spin || !this._adjustment) return;
39
+ this._spin.orientation =
40
+ this.args.orientation === 'vertical' ? Gtk.Orientation.VERTICAL : Gtk.Orientation.HORIZONTAL;
41
+ this._spin.digits = this.args.digits as number;
42
+ this._spin.numeric = this.args.numeric as boolean;
43
+ this._spin.snap_to_ticks = this.args.snapToTicks as boolean;
44
+ this._spin.wrap = this.args.wrap as boolean;
45
+ this._spin.update_policy =
46
+ this.args.updatePolicy === 'if-valid'
47
+ ? Gtk.SpinButtonUpdatePolicy.IF_VALID
48
+ : Gtk.SpinButtonUpdatePolicy.ALWAYS;
49
+ this._adjustment.set_value(this.args.value as number);
50
+ }
51
+ }
52
+
53
+ GObject.type_ensure(SpinButtonStory.$gtype);
54
+
55
+ export const SpinButtonStories: StoryModule = { stories: [SpinButtonStory] };
@@ -0,0 +1,18 @@
1
+ // Shared, renderer-agnostic metadata for the Switch story. Imported by the GTK renderer
2
+ // (switch.story.ts) and the browser renderer (browser/controls/switch.web.ts), so both
3
+ // expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const switchMeta: StoryMeta = {
8
+ title: 'Controls/Switch',
9
+ description:
10
+ 'Gtk.Switch — a light switch with two states that are NOT the same thing: active is where the ' +
11
+ 'user put it, state is what the switched thing currently is, which is how a change that takes a ' +
12
+ 'while looks like a pending one. Adw.SwitchRow is the same control with a title beside it.',
13
+ controls: [
14
+ { name: 'active', label: 'Active', type: ControlType.BOOLEAN, defaultValue: true },
15
+ { name: 'state', label: 'State (the backend)', type: ControlType.BOOLEAN, defaultValue: true },
16
+ { name: 'disabled', label: 'Disabled', type: ControlType.BOOLEAN, defaultValue: false },
17
+ ],
18
+ };
@@ -0,0 +1,50 @@
1
+ // Gtk.Switch — the light switch, with `active` and `state` shown apart.
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 { switchMeta } from './switch.meta.js';
8
+
9
+ /** Story: a Gtk.Switch whose `active` and `state` are driven separately, as the C allows. */
10
+ export class SwitchStory extends StoryWidget {
11
+ private _switch: Gtk.Switch | null = null;
12
+
13
+ static {
14
+ GObject.registerClass({ GTypeName: 'AdwStorybookSwitch' }, SwitchStory);
15
+ }
16
+
17
+ constructor() {
18
+ super(StoryWidget.fromMeta(SwitchStory.getMetadata(), 'Default'));
19
+ }
20
+
21
+ static getMetadata(): StoryMeta {
22
+ return { ...switchMeta, component: Gtk.Switch.$gtype };
23
+ }
24
+
25
+ initialize(): void {
26
+ this._switch = new Gtk.Switch({ halign: Gtk.Align.CENTER });
27
+ this._apply();
28
+ this.addContent(this._switch);
29
+ }
30
+
31
+ updateArgs(_args: StoryArgs): void {
32
+ this._apply();
33
+ }
34
+
35
+ private _apply(): void {
36
+ if (!this._switch) return;
37
+ // The ORDER is the story's point. `set_active` also sets `state`, because its
38
+ // default `::state-set` handler does (gtkswitch.c:800, :558), so `active` goes
39
+ // first and `state` second: a `state` of false on an `active` of true is the
40
+ // delayed-change case, where the knob is where the user put it and the trough is
41
+ // where the thing still is.
42
+ this._switch.active = this.args.active as boolean;
43
+ this._switch.state = this.args.state as boolean;
44
+ this._switch.sensitive = !(this.args.disabled as boolean);
45
+ }
46
+ }
47
+
48
+ GObject.type_ensure(SwitchStory.$gtype);
49
+
50
+ export const SwitchStories: StoryModule = { stories: [SwitchStory] };
@@ -0,0 +1,39 @@
1
+ // Shared, renderer-agnostic metadata for the Drag Icon story. Imported by the GTK renderer
2
+ // (drag-icon.story.ts) and the browser renderer (browser/drawing/drag-icon.web.ts), so both
3
+ // expose identical controls.
4
+
5
+ import { ControlType, type StoryMeta } from '@gjsify/stories';
6
+
7
+ export const dragIconMeta: StoryMeta = {
8
+ title: 'Drawing/Drag Icon',
9
+ description:
10
+ 'Gtk.DragIcon — the widget that follows the pointer while a drag is in flight, and is destroyed ' +
11
+ 'with the drag. No application builds one: `get_for_drag` returns the icon a drag is using, and ' +
12
+ 'the drag source sets its child. What it takes as that child is the interesting part, because ' +
13
+ '`create_widget_for_value` answers for six kinds of value and a drag source that offers a string ' +
14
+ 'gets a label and one that offers a colour gets a swatch. A drag icon takes no input at all, which ' +
15
+ "is the C's own note: 'drag icons do not allow user input'.",
16
+ controls: [
17
+ {
18
+ name: 'value',
19
+ label: 'Value being dragged',
20
+ type: ControlType.SELECT,
21
+ options: [
22
+ { label: 'A string (a Gtk.Label)', value: 'string' },
23
+ { label: 'A GdkRGBA (a colour swatch)', value: 'rgba' },
24
+ { label: 'A content provider only (no icon)', value: 'none' },
25
+ ],
26
+ defaultValue: 'string',
27
+ },
28
+ {
29
+ name: 'actions',
30
+ label: 'Drag actions',
31
+ type: ControlType.SELECT,
32
+ options: [
33
+ { label: 'Copy', value: 'copy' },
34
+ { label: 'Move', value: 'move' },
35
+ ],
36
+ defaultValue: 'copy',
37
+ },
38
+ ],
39
+ };