@yuneta/gobj-ui 7.23.10 → 7.23.11
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 +14 -5
- package/dist/gobj-ui.cjs.js +89 -5
- package/dist/gobj-ui.es.js +89 -5
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +113 -6
- package/src/lib_icons.js +13 -0
package/README.md
CHANGED
|
@@ -877,11 +877,19 @@ a card with a border sitting on the graph). Above that width nothing changes.
|
|
|
877
877
|
|
|
878
878
|
**New keys for consumers: `show toolbar`, `hide toolbar`.**
|
|
879
879
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
880
|
+
**Multi-selection reaches a finger through a MODE, not through a gesture**
|
|
881
|
+
(`7.23.11`). Both halves of it — shift+click to add a card, shift+drag for the
|
|
882
|
+
rubber band — hang off a key a phone does not have, and there is no spare
|
|
883
|
+
gesture to give them: G6 binds panning and the band to the same plain drag, so
|
|
884
|
+
one of the two has to stand aside. The edit toolbar carries a **selection
|
|
885
|
+
mode** toggle (the dashed marquee, next to `+`): while it is on, a tap picks a
|
|
886
|
+
card and a drag on the background draws the band, and panning is what stands
|
|
887
|
+
aside. It is deliberately a button and not a heuristic — the toolbar says which
|
|
888
|
+
of the two the graph is listening for, and turning it off gives the camera
|
|
889
|
+
back. It is not device-specific: the same button spares a desktop reader the
|
|
890
|
+
key. Leaving edition turns it off, and it is not persisted.
|
|
891
|
+
|
|
892
|
+
**New key for consumers: `selection mode`.**
|
|
885
893
|
|
|
886
894
|
### Tabs opened at runtime, and the two decisions their url costs
|
|
887
895
|
|
|
@@ -928,6 +936,7 @@ clicked":
|
|
|
928
936
|
| click a node | selects it **and opens it**: resize handles, ports, popovers |
|
|
929
937
|
| **shift + click** | adds that node to the selection, or takes it out |
|
|
930
938
|
| **shift + drag on the canvas** | rubber band: the selection becomes what it enclosed |
|
|
939
|
+
| the **selection mode** button | makes those two the PLAIN gestures — a tap picks, a canvas drag is the band — for as long as it is on (panning stands aside meanwhile) |
|
|
931
940
|
| **ctrl/cmd + A** | every node |
|
|
932
941
|
| the **fit-to-selection** button | puts the viewport on what is selected |
|
|
933
942
|
| drag any selected node | **moves the whole selection**, as one undo |
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -47493,6 +47493,19 @@ var ICONS = `<svg xmlns="http://www.w3.org/2000/svg">
|
|
|
47493
47493
|
<symbol id="g6-icon-toolbar-hide" viewBox="0 0 384 512">
|
|
47494
47494
|
<path fill="currentColor" d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/>
|
|
47495
47495
|
</symbol>
|
|
47496
|
+
<!-- dashed marquee (selection mode).
|
|
47497
|
+
The band ITSELF, because that is what the button turns on: a
|
|
47498
|
+
drag on the canvas draws one and a tap picks a card. Not the
|
|
47499
|
+
fit-to-selection glyph next to it in the other toolbar -- that
|
|
47500
|
+
one is solid brackets around a solid object and means "put the
|
|
47501
|
+
camera on what is picked", which is the opposite end of the
|
|
47502
|
+
gesture. Dashes: 16 segments of 59 with gaps of 36 over a
|
|
47503
|
+
perimeter of 1520, so they land on the corners. -->
|
|
47504
|
+
<symbol id="g6-icon-select-mode" viewBox="0 0 512 512">
|
|
47505
|
+
<rect x="46" y="86" width="420" height="340" fill="none"
|
|
47506
|
+
stroke="currentColor" stroke-width="40"
|
|
47507
|
+
stroke-dasharray="59 36"/>
|
|
47508
|
+
</symbol>
|
|
47496
47509
|
<!-- floppy-disk (save) -->
|
|
47497
47510
|
<symbol id="g6-icon-save" viewBox="0 0 448 512">
|
|
47498
47511
|
<path fill="currentColor" d="M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-242.7c0-17-6.7-33.3-18.7-45.3L352 50.7C340 38.7 323.7 32 306.7 32L64 32zm32 96c0-17.7 14.3-32 32-32l160 0c17.7 0 32 14.3 32 32l0 64c0 17.7-14.3 32-32 32l-160 0c-17.7 0-32-14.3-32-32l0-64zM224 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"/>
|
|
@@ -47742,6 +47755,7 @@ var PRIVATE_DATA$4 = {
|
|
|
47742
47755
|
toolbar_collapsed: true,
|
|
47743
47756
|
_toolbars_could_collapse: null,
|
|
47744
47757
|
_on_focusout_restore: null,
|
|
47758
|
+
selection_mode: false,
|
|
47745
47759
|
_selected_paint_ids: [],
|
|
47746
47760
|
_pending_focus_topic: null,
|
|
47747
47761
|
_pending_find: null,
|
|
@@ -48065,6 +48079,7 @@ function update_toolbar(gobj) {
|
|
|
48065
48079
|
configure_toolbar_edit(gobj);
|
|
48066
48080
|
if (graph_get_plugin(gobj, "toolbar-edit")) graph.updatePlugin({ key: "toolbar-edit" });
|
|
48067
48081
|
update_zoom_selection_button(gobj);
|
|
48082
|
+
update_selection_mode_button(gobj);
|
|
48068
48083
|
}
|
|
48069
48084
|
/************************************************************
|
|
48070
48085
|
* The floating toolbars follow the theme.
|
|
@@ -48279,7 +48294,8 @@ function configure_toolbar(gobj) {
|
|
|
48279
48294
|
* Contains edit-mode buttons: Undo, Redo, Save
|
|
48280
48295
|
************************************************************/
|
|
48281
48296
|
function configure_toolbar_edit(gobj) {
|
|
48282
|
-
|
|
48297
|
+
let priv = gobj.priv;
|
|
48298
|
+
if (!priv.edit_mode || toolbars_collapsed(gobj)) {
|
|
48283
48299
|
graph_remove_plugin(gobj, "toolbar-edit");
|
|
48284
48300
|
return;
|
|
48285
48301
|
}
|
|
@@ -48298,6 +48314,12 @@ function configure_toolbar_edit(gobj) {
|
|
|
48298
48314
|
className: "EV_CREATE_NODE_BTN color_create_state",
|
|
48299
48315
|
title: (0, i18next.t)("create node")
|
|
48300
48316
|
},
|
|
48317
|
+
{
|
|
48318
|
+
id: "g6-icon-select-mode",
|
|
48319
|
+
value: "selection-mode",
|
|
48320
|
+
className: "EV_TOGGLE_SELECTION_MODE" + (priv.selection_mode ? " color_active_state" : ""),
|
|
48321
|
+
title: (0, i18next.t)("selection mode")
|
|
48322
|
+
},
|
|
48301
48323
|
{
|
|
48302
48324
|
id: "g6-icon-save",
|
|
48303
48325
|
value: "save",
|
|
@@ -48326,6 +48348,9 @@ function configure_toolbar_edit(gobj) {
|
|
|
48326
48348
|
case "create-node":
|
|
48327
48349
|
toggle_create_popover(gobj);
|
|
48328
48350
|
break;
|
|
48351
|
+
case "selection-mode":
|
|
48352
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_SELECTION_MODE", {}, gobj);
|
|
48353
|
+
break;
|
|
48329
48354
|
case "undo":
|
|
48330
48355
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_HISTORY_UNDO", {}, gobj);
|
|
48331
48356
|
break;
|
|
@@ -48369,7 +48394,7 @@ function configure_behaviour(gobj) {
|
|
|
48369
48394
|
type: "drag-canvas",
|
|
48370
48395
|
key: "drag-canvas",
|
|
48371
48396
|
enable: (event) => {
|
|
48372
|
-
if (event.shiftKey) return false;
|
|
48397
|
+
if (event.shiftKey || priv.selection_mode) return false;
|
|
48373
48398
|
if ("targetType" in event) return event.targetType === "canvas";
|
|
48374
48399
|
return true;
|
|
48375
48400
|
}
|
|
@@ -48379,7 +48404,8 @@ function configure_behaviour(gobj) {
|
|
|
48379
48404
|
{
|
|
48380
48405
|
type: BRUSH_SELECT_OWNED,
|
|
48381
48406
|
key: "brush-select",
|
|
48382
|
-
trigger: ["shift"],
|
|
48407
|
+
trigger: priv.selection_mode ? [] : ["shift"],
|
|
48408
|
+
enable: (event) => event.targetType === "canvas",
|
|
48383
48409
|
enableElements: ["node"],
|
|
48384
48410
|
immediately: false,
|
|
48385
48411
|
onSelect: (states) => {
|
|
@@ -48395,7 +48421,10 @@ function configure_behaviour(gobj) {
|
|
|
48395
48421
|
break;
|
|
48396
48422
|
default: (0, _yuneta_gobj_js.log_error)(`operation mode unknown: ${operation_mode}`);
|
|
48397
48423
|
}
|
|
48398
|
-
if (!priv.edit_mode)
|
|
48424
|
+
if (!priv.edit_mode) {
|
|
48425
|
+
priv.selection_mode = false;
|
|
48426
|
+
deselect_node(gobj);
|
|
48427
|
+
}
|
|
48399
48428
|
graph_write_behaviors(gobj, behaviors);
|
|
48400
48429
|
}
|
|
48401
48430
|
/************************************************************
|
|
@@ -49721,6 +49750,21 @@ function update_zoom_selection_button(gobj) {
|
|
|
49721
49750
|
else disableElements($container, ".EV_ZOOM_SELECTION");
|
|
49722
49751
|
}
|
|
49723
49752
|
/************************************************************
|
|
49753
|
+
* The selection mode is a state, so it has to LOOK like one.
|
|
49754
|
+
*
|
|
49755
|
+
* Toggled on the element rather than re-rendered with the
|
|
49756
|
+
* toolbar, for the same reason as the button above: a
|
|
49757
|
+
* re-render rebuilds the innerHTML and drops what every OTHER
|
|
49758
|
+
* button was told.
|
|
49759
|
+
************************************************************/
|
|
49760
|
+
function update_selection_mode_button(gobj) {
|
|
49761
|
+
let priv = gobj.priv;
|
|
49762
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
49763
|
+
if (!$container) return;
|
|
49764
|
+
if (!$container.querySelector(".EV_TOGGLE_SELECTION_MODE")) return;
|
|
49765
|
+
set_active_state($container, ".EV_TOGGLE_SELECTION_MODE", priv.selection_mode);
|
|
49766
|
+
}
|
|
49767
|
+
/************************************************************
|
|
49724
49768
|
* Select a SET of nodes: what a marquee and a shift-click do.
|
|
49725
49769
|
*
|
|
49726
49770
|
* It leaves `_selected_node_id` null even for a set of one,
|
|
@@ -52323,6 +52367,40 @@ function ac_set_operation_mode$1(gobj, event, kw, src) {
|
|
|
52323
52367
|
return 0;
|
|
52324
52368
|
}
|
|
52325
52369
|
/************************************************************
|
|
52370
|
+
* Selection mode on/off, from the edit toolbar.
|
|
52371
|
+
*
|
|
52372
|
+
* Shift is what the selection is built on, and a telephone has
|
|
52373
|
+
* no Shift: the marquee and the add-to-selection click were a
|
|
52374
|
+
* desktop feature by construction. This makes that key a MODE
|
|
52375
|
+
* -- while it is on, a tap picks a card and a drag on the
|
|
52376
|
+
* background draws the band, so the same two gestures are
|
|
52377
|
+
* reachable with one finger.
|
|
52378
|
+
*
|
|
52379
|
+
* It costs panning while it is on, and deliberately: G6 binds
|
|
52380
|
+
* both to a plain drag, and a gesture cannot be two things.
|
|
52381
|
+
* That is why it is a button and not a heuristic -- the reader
|
|
52382
|
+
* turns it off to move the camera, and the toolbar says which
|
|
52383
|
+
* of the two the graph is listening for.
|
|
52384
|
+
************************************************************/
|
|
52385
|
+
function ac_toggle_selection_mode(gobj, event, kw, src) {
|
|
52386
|
+
let priv = gobj.priv;
|
|
52387
|
+
if (!priv.edit_mode) {
|
|
52388
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: selection mode asked outside edition`);
|
|
52389
|
+
return 0;
|
|
52390
|
+
}
|
|
52391
|
+
priv.selection_mode = !priv.selection_mode;
|
|
52392
|
+
if (priv.selection_mode) {
|
|
52393
|
+
deselect_port(gobj);
|
|
52394
|
+
hide_node_icon(gobj);
|
|
52395
|
+
hide_node_popover(gobj);
|
|
52396
|
+
hide_resize_handles(gobj);
|
|
52397
|
+
priv._selected_node_id = null;
|
|
52398
|
+
}
|
|
52399
|
+
configure_behaviour(gobj);
|
|
52400
|
+
update_selection_mode_button(gobj);
|
|
52401
|
+
return 0;
|
|
52402
|
+
}
|
|
52403
|
+
/************************************************************
|
|
52326
52404
|
* Node drag end
|
|
52327
52405
|
************************************************************/
|
|
52328
52406
|
function ac_node_drag_end(gobj, event, kw, src) {
|
|
@@ -52387,7 +52465,7 @@ function ac_node_click$2(gobj, event, kw, src) {
|
|
|
52387
52465
|
topic_name: nodedata.data.desc.topic_name,
|
|
52388
52466
|
record: nodedata.data.record
|
|
52389
52467
|
});
|
|
52390
|
-
if (priv.edit_mode && kw.evt.shiftKey) toggle_in_selection(gobj, node_id);
|
|
52468
|
+
if (priv.edit_mode && (kw.evt.shiftKey || priv.selection_mode)) toggle_in_selection(gobj, node_id);
|
|
52391
52469
|
else if (priv.edit_mode) {
|
|
52392
52470
|
let containerRect = priv.$container.getBoundingClientRect();
|
|
52393
52471
|
let canvasPoint = graph.getCanvasByViewport([kw.evt.client.x - containerRect.left, kw.evt.client.y - containerRect.top]);
|
|
@@ -52685,6 +52763,11 @@ function create_gclass$4(gclass_name) {
|
|
|
52685
52763
|
ac_set_operation_mode$1,
|
|
52686
52764
|
null
|
|
52687
52765
|
],
|
|
52766
|
+
[
|
|
52767
|
+
"EV_TOGGLE_SELECTION_MODE",
|
|
52768
|
+
ac_toggle_selection_mode,
|
|
52769
|
+
null
|
|
52770
|
+
],
|
|
52688
52771
|
[
|
|
52689
52772
|
"EV_SAVE_GRAPH",
|
|
52690
52773
|
ac_save_graph,
|
|
@@ -52759,6 +52842,7 @@ function create_gclass$4(gclass_name) {
|
|
|
52759
52842
|
["EV_FULLSCREEN", 0],
|
|
52760
52843
|
["EV_SET_LAYOUT", 0],
|
|
52761
52844
|
["EV_SET_OPERATION_MODE", 0],
|
|
52845
|
+
["EV_TOGGLE_SELECTION_MODE", 0],
|
|
52762
52846
|
["EV_HISTORY_UNDO", 0],
|
|
52763
52847
|
["EV_HISTORY_REDO", 0],
|
|
52764
52848
|
["EV_SAVE_GRAPH", 0],
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -47480,6 +47480,19 @@ var ICONS = `<svg xmlns="http://www.w3.org/2000/svg">
|
|
|
47480
47480
|
<symbol id="g6-icon-toolbar-hide" viewBox="0 0 384 512">
|
|
47481
47481
|
<path fill="currentColor" d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/>
|
|
47482
47482
|
</symbol>
|
|
47483
|
+
<!-- dashed marquee (selection mode).
|
|
47484
|
+
The band ITSELF, because that is what the button turns on: a
|
|
47485
|
+
drag on the canvas draws one and a tap picks a card. Not the
|
|
47486
|
+
fit-to-selection glyph next to it in the other toolbar -- that
|
|
47487
|
+
one is solid brackets around a solid object and means "put the
|
|
47488
|
+
camera on what is picked", which is the opposite end of the
|
|
47489
|
+
gesture. Dashes: 16 segments of 59 with gaps of 36 over a
|
|
47490
|
+
perimeter of 1520, so they land on the corners. -->
|
|
47491
|
+
<symbol id="g6-icon-select-mode" viewBox="0 0 512 512">
|
|
47492
|
+
<rect x="46" y="86" width="420" height="340" fill="none"
|
|
47493
|
+
stroke="currentColor" stroke-width="40"
|
|
47494
|
+
stroke-dasharray="59 36"/>
|
|
47495
|
+
</symbol>
|
|
47483
47496
|
<!-- floppy-disk (save) -->
|
|
47484
47497
|
<symbol id="g6-icon-save" viewBox="0 0 448 512">
|
|
47485
47498
|
<path fill="currentColor" d="M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-242.7c0-17-6.7-33.3-18.7-45.3L352 50.7C340 38.7 323.7 32 306.7 32L64 32zm32 96c0-17.7 14.3-32 32-32l160 0c17.7 0 32 14.3 32 32l0 64c0 17.7-14.3 32-32 32l-160 0c-17.7 0-32-14.3-32-32l0-64zM224 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"/>
|
|
@@ -47729,6 +47742,7 @@ var PRIVATE_DATA$4 = {
|
|
|
47729
47742
|
toolbar_collapsed: true,
|
|
47730
47743
|
_toolbars_could_collapse: null,
|
|
47731
47744
|
_on_focusout_restore: null,
|
|
47745
|
+
selection_mode: false,
|
|
47732
47746
|
_selected_paint_ids: [],
|
|
47733
47747
|
_pending_focus_topic: null,
|
|
47734
47748
|
_pending_find: null,
|
|
@@ -48052,6 +48066,7 @@ function update_toolbar(gobj) {
|
|
|
48052
48066
|
configure_toolbar_edit(gobj);
|
|
48053
48067
|
if (graph_get_plugin(gobj, "toolbar-edit")) graph.updatePlugin({ key: "toolbar-edit" });
|
|
48054
48068
|
update_zoom_selection_button(gobj);
|
|
48069
|
+
update_selection_mode_button(gobj);
|
|
48055
48070
|
}
|
|
48056
48071
|
/************************************************************
|
|
48057
48072
|
* The floating toolbars follow the theme.
|
|
@@ -48266,7 +48281,8 @@ function configure_toolbar(gobj) {
|
|
|
48266
48281
|
* Contains edit-mode buttons: Undo, Redo, Save
|
|
48267
48282
|
************************************************************/
|
|
48268
48283
|
function configure_toolbar_edit(gobj) {
|
|
48269
|
-
|
|
48284
|
+
let priv = gobj.priv;
|
|
48285
|
+
if (!priv.edit_mode || toolbars_collapsed(gobj)) {
|
|
48270
48286
|
graph_remove_plugin(gobj, "toolbar-edit");
|
|
48271
48287
|
return;
|
|
48272
48288
|
}
|
|
@@ -48285,6 +48301,12 @@ function configure_toolbar_edit(gobj) {
|
|
|
48285
48301
|
className: "EV_CREATE_NODE_BTN color_create_state",
|
|
48286
48302
|
title: t("create node")
|
|
48287
48303
|
},
|
|
48304
|
+
{
|
|
48305
|
+
id: "g6-icon-select-mode",
|
|
48306
|
+
value: "selection-mode",
|
|
48307
|
+
className: "EV_TOGGLE_SELECTION_MODE" + (priv.selection_mode ? " color_active_state" : ""),
|
|
48308
|
+
title: t("selection mode")
|
|
48309
|
+
},
|
|
48288
48310
|
{
|
|
48289
48311
|
id: "g6-icon-save",
|
|
48290
48312
|
value: "save",
|
|
@@ -48313,6 +48335,9 @@ function configure_toolbar_edit(gobj) {
|
|
|
48313
48335
|
case "create-node":
|
|
48314
48336
|
toggle_create_popover(gobj);
|
|
48315
48337
|
break;
|
|
48338
|
+
case "selection-mode":
|
|
48339
|
+
gobj_send_event(gobj, "EV_TOGGLE_SELECTION_MODE", {}, gobj);
|
|
48340
|
+
break;
|
|
48316
48341
|
case "undo":
|
|
48317
48342
|
gobj_send_event(gobj, "EV_HISTORY_UNDO", {}, gobj);
|
|
48318
48343
|
break;
|
|
@@ -48356,7 +48381,7 @@ function configure_behaviour(gobj) {
|
|
|
48356
48381
|
type: "drag-canvas",
|
|
48357
48382
|
key: "drag-canvas",
|
|
48358
48383
|
enable: (event) => {
|
|
48359
|
-
if (event.shiftKey) return false;
|
|
48384
|
+
if (event.shiftKey || priv.selection_mode) return false;
|
|
48360
48385
|
if ("targetType" in event) return event.targetType === "canvas";
|
|
48361
48386
|
return true;
|
|
48362
48387
|
}
|
|
@@ -48366,7 +48391,8 @@ function configure_behaviour(gobj) {
|
|
|
48366
48391
|
{
|
|
48367
48392
|
type: BRUSH_SELECT_OWNED,
|
|
48368
48393
|
key: "brush-select",
|
|
48369
|
-
trigger: ["shift"],
|
|
48394
|
+
trigger: priv.selection_mode ? [] : ["shift"],
|
|
48395
|
+
enable: (event) => event.targetType === "canvas",
|
|
48370
48396
|
enableElements: ["node"],
|
|
48371
48397
|
immediately: false,
|
|
48372
48398
|
onSelect: (states) => {
|
|
@@ -48382,7 +48408,10 @@ function configure_behaviour(gobj) {
|
|
|
48382
48408
|
break;
|
|
48383
48409
|
default: log_error(`operation mode unknown: ${operation_mode}`);
|
|
48384
48410
|
}
|
|
48385
|
-
if (!priv.edit_mode)
|
|
48411
|
+
if (!priv.edit_mode) {
|
|
48412
|
+
priv.selection_mode = false;
|
|
48413
|
+
deselect_node(gobj);
|
|
48414
|
+
}
|
|
48386
48415
|
graph_write_behaviors(gobj, behaviors);
|
|
48387
48416
|
}
|
|
48388
48417
|
/************************************************************
|
|
@@ -49708,6 +49737,21 @@ function update_zoom_selection_button(gobj) {
|
|
|
49708
49737
|
else disableElements($container, ".EV_ZOOM_SELECTION");
|
|
49709
49738
|
}
|
|
49710
49739
|
/************************************************************
|
|
49740
|
+
* The selection mode is a state, so it has to LOOK like one.
|
|
49741
|
+
*
|
|
49742
|
+
* Toggled on the element rather than re-rendered with the
|
|
49743
|
+
* toolbar, for the same reason as the button above: a
|
|
49744
|
+
* re-render rebuilds the innerHTML and drops what every OTHER
|
|
49745
|
+
* button was told.
|
|
49746
|
+
************************************************************/
|
|
49747
|
+
function update_selection_mode_button(gobj) {
|
|
49748
|
+
let priv = gobj.priv;
|
|
49749
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
49750
|
+
if (!$container) return;
|
|
49751
|
+
if (!$container.querySelector(".EV_TOGGLE_SELECTION_MODE")) return;
|
|
49752
|
+
set_active_state($container, ".EV_TOGGLE_SELECTION_MODE", priv.selection_mode);
|
|
49753
|
+
}
|
|
49754
|
+
/************************************************************
|
|
49711
49755
|
* Select a SET of nodes: what a marquee and a shift-click do.
|
|
49712
49756
|
*
|
|
49713
49757
|
* It leaves `_selected_node_id` null even for a set of one,
|
|
@@ -52310,6 +52354,40 @@ function ac_set_operation_mode$1(gobj, event, kw, src) {
|
|
|
52310
52354
|
return 0;
|
|
52311
52355
|
}
|
|
52312
52356
|
/************************************************************
|
|
52357
|
+
* Selection mode on/off, from the edit toolbar.
|
|
52358
|
+
*
|
|
52359
|
+
* Shift is what the selection is built on, and a telephone has
|
|
52360
|
+
* no Shift: the marquee and the add-to-selection click were a
|
|
52361
|
+
* desktop feature by construction. This makes that key a MODE
|
|
52362
|
+
* -- while it is on, a tap picks a card and a drag on the
|
|
52363
|
+
* background draws the band, so the same two gestures are
|
|
52364
|
+
* reachable with one finger.
|
|
52365
|
+
*
|
|
52366
|
+
* It costs panning while it is on, and deliberately: G6 binds
|
|
52367
|
+
* both to a plain drag, and a gesture cannot be two things.
|
|
52368
|
+
* That is why it is a button and not a heuristic -- the reader
|
|
52369
|
+
* turns it off to move the camera, and the toolbar says which
|
|
52370
|
+
* of the two the graph is listening for.
|
|
52371
|
+
************************************************************/
|
|
52372
|
+
function ac_toggle_selection_mode(gobj, event, kw, src) {
|
|
52373
|
+
let priv = gobj.priv;
|
|
52374
|
+
if (!priv.edit_mode) {
|
|
52375
|
+
log_error(`${gobj_short_name(gobj)}: selection mode asked outside edition`);
|
|
52376
|
+
return 0;
|
|
52377
|
+
}
|
|
52378
|
+
priv.selection_mode = !priv.selection_mode;
|
|
52379
|
+
if (priv.selection_mode) {
|
|
52380
|
+
deselect_port(gobj);
|
|
52381
|
+
hide_node_icon(gobj);
|
|
52382
|
+
hide_node_popover(gobj);
|
|
52383
|
+
hide_resize_handles(gobj);
|
|
52384
|
+
priv._selected_node_id = null;
|
|
52385
|
+
}
|
|
52386
|
+
configure_behaviour(gobj);
|
|
52387
|
+
update_selection_mode_button(gobj);
|
|
52388
|
+
return 0;
|
|
52389
|
+
}
|
|
52390
|
+
/************************************************************
|
|
52313
52391
|
* Node drag end
|
|
52314
52392
|
************************************************************/
|
|
52315
52393
|
function ac_node_drag_end(gobj, event, kw, src) {
|
|
@@ -52374,7 +52452,7 @@ function ac_node_click$2(gobj, event, kw, src) {
|
|
|
52374
52452
|
topic_name: nodedata.data.desc.topic_name,
|
|
52375
52453
|
record: nodedata.data.record
|
|
52376
52454
|
});
|
|
52377
|
-
if (priv.edit_mode && kw.evt.shiftKey) toggle_in_selection(gobj, node_id);
|
|
52455
|
+
if (priv.edit_mode && (kw.evt.shiftKey || priv.selection_mode)) toggle_in_selection(gobj, node_id);
|
|
52378
52456
|
else if (priv.edit_mode) {
|
|
52379
52457
|
let containerRect = priv.$container.getBoundingClientRect();
|
|
52380
52458
|
let canvasPoint = graph.getCanvasByViewport([kw.evt.client.x - containerRect.left, kw.evt.client.y - containerRect.top]);
|
|
@@ -52672,6 +52750,11 @@ function create_gclass$4(gclass_name) {
|
|
|
52672
52750
|
ac_set_operation_mode$1,
|
|
52673
52751
|
null
|
|
52674
52752
|
],
|
|
52753
|
+
[
|
|
52754
|
+
"EV_TOGGLE_SELECTION_MODE",
|
|
52755
|
+
ac_toggle_selection_mode,
|
|
52756
|
+
null
|
|
52757
|
+
],
|
|
52675
52758
|
[
|
|
52676
52759
|
"EV_SAVE_GRAPH",
|
|
52677
52760
|
ac_save_graph,
|
|
@@ -52746,6 +52829,7 @@ function create_gclass$4(gclass_name) {
|
|
|
52746
52829
|
["EV_FULLSCREEN", 0],
|
|
52747
52830
|
["EV_SET_LAYOUT", 0],
|
|
52748
52831
|
["EV_SET_OPERATION_MODE", 0],
|
|
52832
|
+
["EV_TOGGLE_SELECTION_MODE", 0],
|
|
52749
52833
|
["EV_HISTORY_UNDO", 0],
|
|
52750
52834
|
["EV_HISTORY_REDO", 0],
|
|
52751
52835
|
["EV_SAVE_GRAPH", 0],
|
package/package.json
CHANGED
package/src/c_g6_nodes_tree.js
CHANGED
|
@@ -350,6 +350,9 @@ let PRIVATE_DATA = {
|
|
|
350
350
|
toolbar_collapsed: true, // floating toolbars folded (narrow only)
|
|
351
351
|
_toolbars_could_collapse: null, // last answer, to notice it changed
|
|
352
352
|
_on_focusout_restore: null, // ...and putting it back when it goes nowhere
|
|
353
|
+
selection_mode: false, // taps pick cards, a canvas drag is the band
|
|
354
|
+
// (edition only, transient: a mode nobody
|
|
355
|
+
// can see is a mode nobody can leave)
|
|
353
356
|
_selected_paint_ids: [], // node ids whose card is PAINTED selected
|
|
354
357
|
// (G6's 'selected' state is the selection
|
|
355
358
|
// itself; this is what is on screen, and
|
|
@@ -1026,6 +1029,7 @@ function update_toolbar(gobj)
|
|
|
1026
1029
|
/* A re-render rebuilds the innerHTML, so a button whose enabled
|
|
1027
1030
|
* state is not part of getItems() has to be told again. */
|
|
1028
1031
|
update_zoom_selection_button(gobj);
|
|
1032
|
+
update_selection_mode_button(gobj);
|
|
1029
1033
|
}
|
|
1030
1034
|
|
|
1031
1035
|
/************************************************************
|
|
@@ -1326,6 +1330,19 @@ function configure_toolbar_edit(gobj)
|
|
|
1326
1330
|
getItems: () => {
|
|
1327
1331
|
return [
|
|
1328
1332
|
{ id: 'g6-icon-plus', value: 'create-node', className: 'EV_CREATE_NODE_BTN color_create_state', title: t('create node') },
|
|
1333
|
+
/* The mode is carried in the class getItems()
|
|
1334
|
+
* returns, not only pushed onto the element after
|
|
1335
|
+
* the fact: this toolbar is rebuilt whole (a fold,
|
|
1336
|
+
* a language change), and the rebuilt DOM is not
|
|
1337
|
+
* there yet when the rebuild returns -- so a
|
|
1338
|
+
* button told afterwards came back OFF while the
|
|
1339
|
+
* graph was still listening for a selection. */
|
|
1340
|
+
{
|
|
1341
|
+
id: 'g6-icon-select-mode', value: 'selection-mode',
|
|
1342
|
+
className: 'EV_TOGGLE_SELECTION_MODE' +
|
|
1343
|
+
(priv.selection_mode? ' color_active_state' : ''),
|
|
1344
|
+
title: t('selection mode')
|
|
1345
|
+
},
|
|
1329
1346
|
{ id: 'g6-icon-save', value: 'save', className: 'EV_SAVE_GRAPH', title: t('save'), disabled: true },
|
|
1330
1347
|
{ id: 'g6-icon-undo', value: 'undo', className: 'EV_HISTORY_UNDO', title: t('undo'), disabled: true },
|
|
1331
1348
|
{ id: 'g6-icon-redo', value: 'redo', className: 'EV_HISTORY_REDO', title: t('redo'), disabled: true },
|
|
@@ -1336,6 +1353,9 @@ function configure_toolbar_edit(gobj)
|
|
|
1336
1353
|
case 'create-node':
|
|
1337
1354
|
toggle_create_popover(gobj);
|
|
1338
1355
|
break;
|
|
1356
|
+
case 'selection-mode':
|
|
1357
|
+
gobj_send_event(gobj, "EV_TOGGLE_SELECTION_MODE", {}, gobj);
|
|
1358
|
+
break;
|
|
1339
1359
|
case 'undo':
|
|
1340
1360
|
gobj_send_event(gobj, "EV_HISTORY_UNDO", {}, gobj);
|
|
1341
1361
|
break;
|
|
@@ -1429,7 +1449,7 @@ function configure_behaviour(gobj)
|
|
|
1429
1449
|
type: "drag-canvas",
|
|
1430
1450
|
key: "drag-canvas",
|
|
1431
1451
|
enable: (event) => {
|
|
1432
|
-
if(event.shiftKey) {
|
|
1452
|
+
if(event.shiftKey || priv.selection_mode) {
|
|
1433
1453
|
return false;
|
|
1434
1454
|
}
|
|
1435
1455
|
if('targetType' in event) {
|
|
@@ -1458,7 +1478,18 @@ function configure_behaviour(gobj)
|
|
|
1458
1478
|
* button lit on a graph nobody had touched. */
|
|
1459
1479
|
type: BRUSH_SELECT_OWNED,
|
|
1460
1480
|
key: "brush-select",
|
|
1461
|
-
|
|
1481
|
+
/* There is no Shift on a phone. The toolbar's
|
|
1482
|
+
* selection mode is that key made into a state:
|
|
1483
|
+
* with it on, the band needs no modifier -- and
|
|
1484
|
+
* panning stands aside above, because the two
|
|
1485
|
+
* cannot both be a plain drag. */
|
|
1486
|
+
trigger: priv.selection_mode ? [] : ["shift"],
|
|
1487
|
+
/* A band starts on the BACKGROUND. G6's default
|
|
1488
|
+
* (`enable: true`) does not look at what is under
|
|
1489
|
+
* the pointer, so a drag that begins on a card
|
|
1490
|
+
* drew a band and moved the card at the same
|
|
1491
|
+
* time. */
|
|
1492
|
+
enable: (event) => event.targetType === 'canvas',
|
|
1462
1493
|
enableElements: ["node"],
|
|
1463
1494
|
/* Left at G6's default (false): the set is read at
|
|
1464
1495
|
* pointerup, not on every pointermove. Each answer
|
|
@@ -1494,6 +1525,9 @@ function configure_behaviour(gobj)
|
|
|
1494
1525
|
break;
|
|
1495
1526
|
}
|
|
1496
1527
|
if(!priv.edit_mode) {
|
|
1528
|
+
/* The selection and the mode that picks it both belong to
|
|
1529
|
+
* edition, and neither survives leaving it. */
|
|
1530
|
+
priv.selection_mode = false;
|
|
1497
1531
|
deselect_node(gobj);
|
|
1498
1532
|
}
|
|
1499
1533
|
graph_write_behaviors(gobj, behaviors);
|
|
@@ -3573,6 +3607,30 @@ function update_zoom_selection_button(gobj)
|
|
|
3573
3607
|
}
|
|
3574
3608
|
}
|
|
3575
3609
|
|
|
3610
|
+
/************************************************************
|
|
3611
|
+
* The selection mode is a state, so it has to LOOK like one.
|
|
3612
|
+
*
|
|
3613
|
+
* Toggled on the element rather than re-rendered with the
|
|
3614
|
+
* toolbar, for the same reason as the button above: a
|
|
3615
|
+
* re-render rebuilds the innerHTML and drops what every OTHER
|
|
3616
|
+
* button was told.
|
|
3617
|
+
************************************************************/
|
|
3618
|
+
function update_selection_mode_button(gobj)
|
|
3619
|
+
{
|
|
3620
|
+
let priv = gobj.priv;
|
|
3621
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
3622
|
+
|
|
3623
|
+
if(!$container) {
|
|
3624
|
+
return;
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
if(!$container.querySelector(".EV_TOGGLE_SELECTION_MODE")) {
|
|
3628
|
+
return; /* no edit toolbar: not in edition, or folded away */
|
|
3629
|
+
}
|
|
3630
|
+
|
|
3631
|
+
set_active_state($container, ".EV_TOGGLE_SELECTION_MODE", priv.selection_mode);
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3576
3634
|
/************************************************************
|
|
3577
3635
|
* Select a SET of nodes: what a marquee and a shift-click do.
|
|
3578
3636
|
*
|
|
@@ -7533,6 +7591,51 @@ function ac_set_operation_mode(gobj, event, kw, src)
|
|
|
7533
7591
|
return 0;
|
|
7534
7592
|
}
|
|
7535
7593
|
|
|
7594
|
+
/************************************************************
|
|
7595
|
+
* Selection mode on/off, from the edit toolbar.
|
|
7596
|
+
*
|
|
7597
|
+
* Shift is what the selection is built on, and a telephone has
|
|
7598
|
+
* no Shift: the marquee and the add-to-selection click were a
|
|
7599
|
+
* desktop feature by construction. This makes that key a MODE
|
|
7600
|
+
* -- while it is on, a tap picks a card and a drag on the
|
|
7601
|
+
* background draws the band, so the same two gestures are
|
|
7602
|
+
* reachable with one finger.
|
|
7603
|
+
*
|
|
7604
|
+
* It costs panning while it is on, and deliberately: G6 binds
|
|
7605
|
+
* both to a plain drag, and a gesture cannot be two things.
|
|
7606
|
+
* That is why it is a button and not a heuristic -- the reader
|
|
7607
|
+
* turns it off to move the camera, and the toolbar says which
|
|
7608
|
+
* of the two the graph is listening for.
|
|
7609
|
+
************************************************************/
|
|
7610
|
+
function ac_toggle_selection_mode(gobj, event, kw, src)
|
|
7611
|
+
{
|
|
7612
|
+
let priv = gobj.priv;
|
|
7613
|
+
|
|
7614
|
+
if(!priv.edit_mode) {
|
|
7615
|
+
log_error(`${gobj_short_name(gobj)}: selection mode asked outside edition`);
|
|
7616
|
+
return 0;
|
|
7617
|
+
}
|
|
7618
|
+
|
|
7619
|
+
priv.selection_mode = !priv.selection_mode;
|
|
7620
|
+
|
|
7621
|
+
if(priv.selection_mode) {
|
|
7622
|
+
/* A set has no handles, no ports and no popover: those hang
|
|
7623
|
+
* off `_selected_node_id`, the node OPENED for editing, and
|
|
7624
|
+
* in this mode a tap no longer opens one. The selection
|
|
7625
|
+
* itself stays -- entering the mode is not a way to lose it. */
|
|
7626
|
+
deselect_port(gobj);
|
|
7627
|
+
hide_node_icon(gobj);
|
|
7628
|
+
hide_node_popover(gobj);
|
|
7629
|
+
hide_resize_handles(gobj);
|
|
7630
|
+
priv._selected_node_id = null;
|
|
7631
|
+
}
|
|
7632
|
+
|
|
7633
|
+
configure_behaviour(gobj);
|
|
7634
|
+
update_selection_mode_button(gobj);
|
|
7635
|
+
|
|
7636
|
+
return 0;
|
|
7637
|
+
}
|
|
7638
|
+
|
|
7536
7639
|
/************************************************************
|
|
7537
7640
|
* Node drag end
|
|
7538
7641
|
************************************************************/
|
|
@@ -7632,11 +7735,13 @@ function ac_node_click(gobj, event, kw, src)
|
|
|
7632
7735
|
record: nodedata.data.record
|
|
7633
7736
|
});
|
|
7634
7737
|
|
|
7635
|
-
if(priv.edit_mode && kw.evt.shiftKey) {
|
|
7738
|
+
if(priv.edit_mode && (kw.evt.shiftKey || priv.selection_mode)) {
|
|
7636
7739
|
/* Shift+click extends the selection, the way it does
|
|
7637
|
-
* everywhere
|
|
7638
|
-
*
|
|
7639
|
-
*
|
|
7740
|
+
* everywhere -- and so does a plain tap while the
|
|
7741
|
+
* toolbar's selection mode is on, which is that key
|
|
7742
|
+
* for a finger. It never looks for a port: a port is
|
|
7743
|
+
* a one-node affordance, and this gesture is about
|
|
7744
|
+
* the set. */
|
|
7640
7745
|
toggle_in_selection(gobj, node_id);
|
|
7641
7746
|
} else if(priv.edit_mode) {
|
|
7642
7747
|
// Check if click hits a port
|
|
@@ -7941,6 +8046,7 @@ function create_gclass(gclass_name)
|
|
|
7941
8046
|
["EV_FULLSCREEN", ac_fullscreen, null],
|
|
7942
8047
|
["EV_SET_LAYOUT", ac_set_layout, null],
|
|
7943
8048
|
["EV_SET_OPERATION_MODE", ac_set_operation_mode, null],
|
|
8049
|
+
["EV_TOGGLE_SELECTION_MODE", ac_toggle_selection_mode, null],
|
|
7944
8050
|
["EV_SAVE_GRAPH", ac_save_graph, null],
|
|
7945
8051
|
["EV_HISTORY_UNDO", ac_history_undo, null],
|
|
7946
8052
|
["EV_HISTORY_REDO", ac_history_redo, null],
|
|
@@ -7991,6 +8097,7 @@ function create_gclass(gclass_name)
|
|
|
7991
8097
|
["EV_FULLSCREEN", 0],
|
|
7992
8098
|
["EV_SET_LAYOUT", 0],
|
|
7993
8099
|
["EV_SET_OPERATION_MODE", 0],
|
|
8100
|
+
["EV_TOGGLE_SELECTION_MODE", 0],
|
|
7994
8101
|
["EV_HISTORY_UNDO", 0],
|
|
7995
8102
|
["EV_HISTORY_REDO", 0],
|
|
7996
8103
|
["EV_SAVE_GRAPH", 0],
|
package/src/lib_icons.js
CHANGED
|
@@ -127,6 +127,19 @@ const ICONS = `<svg xmlns="http://www.w3.org/2000/svg">
|
|
|
127
127
|
<symbol id="g6-icon-toolbar-hide" viewBox="0 0 384 512">
|
|
128
128
|
<path fill="currentColor" d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/>
|
|
129
129
|
</symbol>
|
|
130
|
+
<!-- dashed marquee (selection mode).
|
|
131
|
+
The band ITSELF, because that is what the button turns on: a
|
|
132
|
+
drag on the canvas draws one and a tap picks a card. Not the
|
|
133
|
+
fit-to-selection glyph next to it in the other toolbar -- that
|
|
134
|
+
one is solid brackets around a solid object and means "put the
|
|
135
|
+
camera on what is picked", which is the opposite end of the
|
|
136
|
+
gesture. Dashes: 16 segments of 59 with gaps of 36 over a
|
|
137
|
+
perimeter of 1520, so they land on the corners. -->
|
|
138
|
+
<symbol id="g6-icon-select-mode" viewBox="0 0 512 512">
|
|
139
|
+
<rect x="46" y="86" width="420" height="340" fill="none"
|
|
140
|
+
stroke="currentColor" stroke-width="40"
|
|
141
|
+
stroke-dasharray="59 36"/>
|
|
142
|
+
</symbol>
|
|
130
143
|
<!-- floppy-disk (save) -->
|
|
131
144
|
<symbol id="g6-icon-save" viewBox="0 0 448 512">
|
|
132
145
|
<path fill="currentColor" d="M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-242.7c0-17-6.7-33.3-18.7-45.3L352 50.7C340 38.7 323.7 32 306.7 32L64 32zm32 96c0-17.7 14.3-32 32-32l160 0c17.7 0 32 14.3 32 32l0 64c0 17.7-14.3 32-32 32l-160 0c-17.7 0-32-14.3-32-32l0-64zM224 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"/>
|