@yuneta/gobj-ui 7.23.148 → 7.23.150

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
@@ -1425,6 +1425,30 @@ layouts by three thin adapters in `c_g6_nodes_tree.js`:
1425
1425
  construction, across the ring or along the radius; several roots share the
1426
1426
  circle around an empty centre.
1427
1427
 
1428
+ **Elbow edges** (`7.23.149`) are an option of the edges, not a layout: the
1429
+ toolbar's `GRAPH_EDGE_ELBOW` toggle sets `edge_shape` to `elbow`, and every
1430
+ edge goes straight out of the parent's port to the channel half way to the
1431
+ child, along it, and straight into the child's port — mxGraph's tree routing.
1432
+ The children of one hook share a row and a port, so they share the channel
1433
+ and read as one bus. The two edge types (`treedb-elbow-v` / `-h`) subclass
1434
+ G6's `Polyline` and compute the elbow from the ports on every draw, so
1435
+ dragging, folding and relayout need nothing else. It follows the reading
1436
+ direction, and a layout with no rows (`rowless_layouts`: `radial`,
1437
+ `d3-force`, `force-atlas2`) keeps the curve, with the toggle disabled.
1438
+ `edge_shape` is `SDF_PERSIST` on `C_YUI_TREEDB_GRAPH`, a preference per
1439
+ treedb like `node_labels`. Consumer key: `elbow edges`.
1440
+
1441
+ Two cases are not a channel (`7.23.150`, `treedb_elbow.js`, pure and
1442
+ tested). An elbow that does not run **forward** — the target above its
1443
+ source or in the same row, which one edge of every reciprocal pair is —
1444
+ goes **round** the two cards instead of through them: a short run out of its
1445
+ port, along the outside of both, and in from the other port's own side. And
1446
+ the edges joining the **same two cards**, either way round, take **lanes**
1447
+ 10px apart in the order they were made (0, +1, −1…), so a new one never
1448
+ moves the ones already drawn; a detour on a negative lane goes round the
1449
+ left. The detour clears the two cards it joins, not the others: a card of a
1450
+ third record standing in its way is crossed, as a curve would cross it.
1451
+
1428
1452
  All three take the **same spanning tree**, chosen deterministically: roots are the
1429
1453
  nodes with no incoming edge, in node order; a node belongs to the **first
1430
1454
  parent that reaches it** in a breadth-first walk (the place, not the
@@ -29630,6 +29630,54 @@ function layout_radial(nodes, edges, opts) {
29630
29630
  }
29631
29631
  return pos;
29632
29632
  }
29633
+ /************************************************************
29634
+ * The lane of `id` among `ids`, the edges joining the same two
29635
+ * cards: 0, then +1, -1, +2, -2... in the order they were made.
29636
+ * Edge ids end in a counter, so a numeric sort is that order.
29637
+ ************************************************************/
29638
+ function elbow_lane(ids, id) {
29639
+ let k = ids.slice().sort((a, b) => String(a).localeCompare(String(b), void 0, { numeric: true })).indexOf(id);
29640
+ if (k <= 0) return 0;
29641
+ return (k % 2 ? 1 : -1) * Math.ceil(k / 2);
29642
+ }
29643
+ function swap(p) {
29644
+ return [p[1], p[0]];
29645
+ }
29646
+ function swap_box(b) {
29647
+ return {
29648
+ x1: b.y1,
29649
+ y1: b.x1,
29650
+ x2: b.y2,
29651
+ y2: b.x2
29652
+ };
29653
+ }
29654
+ /************************************************************
29655
+ * The control points of an elbow from the port `s` to the port
29656
+ * `t` ([x, y] each), knowing the boxes of the two cards
29657
+ * ({x1, y1, x2, y2}) and the edge's lane.
29658
+ *
29659
+ * vertical the rows are stacked (top to bottom); false
29660
+ * when they are side by side (left to right)
29661
+ ************************************************************/
29662
+ function elbow_points(s, t, box_s, box_t, lane, vertical) {
29663
+ if (!vertical) return elbow_points(swap(s), swap(t), swap_box(box_s), swap_box(box_t), lane, true).map(swap);
29664
+ let shift = lane * 10;
29665
+ if (t[1] - s[1] > 20) {
29666
+ let mid = (s[1] + t[1]) / 2 + shift;
29667
+ mid = Math.min(Math.max(mid, s[1] + 10), t[1] - 10);
29668
+ return [[s[0], mid], [t[0], mid]];
29669
+ }
29670
+ let out = 16 + Math.abs(shift);
29671
+ let side = lane < 0 ? Math.min(box_s.x1, box_t.x1) - 24 - Math.abs(shift) : Math.max(box_s.x2, box_t.x2) + 24 + Math.abs(shift);
29672
+ let y1 = s[1] + out;
29673
+ let y2 = t[1] - out;
29674
+ return [
29675
+ [s[0], y1],
29676
+ [side, y1],
29677
+ [side, y2],
29678
+ [t[0], y2]
29679
+ ];
29680
+ }
29633
29681
  //#endregion
