@yuneta/gobj-ui 2.0.0 → 2.2.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 (58) hide show
  1. package/README.md +25 -20
  2. package/dist/gobj-ui.cjs.js +2331 -526
  3. package/dist/gobj-ui.es.js +2331 -528
  4. package/index.js +32 -31
  5. package/package.json +5 -6
  6. package/{c_g6_nodes_tree.js → src/c_g6_nodes_tree.js} +6 -1
  7. package/{c_yui_form.js → src/c_yui_form.js} +1 -1
  8. package/{c_yui_gobj_tree_js.js → src/c_yui_gobj_tree_js.js} +1 -1
  9. package/{c_yui_json_graph.js → src/c_yui_json_graph.js} +1 -1
  10. package/{c_yui_main.js → src/c_yui_main.js} +3 -3
  11. package/{c_yui_map.js → src/c_yui_map.js} +6 -1
  12. package/{c_yui_nav.js → src/c_yui_nav.js} +134 -26
  13. package/{c_yui_pager.js → src/c_yui_pager.js} +1 -1
  14. package/{c_yui_routing.css → src/c_yui_routing.css} +1 -1
  15. package/{c_yui_routing.js → src/c_yui_routing.js} +1 -1
  16. package/{c_yui_shell.css → src/c_yui_shell.css} +110 -0
  17. package/{c_yui_shell.js → src/c_yui_shell.js} +163 -10
  18. package/{c_yui_tabs.js → src/c_yui_tabs.js} +1 -1
  19. package/{c_yui_treedb_graph.js → src/c_yui_treedb_graph.js} +35 -9
  20. package/{c_yui_treedb_topic_with_form.js → src/c_yui_treedb_topic_with_form.js} +1 -1
  21. package/{c_yui_treedb_topics.js → src/c_yui_treedb_topics.js} +36 -8
  22. package/{c_yui_uplot.js → src/c_yui_uplot.js} +1 -1
  23. package/{c_yui_window.js → src/c_yui_window.js} +242 -21
  24. package/src/c_yui_window_manager.js +602 -0
  25. package/{c_yui_wizard.js → src/c_yui_wizard.js} +1 -1
  26. package/{shell_modals.js → src/shell_modals.js} +53 -13
  27. package/src/tabulator.css +53 -0
  28. package/src/yui_dev.js +1478 -0
  29. package/{yui_icons.css → src/yui_icons.css} +5 -0
  30. package/src/yui_inputs.css +32 -0
  31. package/src/yui_inputs.js +71 -0
  32. package/vite.config.js +0 -131
  33. package/yui_dev.js +0 -583
  34. /package/{c_yui_main.css → src/c_yui_main.css} +0 -0
  35. /package/{c_yui_map.css → src/c_yui_map.css} +0 -0
  36. /package/{c_yui_treedb_topic_with_form.css → src/c_yui_treedb_topic_with_form.css} +0 -0
  37. /package/{g6_drag_canvas_touch.js → src/g6_drag_canvas_touch.js} +0 -0
  38. /package/{lib_graph.css → src/lib_graph.css} +0 -0
  39. /package/{lib_graph.js → src/lib_graph.js} +0 -0
  40. /package/{lib_icons.js → src/lib_icons.js} +0 -0
  41. /package/{lib_maplibre.js → src/lib_maplibre.js} +0 -0
  42. /package/{pager_helpers.js → src/pager_helpers.js} +0 -0
  43. /package/{pager_helpers.test.js → src/pager_helpers.test.js} +0 -0
  44. /package/{route_resolver.js → src/route_resolver.js} +0 -0
  45. /package/{route_resolver.test.js → src/route_resolver.test.js} +0 -0
  46. /package/{shell_focus_trap.js → src/shell_focus_trap.js} +0 -0
  47. /package/{shell_focus_trap.test.js → src/shell_focus_trap.test.js} +0 -0
  48. /package/{shell_show_on.js → src/shell_show_on.js} +0 -0
  49. /package/{shell_show_on.test.js → src/shell_show_on.test.js} +0 -0
  50. /package/{shell_toolbar_helpers.js → src/shell_toolbar_helpers.js} +0 -0
  51. /package/{shell_toolbar_helpers.test.js → src/shell_toolbar_helpers.test.js} +0 -0
  52. /package/{themes.js → src/themes.js} +0 -0
  53. /package/{wizard_helpers.js → src/wizard_helpers.js} +0 -0
  54. /package/{wizard_helpers.test.js → src/wizard_helpers.test.js} +0 -0
  55. /package/{ytable.css → src/ytable.css} +0 -0
  56. /package/{ytable.js → src/ytable.js} +0 -0
  57. /package/{yui_toolbar.css → src/yui_toolbar.css} +0 -0
  58. /package/{yui_toolbar.js → src/yui_toolbar.js} +0 -0
