@yuneta/gobj-ui 7.23.79 → 7.23.80

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/README.md CHANGED
@@ -1374,6 +1374,20 @@ The ports of an open card grew with this (radius 14 on a card, 8 on a chip
1374
1374
  since `7.23.79`; 10 / 5 in `7.23.75`, 2 px stroke): they are what a link is drawn from and what a resize takes hold
1375
1375
  of, and at radius 6 with a hairline nobody could tell they were either.
1376
1376
 
1377
+ **A size nobody chose is not saved** (since `7.23.80`). `Save` collects the
1378
+ geometry of every card into `__graphs__`, and it used to write the SIZE and
1379
+ the port radius of every card too — so every Save froze the library's size of
1380
+ the day into the treedb, and a later default (the bigger ports above) reached
1381
+ no saved treedb: the same trap as the invented cascade coordinates, for the
1382
+ size. A card on its tier's default now saves its position and nothing else;
1383
+ a closed node saves no size at all (a square is not the card's size), its
1384
+ entry keeps what it had. And the node's context menu, in edition, has the way
1385
+ back: **reset sizes** / **reset topic sizes** forget every saved size, port
1386
+ radius and per-port radius — per node and as topic defaults from `resize all`
1387
+ — for all topics or the node's, put the library's defaults back on every card
1388
+ on the spot, and arm Save. Positions and edge styles are not touched.
1389
+ Consumer i18n keys: `reset sizes`, `reset topic sizes`.
1390
+
1377
1391
  ### The legend is the graph's layer control
1378
1392
 
1379
1393
  The legend strip under the toolbar is **always there** now (the *Legend*
@@ -56057,17 +56057,36 @@ function update_geometry(gobj, node_id) {
56057
56057
  let topic_props = priv._graph_properties[topic_name];
56058
56058
  if (!(0, _yuneta_gobj_js.is_object)(topic_props.nodes)) topic_props.nodes = {};
56059
56059
  let node_props = topic_props.nodes[record.id] || {};
56060
- (0, _yuneta_gobj_js.json_object_update)(node_props, (0, _yuneta_gobj_js.kw_clone_by_keys)(gobj, style, [
56060
+ let picked = (0, _yuneta_gobj_js.kw_clone_by_keys)(gobj, style, [
56061
56061
  "x",
56062
56062
  "y",
56063
56063
  "size",
56064
56064
  "portR"
56065
- ]));
56066
- let ports = (nodedata.style || {}).ports || [];
56067
- let port_sizes = {};
56068
- for (let i = 0; i < ports.length; i++) if (ports[i].r != null) port_sizes[ports[i].key] = ports[i].r;
56069
- if (Object.keys(port_sizes).length > 0) node_props.port_sizes = port_sizes;
56070
- else delete node_props.port_sizes;
56065
+ ]);
56066
+ if (node_is_compact(gobj, node_id)) {
56067
+ delete picked.size;
56068
+ delete picked.portR;
56069
+ } else {
56070
+ let desc = nodedata.data.desc;
56071
+ let def_size = card_size_for(desc.node_treedb_type, !!pills_html_of(gobj, nodedata));
56072
+ if ((0, _yuneta_gobj_js.is_array)(picked.size) && picked.size[0] === def_size[0] && picked.size[1] === def_size[1]) {
56073
+ delete picked.size;
56074
+ delete node_props.size;
56075
+ }
56076
+ let def_r = desc.node_treedb_type === "child" ? PORT_R_CHILD : PORT_R_ENTITY;
56077
+ if (picked.portR === def_r) {
56078
+ delete picked.portR;
56079
+ delete node_props.portR;
56080
+ }
56081
+ }
56082
+ (0, _yuneta_gobj_js.json_object_update)(node_props, picked);
56083
+ if (!node_is_compact(gobj, node_id)) {
56084
+ let ports = (nodedata.style || {}).ports || [];
56085
+ let port_sizes = {};
56086
+ for (let i = 0; i < ports.length; i++) if (ports[i].r != null) port_sizes[ports[i].key] = ports[i].r;
56087
+ if (Object.keys(port_sizes).length > 0) node_props.port_sizes = port_sizes;
56088
+ else delete node_props.port_sizes;
56089
+ }
56071
56090
  topic_props.nodes[record.id] = node_props;
56072
56091
  nodedata.data.graph_props = node_props;
56073
56092
  }
@@ -59146,6 +59165,8 @@ function build_node_context_menu(gobj, node_id) {
59146
59165
  if (gobj.priv.edit_mode && !node_is_compact(gobj, node_id)) {
59147
59166
  items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize all"), "resize_all_nodes"));
59148
59167
  items.push(ctx_item("g6-icon-resize", (0, i18next.t)("resize topic nodes"), "resize_topic_nodes"));
59168
+ items.push(ctx_item("g6-icon-undo", (0, i18next.t)("reset sizes"), "reset_all_sizes"));
59169
+ items.push(ctx_item("g6-icon-undo", (0, i18next.t)("reset topic sizes"), "reset_topic_sizes"));
59149
59170
  }
59150
59171
  return items;
59151
59172
  }
@@ -59182,6 +59203,12 @@ function handle_context_menu_click(gobj, value) {
59182
59203
  case "resize_topic_nodes":
59183
59204
  copy_size_to_nodes(gobj, true);
59184
59205
  break;
59206
+ case "reset_all_sizes":
59207
+ reset_sizes(gobj, false);
59208
+ break;
59209
+ case "reset_topic_sizes":
59210
+ reset_sizes(gobj, true);
59211
+ break;
59185
59212
  case "resize_all_ports":
59186
59213
  copy_size_to_ports(gobj, false);
59187
59214
  break;
@@ -59243,6 +59270,56 @@ function copy_size_to_nodes(gobj, same_topic_only) {
59243
59270
  }
59244
59271
  }
59245
59272
  /************************************************************
59273
+ * Forget every SAVED size: the card sizes, the port radii and the
59274
+ * per-port radii, per node and as topic defaults (`resize all`),
59275
+ * for one topic or for all of them. The cards go back to the
59276
+ * library's defaults on the spot, and Save writes the cleared
59277
+ * entries -- a size nobody chose is not written back (see
59278
+ * update_geometry). Positions and edge styles are not touched:
59279
+ * they are a different choice.
59280
+ ************************************************************/
59281
+ function reset_sizes(gobj, same_topic_only) {
59282
+ let priv = gobj.priv;
59283
+ let graph = priv.graph;
59284
+ let topic = "";
59285
+ if (same_topic_only) {
59286
+ let nd = priv._context_node_id ? graph.getNodeData(priv._context_node_id) : null;
59287
+ if (!nd || !nd.data || !nd.data.topic_name) {
59288
+ (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: reset topic sizes without a node`);
59289
+ return;
59290
+ }
59291
+ topic = nd.data.topic_name;
59292
+ }
59293
+ const SIZE_KEYS = [
59294
+ "size",
59295
+ "portR",
59296
+ "port_sizes"
59297
+ ];
59298
+ let strip = (props) => {
59299
+ if (!(0, _yuneta_gobj_js.is_object)(props)) return;
59300
+ for (let k of SIZE_KEYS) delete props[k];
59301
+ };
59302
+ for (const [topic_name, props] of Object.entries(priv._graph_properties || {})) {
59303
+ if (topic && topic_name !== topic) continue;
59304
+ if ((0, _yuneta_gobj_js.is_object)(props.nodes)) for (let node_props of Object.values(props.nodes)) strip(node_props);
59305
+ strip(props.defaults);
59306
+ }
59307
+ let ids = [];
59308
+ for (let nd of graph.getNodeData() || []) {
59309
+ if (!nd || !nd.data || !nd.data.desc || is_more_node(nd)) continue;
59310
+ if (topic && nd.data.topic_name !== topic) continue;
59311
+ strip(nd.data.graph_props);
59312
+ if (nd.data.record) strip(nd.data.record._geometry);
59313
+ ids.push(nd.id);
59314
+ }
59315
+ reshape_nodes(gobj, ids);
59316
+ graph.draw().then(() => {
59317
+ update_resize_handles_position(gobj);
59318
+ update_port_resize_handles_position(gobj);
59319
+ mark_graph_dirty(gobj);
59320
+ });
59321
+ }
59322
+ /************************************************************
59246
59323
  * Copy the selected port's radius to matching ports.
59247
59324
  * If same_topic_only=true, only ports in same-topic nodes.
59248
59325
  * If same_topic_only=false, matching ports in all nodes.
@@ -56052,17 +56052,36 @@ function update_geometry(gobj, node_id) {
56052
56052
  let topic_props = priv._graph_properties[topic_name];
56053
56053
  if (!is_object(topic_props.nodes)) topic_props.nodes = {};
56054
56054
  let node_props = topic_props.nodes[record.id] || {};
56055
- json_object_update(node_props, kw_clone_by_keys(gobj, style, [
56055
+ let picked = kw_clone_by_keys(gobj, style, [
56056
56056
  "x",
56057
56057
  "y",
56058
56058
  "size",
56059
56059
  "portR"
56060
- ]));
56061
- let ports = (nodedata.style || {}).ports || [];
56062
- let port_sizes = {};
56063
- for (let i = 0; i < ports.length; i++) if (ports[i].r != null) port_sizes[ports[i].key] = ports[i].r;
56064
- if (Object.keys(port_sizes).length > 0) node_props.port_sizes = port_sizes;
56065
- else delete node_props.port_sizes;
56060
+ ]);
56061
+ if (node_is_compact(gobj, node_id)) {
56062
+ delete picked.size;
56063
+ delete picked.portR;
56064
+ } else {
56065
+ let desc = nodedata.data.desc;
56066
+ let def_size = card_size_for(desc.node_treedb_type, !!pills_html_of(gobj, nodedata));
56067
+ if (is_array(picked.size) && picked.size[0] === def_size[0] && picked.size[1] === def_size[1]) {
56068
+ delete picked.size;
56069
+ delete node_props.size;
56070
+ }
56071
+ let def_r = desc.node_treedb_type === "child" ? PORT_R_CHILD : PORT_R_ENTITY;
56072
+ if (picked.portR === def_r) {
56073
+ delete picked.portR;
56074
+ delete node_props.portR;
56075
+ }
56076
+ }
56077
+ json_object_update(node_props, picked);
56078
+ if (!node_is_compact(gobj, node_id)) {
56079
+ let ports = (nodedata.style || {}).ports || [];
56080
+ let port_sizes = {};
56081
+ for (let i = 0; i < ports.length; i++) if (ports[i].r != null) port_sizes[ports[i].key] = ports[i].r;
56082
+ if (Object.keys(port_sizes).length > 0) node_props.port_sizes = port_sizes;
56083
+ else delete node_props.port_sizes;
56084
+ }
56066
56085
  topic_props.nodes[record.id] = node_props;
56067
56086
  nodedata.data.graph_props = node_props;
56068
56087
  }
@@ -59141,6 +59160,8 @@ function build_node_context_menu(gobj, node_id) {
59141
59160
  if (gobj.priv.edit_mode && !node_is_compact(gobj, node_id)) {
59142
59161
  items.push(ctx_item("g6-icon-resize", t("resize all"), "resize_all_nodes"));
59143
59162
  items.push(ctx_item("g6-icon-resize", t("resize topic nodes"), "resize_topic_nodes"));
59163
+ items.push(ctx_item("g6-icon-undo", t("reset sizes"), "reset_all_sizes"));
59164
+ items.push(ctx_item("g6-icon-undo", t("reset topic sizes"), "reset_topic_sizes"));
59144
59165
  }
59145
59166
  return items;
59146
59167
  }
@@ -59177,6 +59198,12 @@ function handle_context_menu_click(gobj, value) {
59177
59198
  case "resize_topic_nodes":
59178
59199
  copy_size_to_nodes(gobj, true);
59179
59200
  break;
59201
+ case "reset_all_sizes":
59202
+ reset_sizes(gobj, false);
59203
+ break;
59204
+ case "reset_topic_sizes":
59205
+ reset_sizes(gobj, true);
59206
+ break;
59180
59207
  case "resize_all_ports":
59181
59208
  copy_size_to_ports(gobj, false);
59182
59209
  break;
@@ -59238,6 +59265,56 @@ function copy_size_to_nodes(gobj, same_topic_only) {
59238
59265
  }
59239
59266
  }
59240
59267
  /************************************************************
59268
+ * Forget every SAVED size: the card sizes, the port radii and the
59269
+ * per-port radii, per node and as topic defaults (`resize all`),
59270
+ * for one topic or for all of them. The cards go back to the
59271
+ * library's defaults on the spot, and Save writes the cleared
59272
+ * entries -- a size nobody chose is not written back (see
59273
+ * update_geometry). Positions and edge styles are not touched:
59274
+ * they are a different choice.
59275
+ ************************************************************/
59276
+ function reset_sizes(gobj, same_topic_only) {
59277
+ let priv = gobj.priv;
59278
+ let graph = priv.graph;
59279
+ let topic = "";
59280
+ if (same_topic_only) {
59281
+ let nd = priv._context_node_id ? graph.getNodeData(priv._context_node_id) : null;
59282
+ if (!nd || !nd.data || !nd.data.topic_name) {
59283
+ log_error(`${gobj_short_name(gobj)}: reset topic sizes without a node`);
59284
+ return;
59285
+ }
59286
+ topic = nd.data.topic_name;
59287
+ }
59288
+ const SIZE_KEYS = [
59289
+ "size",
59290
+ "portR",
59291
+ "port_sizes"
59292
+ ];
59293
+ let strip = (props) => {
59294
+ if (!is_object(props)) return;
59295
+ for (let k of SIZE_KEYS) delete props[k];
59296
+ };
59297
+ for (const [topic_name, props] of Object.entries(priv._graph_properties || {})) {
59298
+ if (topic && topic_name !== topic) continue;
59299
+ if (is_object(props.nodes)) for (let node_props of Object.values(props.nodes)) strip(node_props);
59300
+ strip(props.defaults);
59301
+ }
59302
+ let ids = [];
59303
+ for (let nd of graph.getNodeData() || []) {
59304
+ if (!nd || !nd.data || !nd.data.desc || is_more_node(nd)) continue;
59305
+ if (topic && nd.data.topic_name !== topic) continue;
59306
+ strip(nd.data.graph_props);
59307
+ if (nd.data.record) strip(nd.data.record._geometry);
59308
+ ids.push(nd.id);
59309
+ }
59310
+ reshape_nodes(gobj, ids);
59311
+ graph.draw().then(() => {
59312
+ update_resize_handles_position(gobj);
59313
+ update_port_resize_handles_position(gobj);
59314
+ mark_graph_dirty(gobj);
59315
+ });
59316
+ }
59317
+ /************************************************************
59241
59318
  * Copy the selected port's radius to matching ports.
59242
59319
  * If same_topic_only=true, only ports in same-topic nodes.
59243
59320
  * If same_topic_only=false, matching ports in all nodes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.79",
3
+ "version": "7.23.80",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -2732,26 +2732,50 @@ function update_geometry(gobj, node_id)
2732
2732
  topic_props.nodes = {};
2733
2733
  }
2734
2734
 
2735
- // Extract geometry from render style
2735
+ /* Extract geometry from render style -- the POSITION always, the
2736
+ * SIZE only when somebody chose it. A card on the tier's default
2737
+ * used to be saved with that default, so every Save froze the
2738
+ * library's size of the day into `__graphs__` and a later default
2739
+ * (bigger ports, 7.23.75/79) reached no saved treedb: the same
2740
+ * trap as the invented cascade coordinates, for the size. And a
2741
+ * CLOSED node is a square: its render size is not the card's and
2742
+ * is never saved as one -- the entry keeps what it had. */
2736
2743
  let node_props = topic_props.nodes[record.id] || {};
2737
- json_object_update(
2738
- node_props,
2739
- kw_clone_by_keys(gobj, style, ["x", "y", "size", "portR"])
2740
- );
2744
+ let picked = kw_clone_by_keys(gobj, style, ["x", "y", "size", "portR"]);
2745
+ if(node_is_compact(gobj, node_id)) {
2746
+ delete picked.size;
2747
+ delete picked.portR;
2748
+ } else {
2749
+ let desc = nodedata.data.desc;
2750
+ let def_size = card_size_for(desc.node_treedb_type, !!pills_html_of(gobj, nodedata));
2751
+ if(is_array(picked.size) && picked.size[0] === def_size[0] &&
2752
+ picked.size[1] === def_size[1]) {
2753
+ delete picked.size;
2754
+ delete node_props.size;
2755
+ }
2756
+ let def_r = (desc.node_treedb_type === 'child')? PORT_R_CHILD : PORT_R_ENTITY;
2757
+ if(picked.portR === def_r) {
2758
+ delete picked.portR;
2759
+ delete node_props.portR;
2760
+ }
2761
+ }
2762
+ json_object_update(node_props, picked);
2741
2763
 
2742
2764
  // Save per-port radius values (only ports with custom r)
2743
- let node_style = nodedata.style || {};
2744
- let ports = node_style.ports || [];
2745
- let port_sizes = {};
2746
- for(let i = 0; i < ports.length; i++) {
2747
- if(ports[i].r != null) {
2748
- port_sizes[ports[i].key] = ports[i].r;
2765
+ if(!node_is_compact(gobj, node_id)) {
2766
+ let node_style = nodedata.style || {};
2767
+ let ports = node_style.ports || [];
2768
+ let port_sizes = {};
2769
+ for(let i = 0; i < ports.length; i++) {
2770
+ if(ports[i].r != null) {
2771
+ port_sizes[ports[i].key] = ports[i].r;
2772
+ }
2773
+ }
2774
+ if(Object.keys(port_sizes).length > 0) {
2775
+ node_props.port_sizes = port_sizes;
2776
+ } else {
2777
+ delete node_props.port_sizes;
2749
2778
  }
2750
- }
2751
- if(Object.keys(port_sizes).length > 0) {
2752
- node_props.port_sizes = port_sizes;
2753
- } else {
2754
- delete node_props.port_sizes;
2755
2779
  }
2756
2780
 
2757
2781
  topic_props.nodes[record.id] = node_props;
@@ -7410,6 +7434,11 @@ function build_node_context_menu(gobj, node_id)
7410
7434
  if(gobj.priv.edit_mode && !node_is_compact(gobj, node_id)) {
7411
7435
  items.push(ctx_item('g6-icon-resize', t('resize all'), 'resize_all_nodes'));
7412
7436
  items.push(ctx_item('g6-icon-resize', t('resize topic nodes'), 'resize_topic_nodes'));
7437
+ /* The way back: the sizes somebody saved -- or that a Save
7438
+ * froze before 7.23.80 -- forgotten, the library's defaults
7439
+ * back on every card. */
7440
+ items.push(ctx_item('g6-icon-undo', t('reset sizes'), 'reset_all_sizes'));
7441
+ items.push(ctx_item('g6-icon-undo', t('reset topic sizes'), 'reset_topic_sizes'));
7413
7442
  }
7414
7443
 
7415
7444
  return items;
@@ -7460,6 +7489,12 @@ function handle_context_menu_click(gobj, value)
7460
7489
  case 'resize_topic_nodes':
7461
7490
  copy_size_to_nodes(gobj, true);
7462
7491
  break;
7492
+ case 'reset_all_sizes':
7493
+ reset_sizes(gobj, false);
7494
+ break;
7495
+ case 'reset_topic_sizes':
7496
+ reset_sizes(gobj, true);
7497
+ break;
7463
7498
  case 'resize_all_ports':
7464
7499
  copy_size_to_ports(gobj, false);
7465
7500
  break;
@@ -7564,6 +7599,75 @@ function copy_size_to_nodes(gobj, same_topic_only)
7564
7599
  }
7565
7600
  }
7566
7601
 
7602
+ /************************************************************
7603
+ * Forget every SAVED size: the card sizes, the port radii and the
7604
+ * per-port radii, per node and as topic defaults (`resize all`),
7605
+ * for one topic or for all of them. The cards go back to the
7606
+ * library's defaults on the spot, and Save writes the cleared
7607
+ * entries -- a size nobody chose is not written back (see
7608
+ * update_geometry). Positions and edge styles are not touched:
7609
+ * they are a different choice.
7610
+ ************************************************************/
7611
+ function reset_sizes(gobj, same_topic_only)
7612
+ {
7613
+ let priv = gobj.priv;
7614
+ let graph = priv.graph;
7615
+
7616
+ let topic = "";
7617
+ if(same_topic_only) {
7618
+ let nd = priv._context_node_id? graph.getNodeData(priv._context_node_id) : null;
7619
+ if(!nd || !nd.data || !nd.data.topic_name) {
7620
+ log_error(`${gobj_short_name(gobj)}: reset topic sizes without a node`);
7621
+ return;
7622
+ }
7623
+ topic = nd.data.topic_name;
7624
+ }
7625
+ const SIZE_KEYS = ["size", "portR", "port_sizes"];
7626
+ let strip = (props) => {
7627
+ if(!is_object(props)) {
7628
+ return;
7629
+ }
7630
+ for(let k of SIZE_KEYS) {
7631
+ delete props[k];
7632
+ }
7633
+ };
7634
+
7635
+ /* The saved entries, on screen or folded away. */
7636
+ for(const [topic_name, props] of Object.entries(priv._graph_properties || {})) {
7637
+ if(topic && topic_name !== topic) {
7638
+ continue;
7639
+ }
7640
+ if(is_object(props.nodes)) {
7641
+ for(let node_props of Object.values(props.nodes)) {
7642
+ strip(node_props);
7643
+ }
7644
+ }
7645
+ strip(props.defaults);
7646
+ }
7647
+
7648
+ /* The nodes on screen: their own copy of the entry, then the shape. */
7649
+ let ids = [];
7650
+ for(let nd of (graph.getNodeData() || [])) {
7651
+ if(!nd || !nd.data || !nd.data.desc || is_more_node(nd)) {
7652
+ continue;
7653
+ }
7654
+ if(topic && nd.data.topic_name !== topic) {
7655
+ continue;
7656
+ }
7657
+ strip(nd.data.graph_props);
7658
+ if(nd.data.record) {
7659
+ strip(nd.data.record._geometry);
7660
+ }
7661
+ ids.push(nd.id);
7662
+ }
7663
+ reshape_nodes(gobj, ids);
7664
+ graph.draw().then(() => {
7665
+ update_resize_handles_position(gobj);
7666
+ update_port_resize_handles_position(gobj);
7667
+ mark_graph_dirty(gobj);
7668
+ });
7669
+ }
7670
+
7567
7671
  /************************************************************
7568
7672
  * Copy the selected port's radius to matching ports.
7569
7673
  * If same_topic_only=true, only ports in same-topic nodes.