29634
29682
  //#region node_modules/@babel/runtime/helpers/esm/typeof.js
29635
29683
  function _typeof(o) {
@@ -45644,7 +45692,7 @@ var _excluded$1 = ["style"];
45644
45692
  /**
45645
45693
  * Polyline inherits the marker-related capabilities of Polygon.
45646
45694
  */
45647
- var Polyline = /*#__PURE__*/ function(_Polygon) {
45695
+ var Polyline$1 = /*#__PURE__*/ function(_Polygon) {
45648
45696
  function Polyline() {
45649
45697
  var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, style = _ref.style, rest = _objectWithoutProperties(_ref, _excluded$1);
45650
45698
  _classCallCheck(this, Polyline);
@@ -45736,7 +45784,7 @@ var Polyline = /*#__PURE__*/ function(_Polygon) {
45736
45784
  }
45737
45785
  ]);
45738
45786
  }(Polygon);
45739
- Polyline.PARSED_STYLE_LIST = new Set([].concat(_toConsumableArray(Polygon.PARSED_STYLE_LIST), [
45787
+ Polyline$1.PARSED_STYLE_LIST = new Set([].concat(_toConsumableArray(Polygon.PARSED_STYLE_LIST), [
45740
45788
  "points",
45741
45789
  "markerStart",
45742
45790
  "markerMid",
@@ -56571,6 +56619,12 @@ var attrs_table$4 = [
56571
56619
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "main_topic", 0, "", "The topic the tree hangs from; empty = deduced (the one whose hooks reach the most others). Its parentless records are the roots; a parentless record of a topic linked to it is LOOSE and shown only on request"),
56572
56620
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "loose_topics", 0, "[]", "Topics whose loose records (no parent, in a topic the schema hangs from the main one) are shown as roots"),
56573
56621
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "node_mode", 0, "expanded", "How a record is drawn: `expanded` = the card with its pills and ports; `compact` = a one-line pill with the name and small ports; `shape` = a figure of the topic's colour (square, circle, diamond... per node or topic, from the node properties), no ports, no text -- the topology alone. One node can be toggled against it (EV_TOGGLE_NODE_MODE)"),
56622
+ (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "edge_shape", 0, "curved", "How an edge is drawn: `curved` (the default) or `elbow` -- straight out of its port to the channel between the two rows, along it, and straight into the other port: the bus of an org chart, as mxGraph drew its trees. Layouts with no rows (`rowless_layouts`) keep the curve"),
56623
+ (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "rowless_layouts", _yuneta_gobj_js.sdata_flag_t.SDF_RD, JSON.stringify([
56624
+ "radial",
56625
+ "d3-force",
56626
+ "force-atlas2"
56627
+ ]), "Layouts with no rows for an elbow to run between: their edges stay curved whatever `edge_shape` says (read-only, for the parent to query)"),
56574
56628
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "node_labels", 0, true, "A `shape` node says its name under the figure. Off, it is a coloured figure and nothing else"),
56575
56629
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "confirm_delete_node", 0, true, "Ask confirmation before deleting a node"),
56576
56630
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "confirm_unlink_edge", 0, true, "Ask confirmation before unlinking an edge"),
@@ -56822,6 +56876,8 @@ function register_layouts(gobj) {
56822
56876
  (0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "manual", ManualLayout);
56823
56877
  (0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-tree", TreedbTreeLayout);
56824
56878
  (0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-compact", TreedbCompactLayout);
56879
+ (0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-elbow-v", TreedbElbowV);
56880
+ (0, _antv_g6.register)(_antv_g6.ExtensionCategory.EDGE, "treedb-elbow-h", TreedbElbowH);
56825
56881
  (0, _antv_g6.register)(_antv_g6.ExtensionCategory.LAYOUT, "treedb-radial", TreedbRadialLayout);
56826
56882
  (0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "light", LightNode);
56827
56883
  (0, _antv_g6.register)(_antv_g6.ExtensionCategory.NODE, "treedb-card", TreedbCard);
@@ -57514,7 +57570,10 @@ function layout_direction(gobj) {
57514
57570
  return (0, _yuneta_gobj_js.str_in_list)(LR_LAYOUTS, gobj.priv.layout) ? "LR" : "TB";
57515
57571
  }
57516
57572
  function edge_type_for(gobj) {
57517
- return layout_direction(gobj) === "LR" ? "cubic-horizontal" : "cubic";
57573
+ let lr = layout_direction(gobj) === "LR";
57574
+ let rowless = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "rowless_layouts") || [];
57575
+ if ((0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "edge_shape") === "elbow" && !(0, _yuneta_gobj_js.str_in_list)(rowless, gobj.priv.layout)) return lr ? "treedb-elbow-h" : "treedb-elbow-v";
57576
+ return lr ? "cubic-horizontal" : "cubic";
57518
57577
  }
57519
57578
  /************************************************************
57520
57579
  * Where the ports sit, by direction: fkeys (the way in from a
@@ -58989,6 +59048,70 @@ var TreedbTreeLayout = class extends _antv_g6.BaseLayout {
58989
59048
  return treedb_layout_output(layout_tree(input.nodes, input.edges, options));
58990
59049
  }
58991
59050
  };
59051
+ /************************************************************
59052
+ * An ELBOW edge, the way mxGraph drew a tree: straight out of
59053
+ * the parent's port to the channel half way to the child, along
59054
+ * it, and straight into the child's port. The children of one
59055
+ * hook sit on one row and leave by one port, so they share the
59056
+ * channel and the lines read as one bus.
59057
+ *
59058
+ * Computed on every draw from where the two ends ARE, so a
59059
+ * dragged card, a fold or a layout needs nothing else. `-v` runs
59060
+ * between rows (top to bottom), `-h` between columns. An edge that
59061
+ * does not run forward goes round the two cards, and the edges
59062
+ * joining the same two cards take lanes (treedb_elbow.js).
59063
+ ************************************************************/
59064
+ var ELBOW_RADIUS = 6;
59065
+ function elbow_box(node) {
59066
+ try {
59067
+ let b = node.getShape("key").getBounds();
59068
+ return {
59069
+ x1: b.min[0],
59070
+ y1: b.min[1],
59071
+ x2: b.max[0],
59072
+ y2: b.max[1]
59073
+ };
59074
+ } catch (e) {
59075
+ (0, _yuneta_gobj_js.log_error)(`elbow edge: no bounds for node ${node && node.id}: ${e}`);
59076
+ let c = node.getCenter();
59077
+ return {
59078
+ x1: c[0],
59079
+ y1: c[1],
59080
+ x2: c[0],
59081
+ y2: c[1]
59082
+ };
59083
+ }
59084
+ }
59085
+ function elbow_lane_of(edge) {
59086
+ let graph = edge.context && edge.context.graph;
59087
+ let s = edge.sourceNode && edge.sourceNode.id;
59088
+ let t = edge.targetNode && edge.targetNode.id;
59089
+ if (!graph || s === void 0 || t === void 0 || s === t) return 0;
59090
+ try {
59091
+ return elbow_lane(graph.getRelatedEdgesData(s).filter((d) => d.source === s && d.target === t || d.source === t && d.target === s).map((d) => d.id), edge.id);
59092
+ } catch (e) {
59093
+ (0, _yuneta_gobj_js.log_error)(`elbow edge ${edge.id}: cannot read the edges of ${s}: ${e}`);
59094
+ return 0;
59095
+ }
59096
+ }
59097
+ var TreedbElbowV = class extends _antv_g6.Polyline {
59098
+ getControlPoints(attributes) {
59099
+ let [s, t] = this.getEndpoints(attributes, false);
59100
+ return elbow_points(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), true);
59101
+ }
59102
+ getKeyPath(attributes) {
59103
+ return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
59104
+ }
59105
+ };
59106
+ var TreedbElbowH = class extends _antv_g6.Polyline {
59107
+ getControlPoints(attributes) {
59108
+ let [s, t] = this.getEndpoints(attributes, false);
59109
+ return elbow_points(s, t, elbow_box(this.sourceNode), elbow_box(this.targetNode), elbow_lane_of(this), false);
59110
+ }
59111
+ getKeyPath(attributes) {
59112
+ return super.getKeyPath(Object.assign({}, attributes, { radius: attributes.radius || ELBOW_RADIUS }));
59113
+ }
59114
+ };
58992
59115
  var TreedbCompactLayout = class extends _antv_g6.BaseLayout {
58993
59116
  async execute(data, options) {
58994
59117
  let input = treedb_layout_input(data);
@@ -63432,6 +63555,20 @@ function ac_set_node_labels(gobj, event, kw, src) {
63432
63555
  return 0;
63433
63556
  }
63434
63557
  /************************************************************
63558
+ * Curved or elbow edges (the host's toggle). Nothing moves: every
63559
+ * edge takes the type that goes with the shape and the layout,
63560
+ * and draws again.
63561
+ ************************************************************/
63562
+ function ac_set_edge_shape(gobj, event, kw, src) {
63563
+ let priv = gobj.priv;
63564
+ let shape = kw && kw.edge_shape === "elbow" ? "elbow" : "curved";
63565
+ (0, _yuneta_gobj_js.gobj_write_str_attr)(gobj, "edge_shape", shape);
63566
+ if (!priv.graph || !priv.graph_rendered) return 0;
63567
+ apply_layout_direction(gobj);
63568
+ graph_draw(gobj);
63569
+ return 0;
63570
+ }
63571
+ /************************************************************
63435
63572
  * ONE node opened or closed against the mode (a double click,
63436
63573
  * or the context menu). It holds still on screen while the
63437
63574
  * rest of the graph makes room, as a fold does.
@@ -63991,6 +64128,11 @@ function create_gclass$4(gclass_name) {
63991
64128
  ac_set_node_labels,
63992
64129
  null
63993
64130
  ],
64131
+ [
64132
+ "EV_SET_EDGE_SHAPE",
64133
+ ac_set_edge_shape,
64134
+ null
64135
+ ],
63994
64136
  [
63995
64137
  "EV_TOGGLE_NODE_MODE",
63996
64138
  ac_toggle_node_mode,
@@ -64112,6 +64254,7 @@ function create_gclass$4(gclass_name) {
64112
64254
  ["EV_SET_LOOSE_TOPICS", 0],
64113
64255
  ["EV_SET_NODE_MODE", 0],
64114
64256
  ["EV_SET_NODE_LABELS", 0],
64257
+ ["EV_SET_EDGE_SHAPE", 0],
64115
64258
  ["EV_TOGGLE_NODE_MODE", 0],
64116
64259
  ["EV_NODE_DBLCLICK", 0],
64117
64260
  ["EV_LEGEND_STATE", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
@@ -64188,6 +64331,7 @@ var attrs_table$3 = [
64188
64331
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "main_topic", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "", "The topic the tree hangs from; empty = deduced by the graph. User preference, per treedb"),
64189
64332
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "loose_topics", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "[]", "Topics whose LOOSE records (no parent) are shown. User preference, per treedb"),
64190
64333
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "node_mode", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "expanded", "How the records are drawn: `expanded` = the cards with their pills and ports, `compact` = one-line pills with the name, `shape` = coloured figures, the topology alone. User preference"),
64334
+ (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "edge_shape", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "curved", "How the edges are drawn: `curved` or `elbow` (the bus of an org chart). User preference"),
64191
64335
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "node_labels", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, true, "A `shape` node says its name under its figure. User preference"),
64192
64336
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_DICT, "camera", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "{}", "Where the reader left the viewport: {zoom, x, y}. Handed to the engine on creation and written back when a move settles, so the graph opens where it was left. User preference, per treedb"),
64193
64337
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "fold_level", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, 0, "The level of the MAIN tree the toolbar's stepper stands on: 1 = the main topic's roots, N = N-1 levels under them; 0 = never stepped, `expand_depth`. Handed to the engine on creation, so the graph opens at the level it was left. User preference, per treedb"),
@@ -64280,6 +64424,7 @@ function mt_create$3(gobj) {
64280
64424
  loose_topics: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "loose_topics") || [],
64281
64425
  node_mode: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "node_mode") || "expanded",
64282
64426
  node_labels: (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "node_labels"),
64427
+ edge_shape: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "edge_shape") || "curved",
64283
64428
  camera: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "camera") || {}
64284
64429
  }, gobj);
64285
64430
  populate_nodes_tree_options(gobj);
@@ -64490,58 +64635,82 @@ function option_label(name) {
64490
64635
  * its context menu (the child's business).
64491
64636
  ************************************************************/
64492
64637
  function node_shape_items(gobj, wide) {
64493
- return [[
64494
- "div",
64495
- {
64496
- class: "GRAPH_NODE_MODE buttons has-addons",
64497
- style: "margin:0 0 0 .5rem; flex:0 0 auto; flex-wrap:nowrap;"
64498
- },
64499
- NODE_MODES.map((mode) => {
64500
- let key = NODE_MODE_LABELS[mode];
64501
- return [
64502
- "button",
64503
- {
64504
- class: "GRAPH_NODE_MODE_BTN button",
64505
- type: "button",
64506
- "data-mode": mode,
64507
- style: {
64508
- height: wide,
64509
- width: "2.5em"
64638
+ return [
64639
+ [
64640
+ "div",
64641
+ {
64642
+ class: "GRAPH_NODE_MODE buttons has-addons",
64643
+ style: "margin:0 0 0 .5rem; flex:0 0 auto; flex-wrap:nowrap;"
64644
+ },
64645
+ NODE_MODES.map((mode) => {
64646
+ let key = NODE_MODE_LABELS[mode];
64647
+ return [
64648
+ "button",
64649
+ {
64650
+ class: "GRAPH_NODE_MODE_BTN button",
64651
+ type: "button",
64652
+ "data-mode": mode,
64653
+ style: {
64654
+ height: wide,
64655
+ width: "2.5em"
64656
+ },
64657
+ title: (0, i18next.t)(key),
64658
+ "data-i18n-title": key,
64659
+ "aria-label": (0, i18next.t)(key),
64660
+ "data-i18n-aria-label": key,
64661
+ "aria-pressed": "false"
64510
64662
  },
64511
- title: (0, i18next.t)(key),
64512
- "data-i18n-title": key,
64513
- "aria-label": (0, i18next.t)(key),
64514
- "data-i18n-aria-label": key,
64515
- "aria-pressed": "false"
64663
+ yui_toolbar_icon(NODE_MODE_ICONS[mode]),
64664
+ { click: (evt) => {
64665
+ evt.stopPropagation();
64666
+ (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SET_NODE_MODE", { node_mode: mode }, gobj);
64667
+ } }
64668
+ ];
64669
+ })
64670
+ ],
64671
+ [
64672
+ "button",
64673
+ {
64674
+ class: "GRAPH_NODE_LABELS button",
64675
+ type: "button",
64676
+ style: {
64677
+ height: wide,
64678
+ width: "2.5em"
64516
64679
  },
64517
- yui_toolbar_icon(NODE_MODE_ICONS[mode]),
64518
- { click: (evt) => {
64519
- evt.stopPropagation();
64520
- (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SET_NODE_MODE", { node_mode: mode }, gobj);
64521
- } }
64522
- ];
64523
- })
64524
- ], [
64525
- "button",
64526
- {
64527
- class: "GRAPH_NODE_LABELS button",
64528
- type: "button",
64529
- style: {
64530
- height: wide,
64531
- width: "2.5em"
64680
+ title: (0, i18next.t)("node labels"),
64681
+ "data-i18n-title": "node labels",
64682
+ "aria-label": (0, i18next.t)("node labels"),
64683
+ "data-i18n-aria-label": "node labels",
64684
+ "aria-pressed": "false"
64532
64685
  },
64533
- title: (0, i18next.t)("node labels"),
64534
- "data-i18n-title": "node labels",
64535
- "aria-label": (0, i18next.t)("node labels"),
64536
- "data-i18n-aria-label": "node labels",
64537
- "aria-pressed": "false"
64538
- },
64539
- yui_toolbar_icon("yi-font"),
64540
- { click: (evt) => {
64541
- evt.stopPropagation();
64542
- (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_NODE_LABELS", {}, gobj);
64543
- } }
64544
- ]];
64686
+ yui_toolbar_icon("yi-font"),
64687
+ { click: (evt) => {
64688
+ evt.stopPropagation();
64689
+ (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_NODE_LABELS", {}, gobj);
64690
+ } }
64691
+ ],
64692
+ [
64693
+ "button",
64694
+ {
64695
+ class: "GRAPH_EDGE_ELBOW button",
64696
+ type: "button",
64697
+ style: {
64698
+ height: wide,
64699
+ width: "2.5em"
64700
+ },
64701
+ title: (0, i18next.t)("elbow edges"),
64702
+ "data-i18n-title": "elbow edges",
64703
+ "aria-label": (0, i18next.t)("elbow edges"),
64704
+ "data-i18n-aria-label": "elbow edges",
64705
+ "aria-pressed": "false"
64706
+ },
64707
+ yui_toolbar_icon("yi-diagram-project"),
64708
+ { click: (evt) => {
64709
+ evt.stopPropagation();
64710
+ (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_EDGE_SHAPE", {}, gobj);
64711
+ } }
64712
+ ]
64713
+ ];
64545
64714
  }
64546
64715
  var NODE_MODES = [
64547
64716
  "expanded",
@@ -64574,6 +64743,16 @@ function refresh_node_shape_buttons(gobj, $root) {
64574
64743
  $labels.setAttribute("aria-pressed", labels ? "true" : "false");
64575
64744
  $labels.disabled = mode !== "shape";
64576
64745
  }
64746
+ let elbow = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "edge_shape") === "elbow";
64747
+ set_pressed_state($root, ".GRAPH_EDGE_ELBOW", elbow);
64748
+ let $elbow = $root.querySelector(".GRAPH_EDGE_ELBOW");
64749
+ if ($elbow) {
64750
+ $elbow.setAttribute("aria-pressed", elbow ? "true" : "false");
64751
+ let child = gobj.priv.gobj_nodes_tree;
64752
+ let rowless = child ? (0, _yuneta_gobj_js.gobj_read_attr)(child, "rowless_layouts") || [] : [];
64753
+ let layout = child ? (0, _yuneta_gobj_js.gobj_read_str_attr)(child, "layout") : "";
64754
+ $elbow.disabled = rowless.includes(layout);
64755
+ }
64577
64756
  }
64578
64757
  /************************************************************
64579
64758
  * The fold STEPPER: one level less, where the tree stands, one
@@ -65122,6 +65301,7 @@ function populate_nodes_tree_options(gobj) {
65122
65301
  let current_layout = (0, _yuneta_gobj_js.gobj_read_str_attr)(priv.gobj_nodes_tree, "layout");
65123
65302
  if (current_layout) $layout_select.value = current_layout;
65124
65303
  refresh_layout_stepper(gobj);
65304
+ refresh_node_shape_buttons(gobj, $container);
65125
65305
  }
65126
65306
  let $operation_mode_select = $container.querySelector(".GRAPH_MODE_SELECT");
65127
65307
  $operation_mode_select.value = priv.operation_mode;
@@ -65815,6 +65995,7 @@ function ac_set_layout(gobj, event, kw, src) {
65815
65995
  $layout_select.value = priv.layout;
65816
65996
  (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_SET_LAYOUT", { layout }, gobj);
65817
65997
  refresh_layout_stepper(gobj);
65998
+ refresh_node_shape_buttons(gobj, priv.$container);
65818
65999
  return 0;
65819
66000
  }
65820
66001
  /************************************************************
@@ -66166,6 +66347,7 @@ function ac_layout_autoset(gobj, event, kw, src) {
66166
66347
  if (!$select || !layout) return 0;
66167
66348
  $select.value = layout;
66168
66349
  refresh_layout_stepper(gobj);
66350
+ refresh_node_shape_buttons(gobj, $container);
66169
66351
  return 0;
66170
66352
  }
66171
66353
  /************************************************************
@@ -66238,6 +66420,15 @@ function ac_set_node_mode(gobj, event, kw, src) {
66238
66420
  if (priv.gobj_nodes_tree) (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_SET_NODE_MODE", { node_mode: mode }, gobj);
66239
66421
  return 0;
66240
66422
  }
66423
+ function ac_toggle_edge_shape(gobj, event, kw, src) {
66424
+ let priv = gobj.priv;
66425
+ let shape = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "edge_shape") === "elbow" ? "curved" : "elbow";
66426
+ (0, _yuneta_gobj_js.gobj_write_str_attr)(gobj, "edge_shape", shape);
66427
+ (0, _yuneta_gobj_js.gobj_save_persistent_attrs)(gobj, "edge_shape");
66428
+ refresh_node_shape_buttons(gobj, priv.$container);
66429
+ if (priv.gobj_nodes_tree) (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_SET_EDGE_SHAPE", { edge_shape: shape }, gobj);
66430
+ return 0;
66431
+ }
66241
66432
  function ac_toggle_node_labels(gobj, event, kw, src) {
66242
66433
  let priv = gobj.priv;
66243
66434
  let labels = !(0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "node_labels");
@@ -66482,6 +66673,11 @@ function create_gclass$3(gclass_name) {
66482
66673
  ac_toggle_node_labels,
66483
66674
  null
66484
66675
  ],
66676
+ [
66677
+ "EV_TOGGLE_EDGE_SHAPE",
66678
+ ac_toggle_edge_shape,
66679
+ null
66680
+ ],
66485
66681
  [
66486
66682
  "EV_LAYOUT_AUTOSET",
66487
66683
  ac_layout_autoset,
@@ -66559,6 +66755,7 @@ function create_gclass$3(gclass_name) {
66559
66755
  ["EV_COLLAPSE_LEVEL", 0],
66560
66756
  ["EV_SET_NODE_MODE", 0],
66561
66757
  ["EV_TOGGLE_NODE_LABELS", 0],
66758
+ ["EV_TOGGLE_EDGE_SHAPE", 0],
66562
66759
  ["EV_FIND_RESULT", 0],
66563
66760
  ["EV_LAYOUT_AUTOSET", 0],
66564
66761
  ["EV_CAMERA_CHANGED", 0],