@@ -0,0 +1,602 @@
1
+ /***********************************************************************
2
+ * c_yui_window_manager.js
3
+ *
4
+ * Window manager / dock (taskbar).
5
+ *
6
+ * A light registry + dock strip for C_YUI_WINDOW instances. Windows
7
+ * opt in via their `manager` attr: on create they REGISTER, on
8
+ * destroy they UNREGISTER, their minimize button MINIMIZEs (roll to
9
+ * the dock instead of shading in place), and any pointer press
10
+ * FOCUSes (raise z-order + highlight the dock chip).
11
+ *
12
+ * The manager never owns window lifecycle: it only toggles a
13
+ * window's `$container` display / z-index and reflects state in the
14
+ * dock. Closing stays the window's own affordance (its ✕ →
15
+ * gobj_destroy → EV_UNREGISTER_WINDOW removes the chip).
16
+ *
17
+ * Orthogonal to C_YUI_PAGER (page-stack): a window may host a pager
18
+ * in its body; the manager only arranges the windows themselves.
19
+ *
20
+ * The dock placement is configurable via `dock_mode`:
21
+ * - "floating" (default) a detached bar pinned to a corner
22
+ * (`dock_corner`), hovering over the content.
23
+ * - "inline" a full-width taskbar row mounted inside a layout
24
+ * container (`inline_selector`, e.g. a shell zone).
25
+ * - "responsive" floating on wide viewports, inline on narrow ones
26
+ * (`responsive_query`) — so on mobile it lives above
27
+ * the bottom menu instead of covering it.
28
+ *
29
+ * Copyright (c) 2026, ArtGins.
30
+ * All Rights Reserved.
31
+ ***********************************************************************/
32
+ import {
33
+ SDATA,
34
+ SDATA_END,
35
+ data_type_t,
36
+ gclass_create,
37
+ log_error,
38
+ gobj_read_pointer_attr,
39
+ gobj_subscribe_event,
40
+ gobj_send_event,
41
+ createElement2,
42
+ gobj_write_attr,
43
+ gobj_read_attr,
44
+ gobj_name,
45
+ } from "@yuneta/gobj-js";
46
+
47
+
48
+ /***************************************************************
49
+ * Constants
50
+ ***************************************************************/
51
+ const GCLASS_NAME = "C_YUI_WINDOW_MANAGER";
52
+
53
+ /* Dock sits above every window: windows raise to an incrementing
54
+ * counter that starts well below this. */
55
+ const DOCK_Z = 1000000;
56
+
57
+ /* Chip close glyph (currentColor → theme-aware). */
58
+ const WC_X = '<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M4.5 4.5 L11.5 11.5 M11.5 4.5 L4.5 11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>';
59
+
60
+
61
+ /***************************************************************
62
+ * Data
63
+ ***************************************************************/
64
+ const attrs_table = [
65
+ SDATA(data_type_t.DTP_POINTER, "subscriber", 0, null, "Subscriber of output events"),
66
+ SDATA(data_type_t.DTP_STRING, "dock_mode", 0, "floating", "floating | inline | responsive (floating on wide screens, inline on narrow)"),
67
+ SDATA(data_type_t.DTP_STRING, "dock_corner", 0, "bottom-left", "Floating placement: top-left | top-right | bottom-left | bottom-right"),
68
+ SDATA(data_type_t.DTP_STRING, "inline_selector", 0, "", "CSS selector of the container the dock mounts into when inline (e.g. a shell zone)"),
69
+ SDATA(data_type_t.DTP_STRING, "responsive_query", 0, "(max-width: 768px)", "Media query that selects inline placement when dock_mode is 'responsive'"),
70
+ SDATA(data_type_t.DTP_POINTER, "$parent", 0, null, "Where the floating dock mounts (default document.body)"),
71
+ SDATA(data_type_t.DTP_POINTER, "$container", 0, null, "Internal: the dock element"),
72
+ SDATA_END()
73
+ ];
74
+
75
+ let PRIVATE_DATA = {
76
+ windows: null, /* [{gobj, $chip, minimized}] */
77
+ z: 0, /* z-order counter handed to focused windows */
78
+ mql: null, /* MediaQueryList when dock_mode is 'responsive' */
79
+ mql_handler: null, /* its change listener (kept for teardown) */
80
+ };
81
+
82
+ let __gclass__ = null;
83
+
84
+
85
+
86
+
87
+ /******************************
88
+ * Framework Methods
89
+ ******************************/
90
+
91
+
92
+
93
+
94
+ /***************************************************************
95
+ * Framework Method: Create
96
+ ***************************************************************/
97
+ function mt_create(gobj)
98
+ {
99
+ let priv = gobj.priv;
100
+
101
+ priv.windows = [];
102
+ priv.z = 10;
103
+
104
+ /* In 'responsive' mode the placement follows a media query: watch it
105
+ * so the dock re-homes (floating <-> inline) when the viewport crosses
106
+ * the breakpoint. Set up BEFORE build_dock so the first placement is
107
+ * already correct. */
108
+ if((gobj_read_attr(gobj, "dock_mode") || "floating") === "responsive") {
109
+ let q = gobj_read_attr(gobj, "responsive_query") || "(max-width: 768px)";
110
+ priv.mql = window.matchMedia(q);
111
+ priv.mql_handler = () => {
112
+ apply_placement(gobj);
113
+ };
114
+ priv.mql.addEventListener("change", priv.mql_handler);
115
+ }
116
+
117
+ build_dock(gobj);
118
+
119
+ /*
120
+ * SERVICE subscription model
121
+ */
122
+ const subscriber = gobj_read_pointer_attr(gobj, "subscriber");
123
+ if(subscriber) {
124
+ gobj_subscribe_event(gobj, null, {}, subscriber);
125
+ }
126
+ }
127
+
128
+ /***************************************************************
129
+ * Framework Method: Destroy
130
+ ***************************************************************/
131
+ function mt_destroy(gobj)
132
+ {
133
+ let priv = gobj.priv;
134
+
135
+ if(priv.mql && priv.mql_handler) {
136
+ priv.mql.removeEventListener("change", priv.mql_handler);
137
+ priv.mql = null;
138
+ priv.mql_handler = null;
139
+ }
140
+
141
+ destroy_dock(gobj);
142
+ }
143
+
144
+
145
+
146
+
147
+ /***************************
148
+ * Local Methods
149
+ ***************************/
150
+
151
+
152
+
153
+
154
+ /************************************************************
155
+ * Inject the dock stylesheet once (theme-aware).
156
+ ************************************************************/
157
+ function ensure_dock_style()
158
+ {
159
+ if(document.getElementById('yui-dock-style')) {
160
+ return;
161
+ }
162
+ let css = `
163
+ .yui-dock {
164
+ z-index: ${DOCK_Z};
165
+ display: flex; gap: 6px; align-items: center; padding: 5px 8px;
166
+ overflow-x: auto;
167
+ background: var(--bulma-scheme-main-bis); color: var(--bulma-text);
168
+ border: 1px solid var(--bulma-border);
169
+ font-family: var(--bulma-family-primary, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
170
+ }
171
+ .yui-dock.is-empty { display: none; }
172
+
173
+ /* Floating: a detached bar hovering over the content, pinned to a corner. */
174
+ .yui-dock--floating {
175
+ position: fixed;
176
+ max-width: calc(100vw - 24px);
177
+ border-radius: 10px;
178
+ box-shadow: 0 6px 22px rgba(0,0,0,0.25);
179
+ }
180
+ .yui-dock--bottom-left { bottom: 12px; left: 12px; }
181
+ .yui-dock--bottom-right { bottom: 12px; right: 12px; }
182
+ .yui-dock--top-left { top: 12px; left: 12px; }
183
+ .yui-dock--top-right { top: 12px; right: 12px; }
184
+
185
+ /* Inline: flows inside a layout zone as a full-width taskbar row (the zone
186
+ * already provides the separating border, so the bar itself stays flat). */
187
+ .yui-dock--inline {
188
+ position: relative;
189
+ width: 100%; max-width: 100%;
190
+ border: 0;
191
+ border-radius: 0;
192
+ box-shadow: none;
193
+ }
194
+ .yui-dock-chip {
195
+ display: inline-flex; align-items: center; gap: 7px; font: inherit; font-size: 12px;
196
+ padding: 4px 5px 4px 11px; border: 1px solid var(--bulma-border); border-radius: 7px;
197
+ background: var(--bulma-scheme-main); color: var(--bulma-text); cursor: pointer; white-space: nowrap;
198
+ }
199
+ .yui-dock-chip:hover { border-color: var(--bulma-text-weak); }
200
+ .yui-dock-chip.is-active { border-color: #2563eb; color: #2563eb; background: rgba(37,99,235,0.10); font-weight: 600; }
201
+ .yui-dock-chip.is-min { opacity: 0.65; }
202
+ .yui-dock-dot { width: 8px; height: 8px; border-radius: 50%; background: #22c55e; flex: 0 0 auto; }
203
+ .yui-dock-chip.is-min .yui-dock-dot { background: var(--bulma-text-weak); }
204
+ .yui-dock-icon { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; font-size: 14px; flex: 0 0 auto; }
205
+ .yui-dock-icon svg { width: 14px; height: 14px; display: block; }
206
+ .yui-dock-icon i { line-height: 1; }
207
+ .yui-dock-label { flex: 0 0 auto; }
208
+ .yui-dock-close {
209
+ width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center;
210
+ padding: 0; margin-left: 1px; border: 0; border-radius: 4px;
211
+ background: transparent; color: var(--bulma-text-weak); cursor: pointer; flex: 0 0 auto;
212
+ }
213
+ .yui-dock-close:hover { background: #e0364a; color: #fff; }
214
+ .yui-dock-close svg { width: 11px; height: 11px; display: block; }
215
+ :root[data-theme="dark"] .yui-dock-chip.is-active { border-color: #60a5fa; color: #93c5fd; background: rgba(96,165,250,0.16); }
216
+ `;
217
+ let $style = document.createElement('style');
218
+ $style.id = 'yui-dock-style';
219
+ $style.textContent = css;
220
+ document.head.appendChild($style);
221
+ }
222
+
223
+ /************************************************************
224
+ * Build the dock element (empty, hidden until a window
225
+ * registers).
226
+ ************************************************************/
227
+ function build_dock(gobj)
228
+ {
229
+ ensure_dock_style();
230
+
231
+ let $dock = createElement2(['div', {class: 'yui-dock is-empty'}, []]);
232
+ gobj_write_attr(gobj, "$container", $dock);
233
+
234
+ apply_placement(gobj);
235
+ }
236
+
237
+ /************************************************************
238
+ * Whether the dock should render inline (in a layout zone)
239
+ * rather than floating, given the mode and — for
240
+ * 'responsive' — the current viewport.
241
+ ************************************************************/
242
+ function want_inline_placement(gobj)
243
+ {
244
+ let mode = gobj_read_attr(gobj, "dock_mode") || "floating";
245
+ if(mode === "inline") {
246
+ return true;
247
+ }
248
+ if(mode === "responsive") {
249
+ let priv = gobj.priv;
250
+ return !!(priv.mql && priv.mql.matches);
251
+ }
252
+ return false;
253
+ }
254
+
255
+ /************************************************************
256
+ * Place (or re-place) the dock: pick floating vs inline,
257
+ * set the modifier classes, and mount it in the right
258
+ * container. Also re-attaches the dock if it got detached
259
+ * (e.g. a shell that replaced its parent's children after
260
+ * the dock was first mounted, or the responsive breakpoint
261
+ * flipped). Idempotent — safe to call on every register and
262
+ * on every media-query change.
263
+ ************************************************************/
264
+ function apply_placement(gobj)
265
+ {
266
+ let $dock = gobj_read_attr(gobj, "$container");
267
+ if(!$dock) {
268
+ return;
269
+ }
270
+
271
+ /* Inline needs a host in the DOM. The shell is often built lazily, so
272
+ * its zone may not exist yet — fall back to floating until it does, so
273
+ * the dock never vanishes. */
274
+ let $inline = null;
275
+ if(want_inline_placement(gobj)) {
276
+ let sel = gobj_read_attr(gobj, "inline_selector");
277
+ if(sel) {
278
+ $inline = document.querySelector(sel);
279
+ }
280
+ }
281
+ let inline = !!$inline;
282
+
283
+ $dock.classList.toggle("yui-dock--inline", inline);
284
+ $dock.classList.toggle("yui-dock--floating", !inline);
285
+
286
+ let corner = gobj_read_attr(gobj, "dock_corner") || "bottom-left";
287
+ for(let c of ["top-left", "top-right", "bottom-left", "bottom-right"]) {
288
+ $dock.classList.toggle(`yui-dock--${c}`, !inline && c === corner);
289
+ }
290
+
291
+ let target = inline ? $inline : (gobj_read_attr(gobj, "$parent") || document.body);
292
+ if($dock.parentNode !== target) {
293
+ target.appendChild($dock);
294
+ }
295
+ }
296
+
297
+ /************************************************************
298
+ * Destroy the dock element.
299
+ ************************************************************/
300
+ function destroy_dock(gobj)
301
+ {
302
+ let $dock = gobj_read_attr(gobj, "$container");
303
+ if($dock) {
304
+ if($dock.parentNode) {
305
+ $dock.parentNode.removeChild($dock);
306
+ }
307
+ gobj_write_attr(gobj, "$container", null);
308
+ }
309
+ }
310
+
311
+ /************************************************************
312
+ * The chip's leading mark: a per-type icon if the window
313
+ * provides one (a `yi-*` class name, or inline SVG/HTML), else
314
+ * the status dot. Returns a createElement2() spec.
315
+ ************************************************************/
316
+ function chip_lead(icon)
317
+ {
318
+ if(!icon) {
319
+ return ['span', {class: 'yui-dock-dot'}, ''];
320
+ }
321
+ if(icon.charAt(0) === '<') {
322
+ return ['span', {class: 'yui-dock-icon'}, icon];
323
+ }
324
+ return ['span', {class: 'yui-dock-icon'}, [['i', {class: icon}]]];
325
+ }
326
+
327
+ /************************************************************
328
+ * Find a registry entry by its window gobj.
329
+ ************************************************************/
330
+ function find_entry(priv, win)
331
+ {
332
+ for(let e of priv.windows) {
333
+ if(e.gobj === win) {
334
+ return e;
335
+ }
336
+ }
337
+ return null;
338
+ }
339
+
340
+ /************************************************************
341
+ * Show / hide the empty state.
342
+ ************************************************************/
343
+ function sync_dock_visibility(gobj)
344
+ {
345
+ let priv = gobj.priv;
346
+ let $dock = gobj_read_attr(gobj, "$container");
347
+ if($dock) {
348
+ $dock.classList.toggle('is-empty', priv.windows.length === 0);
349
+ }
350
+ }
351
+
352
+ /************************************************************
353
+ * Mark one entry active (raised), the rest inactive.
354
+ ************************************************************/
355
+ function set_active(gobj, entry)
356
+ {
357
+ let priv = gobj.priv;
358
+ for(let e of priv.windows) {
359
+ if(e.$chip) {
360
+ e.$chip.classList.toggle('is-active', e === entry);
361
+ }
362
+ }
363
+ }
364
+
365
+ /************************************************************
366
+ * Bring a window to front and mark it active/visible.
367
+ ************************************************************/
368
+ function focus_entry(gobj, entry)
369
+ {
370
+ let priv = gobj.priv;
371
+ let $win = gobj_read_attr(entry.gobj, "$container");
372
+ if($win) {
373
+ if(entry.minimized) {
374
+ /* Clear the inline display so the window falls back to its
375
+ * Bulma `is-flex` layout (see minimize_entry). */
376
+ $win.style.removeProperty('display');
377
+ entry.minimized = false;
378
+ if(entry.$chip) {
379
+ entry.$chip.classList.remove('is-min');
380
+ }
381
+ }
382
+ priv.z += 1;
383
+ $win.style.zIndex = priv.z;
384
+ }
385
+ set_active(gobj, entry);
386
+ }
387
+
388
+ /************************************************************
389
+ * Send a window to the dock (hidden, chip dimmed).
390
+ ************************************************************/
391
+ function minimize_entry(gobj, entry)
392
+ {
393
+ let $win = gobj_read_attr(entry.gobj, "$container");
394
+ if($win) {
395
+ /* The window container carries Bulma's `is-flex`
396
+ * (display:flex !important), so a plain inline display:none
397
+ * is overridden — hide with `!important` to win. */
398
+ $win.style.setProperty('display', 'none', 'important');
399
+ }
400
+ entry.minimized = true;
401
+ if(entry.$chip) {
402
+ entry.$chip.classList.add('is-min');
403
+ entry.$chip.classList.remove('is-active');
404
+ }
405
+ }
406
+
407
+ /************************************************************
408
+ * Dock chip click: taskbar toggle — restore+focus a
409
+ * minimized/inactive window, minimize the active one.
410
+ ************************************************************/
411
+ function on_chip_click(gobj, entry)
412
+ {
413
+ if(entry.minimized || !entry.$chip.classList.contains('is-active')) {
414
+ focus_entry(gobj, entry);
415
+ } else {
416
+ minimize_entry(gobj, entry);
417
+ }
418
+ }
419
+
420
+
421
+
422
+
423
+ /***************************
424
+ * Actions
425
+ ***************************/
426
+
427
+
428
+
429
+
430
+ /************************************************************
431
+ * EV_REGISTER_WINDOW { window, title }
432
+ ************************************************************/
433
+ function ac_register_window(gobj, event, kw, src)
434
+ {
435
+ let priv = gobj.priv;
436
+
437
+ let win = kw.window;
438
+ if(!win || find_entry(priv, win)) {
439
+ return 0;
440
+ }
441
+
442
+ apply_placement(gobj);
443
+
444
+ let title = kw.title || gobj_name(win) || "window";
445
+
446
+ let entry = {gobj: win, $chip: null, minimized: false};
447
+ /* A div (not a button) so it can hold the close button — a
448
+ * button inside a button is invalid. The chip toggles; the ✕
449
+ * closes the window (EV_CLOSE_WINDOW → the window's own teardown
450
+ * → EV_UNREGISTER_WINDOW removes this chip). */
451
+ let $chip = createElement2(
452
+ ['div', {class: 'yui-dock-chip', role: 'button', tabindex: '0', title: title}, [
453
+ chip_lead(kw.icon),
454
+ ['span', {class: 'yui-dock-label'}, title],
455
+ ['button', {class: 'yui-dock-close', type: 'button', 'aria-label': 'close'}, WC_X, {
456
+ click: (evt) => {
457
+ evt.stopPropagation();
458
+ gobj_send_event(entry.gobj, "EV_CLOSE_WINDOW", {}, gobj);
459
+ }
460
+ }],
461
+ ], {
462
+ click: (evt) => {
463
+ evt.stopPropagation();
464
+ on_chip_click(gobj, entry);
465
+ }
466
+ }]
467
+ );
468
+ entry.$chip = $chip;
469
+ priv.windows.push(entry);
470
+
471
+ let $dock = gobj_read_attr(gobj, "$container");
472
+ if($dock) {
473
+ $dock.appendChild($chip);
474
+ }
475
+ sync_dock_visibility(gobj);
476
+ focus_entry(gobj, entry);
477
+ return 0;
478
+ }
479
+
480
+ /************************************************************
481
+ * EV_UNREGISTER_WINDOW { window }
482
+ ************************************************************/
483
+ function ac_unregister_window(gobj, event, kw, src)
484
+ {
485
+ let priv = gobj.priv;
486
+
487
+ let entry = find_entry(priv, kw.window);
488
+ if(!entry) {
489
+ return 0;
490
+ }
491
+ if(entry.$chip && entry.$chip.parentNode) {
492
+ entry.$chip.parentNode.removeChild(entry.$chip);
493
+ }
494
+ priv.windows = priv.windows.filter((e) => e !== entry);
495
+ sync_dock_visibility(gobj);
496
+ return 0;
497
+ }
498
+
499
+ /************************************************************
500
+ * EV_MINIMIZE_WINDOW { window }
501
+ ************************************************************/
502
+ function ac_minimize_window(gobj, event, kw, src)
503
+ {
504
+ let entry = find_entry(gobj.priv, kw.window);
505
+ if(entry) {
506
+ minimize_entry(gobj, entry);
507
+ }
508
+ return 0;
509
+ }
510
+
511
+ /************************************************************
512
+ * EV_FOCUS_WINDOW { window }
513
+ ************************************************************/
514
+ function ac_focus_window(gobj, event, kw, src)
515
+ {
516
+ let entry = find_entry(gobj.priv, kw.window);
517
+ if(entry) {
518
+ focus_entry(gobj, entry);
519
+ }
520
+ return 0;
521
+ }
522
+
523
+
524
+
525
+
526
+ /***************************
527
+ * FSM
528
+ ***************************/
529
+
530
+
531
+
532
+
533
+ /*---------------------------------------------*
534
+ * Global methods table
535
+ *---------------------------------------------*/
536
+ const gmt = {
537
+ mt_create: mt_create,
538
+ mt_destroy: mt_destroy,
539
+ };
540
+
541
+ /***************************************************************
542
+ * Create the GClass
543
+ ***************************************************************/
544
+ function create_gclass(gclass_name)
545
+ {
546
+ if(__gclass__) {
547
+ log_error(`GClass ALREADY created: ${gclass_name}`);
548
+ return -1;
549
+ }
550
+
551
+ /*---------------------------------------------*
552
+ * States
553
+ *---------------------------------------------*/
554
+ const states = [
555
+ ["ST_IDLE", [
556
+ ["EV_REGISTER_WINDOW", ac_register_window, null],
557
+ ["EV_UNREGISTER_WINDOW", ac_unregister_window, null],
558
+ ["EV_MINIMIZE_WINDOW", ac_minimize_window, null],
559
+ ["EV_FOCUS_WINDOW", ac_focus_window, null],
560
+ ]]
561
+ ];
562
+
563
+ /*---------------------------------------------*
564
+ * Events
565
+ *---------------------------------------------*/
566
+ const event_types = [
567
+ ["EV_REGISTER_WINDOW", 0],
568
+ ["EV_UNREGISTER_WINDOW", 0],
569
+ ["EV_MINIMIZE_WINDOW", 0],
570
+ ["EV_FOCUS_WINDOW", 0],
571
+ ];
572
+
573
+ __gclass__ = gclass_create(
574
+ gclass_name,
575
+ event_types,
576
+ states,
577
+ gmt,
578
+ 0, // lmt,
579
+ attrs_table,
580
+ PRIVATE_DATA,
581
+ 0, // authz_table,
582
+ 0, // command_table,
583
+ 0, // s_user_trace_level
584
+ 0 // gclass_flag
585
+ );
586
+
587
+ if(!__gclass__) {
588
+ return -1;
589
+ }
590
+
591
+ return 0;
592
+ }
593
+
594
+ /***************************************************************
595
+ * Register GClass
596
+ ***************************************************************/
597
+ function register_c_yui_window_manager()
598
+ {
599
+ return create_gclass(GCLASS_NAME);
600
+ }
601
+
602
+ export { register_c_yui_window_manager };
@@ -155,7 +155,7 @@ function mt_destroy(gobj)
155
155
  function build_ui(gobj)
156
156
  {
157
157
  let $container = createElement2(
158
- ['div', {class: 'yui-wizard', style: 'height:100%; display:flex; flex-direction:column;'}, [
158
+ ['div', {class: 'C_YUI_WIZARD', style: 'height:100%; display:flex; flex-direction:column;'}, [
159
159
  ['div', {class: 'yui-wizard-header is-flex is-align-items-center is-flex-grow-0',
160
160
  style: 'gap:.5rem; padding:.25rem .5rem;'}, [
161
161
  ['span', {class: 'yui-wizard-title is-flex-grow-1', style: 'font-weight:600;'}, ''],