@yuneta/gobj-ui 7.4.5 → 7.5.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.
@@ -19971,6 +19971,21 @@ function ac_legend_topic(gobj, event, kw, src) {
19971
19971
  return 0;
19972
19972
  }
19973
19973
  /************************************************************
19974
+ * The child chose a layout for a treedb nobody has arranged yet.
19975
+ * Only the SELECT is moved: the pick is a default, not the user's
19976
+ * choice, so it is not persisted — the day somebody drags a node the
19977
+ * saved geometry exists and `manual` is right again.
19978
+ ************************************************************/
19979
+ function ac_layout_autoset(gobj, event, kw, src) {
19980
+ let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
19981
+ if (!$container) return 0;
19982
+ let $select = $container.querySelector(".GRAPH_LAYOUT_SELECT");
19983
+ let layout = kw && kw.layout || "";
19984
+ if (!$select || !layout) return 0;
19985
+ $select.value = layout;
19986
+ return 0;
19987
+ }
19988
+ /************************************************************
19974
19989
  * Forward the find down to the graph child.
19975
19990
  ************************************************************/
19976
19991
  function ac_find_nodes$1(gobj, event, kw, src) {
@@ -20171,6 +20186,11 @@ function create_gclass$4(gclass_name) {
20171
20186
  ac_find_nodes$1,
20172
20187
  null
20173
20188
  ],
20189
+ [
20190
+ "EV_LAYOUT_AUTOSET",
20191
+ ac_layout_autoset,
20192
+ null
20193
+ ],
20174
20194
  [
20175
20195
  "EV_TOGGLE_LEGEND",
20176
20196
  ac_toggle_legend,
@@ -20229,6 +20249,7 @@ function create_gclass$4(gclass_name) {
20229
20249
  ["EV_SET_FOCUS_TOPIC", 0],
20230
20250
  ["EV_FIND_NODES", 0],
20231
20251
  ["EV_FIND_RESULT", 0],
20252
+ ["EV_LAYOUT_AUTOSET", 0],
20232
20253
  ["EV_TOGGLE_LEGEND", 0],
20233
20254
  ["EV_LEGEND_TOPIC", 0],
20234
20255
  ["EV_TOPIC_SELECTED", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT | _yuneta_gobj_js.event_flag_t.EVF_NO_WARN_SUBS],
@@ -55678,6 +55699,55 @@ function show_node_detail_popover(gobj, node_id) {
55678
55699
  * junction diamonds get their neutral fill/stroke re-themed.
55679
55700
  ************************************************************/
55680
55701
  /************************************************************
55702
+ * Has anybody ever PLACED a node of this treedb?
55703
+ *
55704
+ * Saved positions live in `__graphs__` (per topic, per node) and, on
55705
+ * older data, in a `_geometry` on the record itself. Both are read.
55706
+ ************************************************************/
55707
+ function has_saved_geometry(gobj) {
55708
+ let priv = gobj.priv;
55709
+ for (let topic of Object.keys(priv._graph_properties || {})) {
55710
+ let props = priv._graph_properties[topic];
55711
+ if (props && (0, _yuneta_gobj_js.is_object)(props.nodes) && Object.keys(props.nodes).length > 0) return true;
55712
+ }
55713
+ for (let topic of Object.keys(priv.records || {})) {
55714
+ let records = priv.records[topic];
55715
+ if (!(0, _yuneta_gobj_js.is_array)(records)) continue;
55716
+ for (let record of records) if (record && (0, _yuneta_gobj_js.is_object)(record._geometry)) return true;
55717
+ }
55718
+ return false;
55719
+ }
55720
+ /************************************************************
55721
+ * Choose a layout for a treedb nobody has arranged yet.
55722
+ *
55723
+ * `manual` means "leave every node where it was put", and where none
55724
+ * was put it means a cascade: get_default_ne_xy() walks x and y
55725
+ * together, so a treedb opened for the first time was a diagonal pile
55726
+ * of cards — 126 of them on a real one — and the only way out was to
55727
+ * know to pick a layout by hand. It is the right default only once
55728
+ * there ARE saved positions to leave alone.
55729
+ *
55730
+ * So: nothing saved and no preference of the user's ⇒ dagre. The pick
55731
+ * is deliberately NOT persisted — it is a default, not a choice, and
55732
+ * the moment the user drags one node the geometry exists and `manual`
55733
+ * becomes right again by itself.
55734
+ ************************************************************/
55735
+ function auto_layout(gobj) {
55736
+ let priv = gobj.priv;
55737
+ if (priv.layout) return;
55738
+ if (has_saved_geometry(gobj)) return;
55739
+ if (!priv.graph) return;
55740
+ let name = "dagre";
55741
+ (0, _yuneta_gobj_js.gobj_write_attr)(gobj, "layout", name);
55742
+ try {
55743
+ priv.graph.setLayout(_layouts[name]);
55744
+ } catch (e) {
55745
+ (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot set the '${name}' layout: ${e}`);
55746
+ return;
55747
+ }
55748
+ (0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_LAYOUT_AUTOSET", { layout: name });
55749
+ }
55750
+ /************************************************************
55681
55751
  * Show or hide the minimap, deciding by the SIZE of the graph.
55682
55752
  *
55683
55753
  * A minimap of a graph that already fits on screen is decoration; one
@@ -56532,6 +56602,11 @@ function ac_load_data(gobj, event, kw, src) {
56532
56602
  graph_draw(gobj).then(() => {
56533
56603
  create_links(gobj);
56534
56604
  graph_draw(gobj).then(() => {
56605
+ try {
56606
+ auto_layout(gobj);
56607
+ } catch (e) {
56608
+ (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: auto_layout failed: ${e}`);
56609
+ }
56535
56610
  graph_layout(gobj).then(() => {
56536
56611
  if (priv.edit_mode) graph_add_plugin(gobj, "history");
56537
56612
  else graph_remove_plugin(gobj, "history");
@@ -57172,6 +57247,7 @@ function create_gclass$1(gclass_name) {
57172
57247
  ["EV_FOCUS_TOPIC", 0],
57173
57248
  ["EV_FIND_NODES", 0],
57174
57249
  ["EV_FIND_RESULT", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
57250
+ ["EV_LAYOUT_AUTOSET", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
57175
57251
  ["EV_CENTER", 0],
57176
57252
  ["EV_FULLSCREEN", 0],
57177
57253
  ["EV_SET_LAYOUT", 0],
@@ -19958,6 +19958,21 @@ function ac_legend_topic(gobj, event, kw, src) {
19958
19958
  return 0;
19959
19959
  }
19960
19960
  /************************************************************
19961
+ * The child chose a layout for a treedb nobody has arranged yet.
19962
+ * Only the SELECT is moved: the pick is a default, not the user's
19963
+ * choice, so it is not persisted — the day somebody drags a node the
19964
+ * saved geometry exists and `manual` is right again.
19965
+ ************************************************************/
19966
+ function ac_layout_autoset(gobj, event, kw, src) {
19967
+ let $container = gobj_read_attr(gobj, "$container");
19968
+ if (!$container) return 0;
19969
+ let $select = $container.querySelector(".GRAPH_LAYOUT_SELECT");
19970
+ let layout = kw && kw.layout || "";
19971
+ if (!$select || !layout) return 0;
19972
+ $select.value = layout;
19973
+ return 0;
19974
+ }
19975
+ /************************************************************
19961
19976
  * Forward the find down to the graph child.
19962
19977
  ************************************************************/
19963
19978
  function ac_find_nodes$1(gobj, event, kw, src) {
@@ -20158,6 +20173,11 @@ function create_gclass$4(gclass_name) {
20158
20173
  ac_find_nodes$1,
20159
20174
  null
20160
20175
  ],
20176
+ [
20177
+ "EV_LAYOUT_AUTOSET",
20178
+ ac_layout_autoset,
20179
+ null
20180
+ ],
20161
20181
  [
20162
20182
  "EV_TOGGLE_LEGEND",
20163
20183
  ac_toggle_legend,
@@ -20216,6 +20236,7 @@ function create_gclass$4(gclass_name) {
20216
20236
  ["EV_SET_FOCUS_TOPIC", 0],
20217
20237
  ["EV_FIND_NODES", 0],
20218
20238
  ["EV_FIND_RESULT", 0],
20239
+ ["EV_LAYOUT_AUTOSET", 0],
20219
20240
  ["EV_TOGGLE_LEGEND", 0],
20220
20241
  ["EV_LEGEND_TOPIC", 0],
20221
20242
  ["EV_TOPIC_SELECTED", event_flag_t.EVF_OUTPUT_EVENT | event_flag_t.EVF_NO_WARN_SUBS],
@@ -55665,6 +55686,55 @@ function show_node_detail_popover(gobj, node_id) {
55665
55686
  * junction diamonds get their neutral fill/stroke re-themed.
55666
55687
  ************************************************************/
55667
55688
  /************************************************************
55689
+ * Has anybody ever PLACED a node of this treedb?
55690
+ *
55691
+ * Saved positions live in `__graphs__` (per topic, per node) and, on
55692
+ * older data, in a `_geometry` on the record itself. Both are read.
55693
+ ************************************************************/
55694
+ function has_saved_geometry(gobj) {
55695
+ let priv = gobj.priv;
55696
+ for (let topic of Object.keys(priv._graph_properties || {})) {
55697
+ let props = priv._graph_properties[topic];
55698
+ if (props && is_object(props.nodes) && Object.keys(props.nodes).length > 0) return true;
55699
+ }
55700
+ for (let topic of Object.keys(priv.records || {})) {
55701
+ let records = priv.records[topic];
55702
+ if (!is_array(records)) continue;
55703
+ for (let record of records) if (record && is_object(record._geometry)) return true;
55704
+ }
55705
+ return false;
55706
+ }
55707
+ /************************************************************
55708
+ * Choose a layout for a treedb nobody has arranged yet.
55709
+ *
55710
+ * `manual` means "leave every node where it was put", and where none
55711
+ * was put it means a cascade: get_default_ne_xy() walks x and y
55712
+ * together, so a treedb opened for the first time was a diagonal pile
55713
+ * of cards — 126 of them on a real one — and the only way out was to
55714
+ * know to pick a layout by hand. It is the right default only once
55715
+ * there ARE saved positions to leave alone.
55716
+ *
55717
+ * So: nothing saved and no preference of the user's ⇒ dagre. The pick
55718
+ * is deliberately NOT persisted — it is a default, not a choice, and
55719
+ * the moment the user drags one node the geometry exists and `manual`
55720
+ * becomes right again by itself.
55721
+ ************************************************************/
55722
+ function auto_layout(gobj) {
55723
+ let priv = gobj.priv;
55724
+ if (priv.layout) return;
55725
+ if (has_saved_geometry(gobj)) return;
55726
+ if (!priv.graph) return;
55727
+ let name = "dagre";
55728
+ gobj_write_attr(gobj, "layout", name);
55729
+ try {
55730
+ priv.graph.setLayout(_layouts[name]);
55731
+ } catch (e) {
55732
+ log_error(`${gobj_short_name(gobj)}: cannot set the '${name}' layout: ${e}`);
55733
+ return;
55734
+ }
55735
+ gobj_publish_event(gobj, "EV_LAYOUT_AUTOSET", { layout: name });
55736
+ }
55737
+ /************************************************************
55668
55738
  * Show or hide the minimap, deciding by the SIZE of the graph.
55669
55739
  *
55670
55740
  * A minimap of a graph that already fits on screen is decoration; one
@@ -56519,6 +56589,11 @@ function ac_load_data(gobj, event, kw, src) {
56519
56589
  graph_draw(gobj).then(() => {
56520
56590
  create_links(gobj);
56521
56591
  graph_draw(gobj).then(() => {
56592
+ try {
56593
+ auto_layout(gobj);
56594
+ } catch (e) {
56595
+ log_error(`${gobj_short_name(gobj)}: auto_layout failed: ${e}`);
56596
+ }
56522
56597
  graph_layout(gobj).then(() => {
56523
56598
  if (priv.edit_mode) graph_add_plugin(gobj, "history");
56524
56599
  else graph_remove_plugin(gobj, "history");
@@ -57159,6 +57234,7 @@ function create_gclass$1(gclass_name) {
57159
57234
  ["EV_FOCUS_TOPIC", 0],
57160
57235
  ["EV_FIND_NODES", 0],
57161
57236
  ["EV_FIND_RESULT", event_flag_t.EVF_OUTPUT_EVENT],
57237
+ ["EV_LAYOUT_AUTOSET", event_flag_t.EVF_OUTPUT_EVENT],
57162
57238
  ["EV_CENTER", 0],
57163
57239
  ["EV_FULLSCREEN", 0],
57164
57240
  ["EV_SET_LAYOUT", 0],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.4.5",
3
+ "version": "7.5.0",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -4483,6 +4483,80 @@ function show_node_detail_popover(gobj, node_id)
4483
4483
  * not re-themed by setTheme()) are regenerated; structural
4484
4484
  * junction diamonds get their neutral fill/stroke re-themed.
4485
4485
  ************************************************************/
4486
+ /************************************************************
4487
+ * Has anybody ever PLACED a node of this treedb?
4488
+ *
4489
+ * Saved positions live in `__graphs__` (per topic, per node) and, on
4490
+ * older data, in a `_geometry` on the record itself. Both are read.
4491
+ ************************************************************/
4492
+ function has_saved_geometry(gobj)
4493
+ {
4494
+ let priv = gobj.priv;
4495
+
4496
+ for(let topic of Object.keys(priv._graph_properties || {})) {
4497
+ let props = priv._graph_properties[topic];
4498
+ if(props && is_object(props.nodes) && Object.keys(props.nodes).length > 0) {
4499
+ return true;
4500
+ }
4501
+ }
4502
+
4503
+ for(let topic of Object.keys(priv.records || {})) {
4504
+ let records = priv.records[topic];
4505
+ if(!is_array(records)) {
4506
+ continue;
4507
+ }
4508
+ for(let record of records) {
4509
+ if(record && is_object(record._geometry)) {
4510
+ return true;
4511
+ }
4512
+ }
4513
+ }
4514
+
4515
+ return false;
4516
+ }
4517
+
4518
+ /************************************************************
4519
+ * Choose a layout for a treedb nobody has arranged yet.
4520
+ *
4521
+ * `manual` means "leave every node where it was put", and where none
4522
+ * was put it means a cascade: get_default_ne_xy() walks x and y
4523
+ * together, so a treedb opened for the first time was a diagonal pile
4524
+ * of cards — 126 of them on a real one — and the only way out was to
4525
+ * know to pick a layout by hand. It is the right default only once
4526
+ * there ARE saved positions to leave alone.
4527
+ *
4528
+ * So: nothing saved and no preference of the user's ⇒ dagre. The pick
4529
+ * is deliberately NOT persisted — it is a default, not a choice, and
4530
+ * the moment the user drags one node the geometry exists and `manual`
4531
+ * becomes right again by itself.
4532
+ ************************************************************/
4533
+ function auto_layout(gobj)
4534
+ {
4535
+ let priv = gobj.priv;
4536
+
4537
+ if(priv.layout) {
4538
+ return; /* the user picked one for this treedb */
4539
+ }
4540
+ if(has_saved_geometry(gobj)) {
4541
+ return; /* somebody arranged it: leave it alone */
4542
+ }
4543
+ if(!priv.graph) {
4544
+ return;
4545
+ }
4546
+
4547
+ let name = "dagre";
4548
+ gobj_write_attr(gobj, "layout", name);
4549
+ try {
4550
+ priv.graph.setLayout(_layouts[name]);
4551
+ } catch(e) {
4552
+ log_error(`${gobj_short_name(gobj)}: cannot set the '${name}' layout: ${e}`);
4553
+ return;
4554
+ }
4555
+ /* The toolbar's select was filled before the data arrived, so it is
4556
+ * still showing `manual`: tell it what the graph is actually doing. */
4557
+ gobj_publish_event(gobj, "EV_LAYOUT_AUTOSET", {layout: name});
4558
+ }
4559
+
4486
4560
  /************************************************************
4487
4561
  * Show or hide the minimap, deciding by the SIZE of the graph.
4488
4562
  *
@@ -5770,6 +5844,14 @@ function ac_load_data(gobj, event, kw, src)
5770
5844
  graph_draw(gobj).then(() => { // draw nodes, else the link fails
5771
5845
  create_links(gobj);
5772
5846
  graph_draw(gobj).then(() => {
5847
+ /* Before the layout runs, and only now: whether anybody has
5848
+ * ever placed a node of this treedb is not known until its
5849
+ * records and __graphs__ are in. */
5850
+ try {
5851
+ auto_layout(gobj);
5852
+ } catch(e) {
5853
+ log_error(`${gobj_short_name(gobj)}: auto_layout failed: ${e}`);
5854
+ }
5773
5855
  graph_layout(gobj).then(() => {
5774
5856
  if(priv.edit_mode) {
5775
5857
  graph_add_plugin(gobj, "history");
@@ -6563,6 +6645,7 @@ function create_gclass(gclass_name)
6563
6645
  ["EV_FOCUS_TOPIC", 0],
6564
6646
  ["EV_FIND_NODES", 0],
6565
6647
  ["EV_FIND_RESULT", event_flag_t.EVF_OUTPUT_EVENT],
6648
+ ["EV_LAYOUT_AUTOSET", event_flag_t.EVF_OUTPUT_EVENT],
6566
6649
  ["EV_CENTER", 0],
6567
6650
  ["EV_FULLSCREEN", 0],
6568
6651
  ["EV_SET_LAYOUT", 0],
@@ -2337,6 +2337,27 @@ function ac_legend_topic(gobj, event, kw, src)
2337
2337
  return 0;
2338
2338
  }
2339
2339
 
2340
+ /************************************************************
2341
+ * The child chose a layout for a treedb nobody has arranged yet.
2342
+ * Only the SELECT is moved: the pick is a default, not the user's
2343
+ * choice, so it is not persisted — the day somebody drags a node the
2344
+ * saved geometry exists and `manual` is right again.
2345
+ ************************************************************/
2346
+ function ac_layout_autoset(gobj, event, kw, src)
2347
+ {
2348
+ let $container = gobj_read_attr(gobj, "$container");
2349
+ if(!$container) {
2350
+ return 0;
2351
+ }
2352
+ let $select = $container.querySelector(".GRAPH_LAYOUT_SELECT");
2353
+ let layout = (kw && kw.layout) || "";
2354
+ if(!$select || !layout) {
2355
+ return 0;
2356
+ }
2357
+ $select.value = layout;
2358
+ return 0;
2359
+ }
2360
+
2340
2361
  /************************************************************
2341
2362
  * Forward the find down to the graph child.
2342
2363
  ************************************************************/
@@ -2490,6 +2511,7 @@ function create_gclass(gclass_name)
2490
2511
  ["EV_SET_OPERATION_MODE", ac_set_operation_mode, null],
2491
2512
  ["EV_SET_FOCUS_TOPIC", ac_set_focus_topic, null],
2492
2513
  ["EV_FIND_NODES", ac_find_nodes, null],
2514
+ ["EV_LAYOUT_AUTOSET", ac_layout_autoset, null],
2493
2515
  ["EV_TOGGLE_LEGEND", ac_toggle_legend, null],
2494
2516
  ["EV_LEGEND_TOPIC", ac_legend_topic, null],
2495
2517
  ["EV_FIND_RESULT", ac_find_result, null],
@@ -2529,6 +2551,7 @@ function create_gclass(gclass_name)
2529
2551
  ["EV_SET_FOCUS_TOPIC", 0],
2530
2552
  ["EV_FIND_NODES", 0],
2531
2553
  ["EV_FIND_RESULT", 0],
2554
+ ["EV_LAYOUT_AUTOSET", 0],
2532
2555
  ["EV_TOGGLE_LEGEND", 0],
2533
2556
  ["EV_LEGEND_TOPIC", 0],
2534
2557
  ["EV_TOPIC_SELECTED",