@yuneta/gobj-ui 7.23.10 → 7.23.12
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 +19 -5
- package/dist/gobj-ui.cjs.js +105 -5
- package/dist/gobj-ui.es.js +105 -6
- package/index.js +1 -1
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +116 -6
- package/src/lib_graph.css +26 -0
- package/src/lib_graph.js +19 -0
- package/src/lib_icons.js +13 -0
package/README.md
CHANGED
|
@@ -877,11 +877,24 @@ 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 looks **pressed** while it is on (`pressed_state`, an inverted
|
|
888
|
+
neutral chip) rather than taking one of the palette's colours: each of those
|
|
889
|
+
names a KIND of action, and `7.23.11` borrowed undo/redo's violet for it —
|
|
890
|
+
which put the same colour on two neighbouring buttons for two different
|
|
891
|
+
reasons, and carried the whole state change in the hairline of an outline
|
|
892
|
+
glyph. It is deliberately a button and not a heuristic — the toolbar says which
|
|
893
|
+
of the two the graph is listening for, and turning it off gives the camera
|
|
894
|
+
back. It is not device-specific: the same button spares a desktop reader the
|
|
895
|
+
key. Leaving edition turns it off, and it is not persisted.
|
|
896
|
+
|
|
897
|
+
**New key for consumers: `selection mode`.**
|
|
885
898
|
|
|
886
899
|
### Tabs opened at runtime, and the two decisions their url costs
|
|
887
900
|
|
|
@@ -928,6 +941,7 @@ clicked":
|
|
|
928
941
|
| click a node | selects it **and opens it**: resize handles, ports, popovers |
|
|
929
942
|
| **shift + click** | adds that node to the selection, or takes it out |
|
|
930
943
|
| **shift + drag on the canvas** | rubber band: the selection becomes what it enclosed |
|
|
944
|
+
| 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
945
|
| **ctrl/cmd + A** | every node |
|
|
932
946
|
| the **fit-to-selection** button | puts the viewport on what is selected |
|
|
933
947
|
| drag any selected node | **moves the whole selection**, as one undo |
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -20597,6 +20597,19 @@ function set_active_state($container, selector, set) {
|
|
|
20597
20597
|
if (set) addClasses($container, selector, "color_active_state");
|
|
20598
20598
|
else removeClasses($container, selector, "color_active_state");
|
|
20599
20599
|
}
|
|
20600
|
+
/************************************************************
|
|
20601
|
+
* Set or reset the 'pressed' state of a TOGGLE.
|
|
20602
|
+
*
|
|
20603
|
+
* Not one of the colours above: each of those names a KIND of
|
|
20604
|
+
* action (create, pending, history, destructive), and a toggle
|
|
20605
|
+
* is not an action -- it is a state the control is IN. So it
|
|
20606
|
+
* looks pressed instead of changing category, which also keeps
|
|
20607
|
+
* it out of the way of a neighbour wearing the same hue.
|
|
20608
|
+
************************************************************/
|
|
20609
|
+
function set_pressed_state($container, selector, set) {
|
|
20610
|
+
if (set) addClasses($container, selector, "pressed_state");
|
|
20611
|
+
else removeClasses($container, selector, "pressed_state");
|
|
20612
|
+
}
|
|
20600
20613
|
/**
|
|
20601
20614
|
* Returns a smart stroke color in `rgba()` format based on:
|
|
20602
20615
|
* - The given fill color (hex or rgb[a])
|
|
@@ -47493,6 +47506,19 @@ var ICONS = `<svg xmlns="http://www.w3.org/2000/svg">
|
|
|
47493
47506
|
<symbol id="g6-icon-toolbar-hide" viewBox="0 0 384 512">
|
|
47494
47507
|
<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
47508
|
</symbol>
|
|
47509
|
+
<!-- dashed marquee (selection mode).
|
|
47510
|
+
The band ITSELF, because that is what the button turns on: a
|
|
47511
|
+
drag on the canvas draws one and a tap picks a card. Not the
|
|
47512
|
+
fit-to-selection glyph next to it in the other toolbar -- that
|
|
47513
|
+
one is solid brackets around a solid object and means "put the
|
|
47514
|
+
camera on what is picked", which is the opposite end of the
|
|
47515
|
+
gesture. Dashes: 16 segments of 59 with gaps of 36 over a
|
|
47516
|
+
perimeter of 1520, so they land on the corners. -->
|
|
47517
|
+
<symbol id="g6-icon-select-mode" viewBox="0 0 512 512">
|
|
47518
|
+
<rect x="46" y="86" width="420" height="340" fill="none"
|
|
47519
|
+
stroke="currentColor" stroke-width="40"
|
|
47520
|
+
stroke-dasharray="59 36"/>
|
|
47521
|
+
</symbol>
|
|
47496
47522
|
<!-- floppy-disk (save) -->
|
|
47497
47523
|
<symbol id="g6-icon-save" viewBox="0 0 448 512">
|
|
47498
47524
|
<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 +47768,7 @@ var PRIVATE_DATA$4 = {
|
|
|
47742
47768
|
toolbar_collapsed: true,
|
|
47743
47769
|
_toolbars_could_collapse: null,
|
|
47744
47770
|
_on_focusout_restore: null,
|
|
47771
|
+
selection_mode: false,
|
|
47745
47772
|
_selected_paint_ids: [],
|
|
47746
47773
|
_pending_focus_topic: null,
|
|
47747
47774
|
_pending_find: null,
|
|
@@ -48065,6 +48092,7 @@ function update_toolbar(gobj) {
|
|
|
48065
48092
|
configure_toolbar_edit(gobj);
|
|
48066
48093
|
if (graph_get_plugin(gobj, "toolbar-edit")) graph.updatePlugin({ key: "toolbar-edit" });
|
|
48067
48094
|
update_zoom_selection_button(gobj);
|
|
48095
|
+
update_selection_mode_button(gobj);
|
|
48068
48096
|
}
|
|
48069
48097
|
/************************************************************
|
|
48070
48098
|
* The floating toolbars follow the theme.
|
|
@@ -48279,7 +48307,8 @@ function configure_toolbar(gobj) {
|
|
|
48279
48307
|
* Contains edit-mode buttons: Undo, Redo, Save
|
|
48280
48308
|
************************************************************/
|
|
48281
48309
|
function configure_toolbar_edit(gobj) {
|
|
48282
|
-
|
|
48310
|
+
let priv = gobj.priv;
|
|
48311
|
+
if (!priv.edit_mode || toolbars_collapsed(gobj)) {
|
|
48283
48312
|
graph_remove_plugin(gobj, "toolbar-edit");
|
|
48284
48313
|
return;
|
|
48285
48314
|
}
|
|
@@ -48298,6 +48327,12 @@ function configure_toolbar_edit(gobj) {
|
|
|
48298
48327
|
className: "EV_CREATE_NODE_BTN color_create_state",
|
|
48299
48328
|
title: (0, i18next.t)("create node")
|
|
48300
48329
|
},
|
|
48330
|
+
{
|
|
48331
|
+
id: "g6-icon-select-mode",
|
|
48332
|
+
value: "selection-mode",
|
|
48333
|
+
className: "EV_TOGGLE_SELECTION_MODE" + (priv.selection_mode ? " pressed_state" : ""),
|
|
48334
|
+
title: (0, i18next.t)("selection mode")
|
|
48335
|
+
},
|
|
48301
48336
|
{
|
|
48302
48337
|
id: "g6-icon-save",
|
|
48303
48338
|
value: "save",
|
|
@@ -48326,6 +48361,9 @@ function configure_toolbar_edit(gobj) {
|
|
|
48326
48361
|
case "create-node":
|
|
48327
48362
|
toggle_create_popover(gobj);
|
|
48328
48363
|
break;
|
|
48364
|
+
case "selection-mode":
|
|
48365
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_SELECTION_MODE", {}, gobj);
|
|
48366
|
+
break;
|
|
48329
48367
|
case "undo":
|
|
48330
48368
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_HISTORY_UNDO", {}, gobj);
|
|
48331
48369
|
break;
|
|
@@ -48369,7 +48407,7 @@ function configure_behaviour(gobj) {
|
|
|
48369
48407
|
type: "drag-canvas",
|
|
48370
48408
|
key: "drag-canvas",
|
|
48371
48409
|
enable: (event) => {
|
|
48372
|
-
if (event.shiftKey) return false;
|
|
48410
|
+
if (event.shiftKey || priv.selection_mode) return false;
|
|
48373
48411
|
if ("targetType" in event) return event.targetType === "canvas";
|
|
48374
48412
|
return true;
|
|
48375
48413
|
}
|
|
@@ -48379,7 +48417,8 @@ function configure_behaviour(gobj) {
|
|
|
48379
48417
|
{
|
|
48380
48418
|
type: BRUSH_SELECT_OWNED,
|
|
48381
48419
|
key: "brush-select",
|
|
48382
|
-
trigger: ["shift"],
|
|
48420
|
+
trigger: priv.selection_mode ? [] : ["shift"],
|
|
48421
|
+
enable: (event) => event.targetType === "canvas",
|
|
48383
48422
|
enableElements: ["node"],
|
|
48384
48423
|
immediately: false,
|
|
48385
48424
|
onSelect: (states) => {
|
|
@@ -48395,7 +48434,10 @@ function configure_behaviour(gobj) {
|
|
|
48395
48434
|
break;
|
|
48396
48435
|
default: (0, _yuneta_gobj_js.log_error)(`operation mode unknown: ${operation_mode}`);
|
|
48397
48436
|
}
|
|
48398
|
-
if (!priv.edit_mode)
|
|
48437
|
+
if (!priv.edit_mode) {
|
|
48438
|
+
priv.selection_mode = false;
|
|
48439
|
+
deselect_node(gobj);
|
|
48440
|
+
}
|
|
48399
48441
|
graph_write_behaviors(gobj, behaviors);
|
|
48400
48442
|
}
|
|
48401
48443
|
/************************************************************
|
|
@@ -49721,6 +49763,23 @@ function update_zoom_selection_button(gobj) {
|
|
|
49721
49763
|
else disableElements($container, ".EV_ZOOM_SELECTION");
|
|
49722
49764
|
}
|
|
49723
49765
|
/************************************************************
|
|
49766
|
+
* The selection mode is a state, so it has to LOOK like one:
|
|
49767
|
+
* a PRESSED toggle, not a button wearing one of the palette's
|
|
49768
|
+
* action colours (see `pressed_state` in lib_graph.css).
|
|
49769
|
+
*
|
|
49770
|
+
* Toggled on the element rather than re-rendered with the
|
|
49771
|
+
* toolbar, for the same reason as the button above: a
|
|
49772
|
+
* re-render rebuilds the innerHTML and drops what every OTHER
|
|
49773
|
+
* button was told.
|
|
49774
|
+
************************************************************/
|
|
49775
|
+
function update_selection_mode_button(gobj) {
|
|
49776
|
+
let priv = gobj.priv;
|
|
49777
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
49778
|
+
if (!$container) return;
|
|
49779
|
+
if (!$container.querySelector(".EV_TOGGLE_SELECTION_MODE")) return;
|
|
49780
|
+
set_pressed_state($container, ".EV_TOGGLE_SELECTION_MODE", priv.selection_mode);
|
|
49781
|
+
}
|
|
49782
|
+
/************************************************************
|
|
49724
49783
|
* Select a SET of nodes: what a marquee and a shift-click do.
|
|
49725
49784
|
*
|
|
49726
49785
|
* It leaves `_selected_node_id` null even for a set of one,
|
|
@@ -52323,6 +52382,40 @@ function ac_set_operation_mode$1(gobj, event, kw, src) {
|
|
|
52323
52382
|
return 0;
|
|
52324
52383
|
}
|
|
52325
52384
|
/************************************************************
|
|
52385
|
+
* Selection mode on/off, from the edit toolbar.
|
|
52386
|
+
*
|
|
52387
|
+
* Shift is what the selection is built on, and a telephone has
|
|
52388
|
+
* no Shift: the marquee and the add-to-selection click were a
|
|
52389
|
+
* desktop feature by construction. This makes that key a MODE
|
|
52390
|
+
* -- while it is on, a tap picks a card and a drag on the
|
|
52391
|
+
* background draws the band, so the same two gestures are
|
|
52392
|
+
* reachable with one finger.
|
|
52393
|
+
*
|
|
52394
|
+
* It costs panning while it is on, and deliberately: G6 binds
|
|
52395
|
+
* both to a plain drag, and a gesture cannot be two things.
|
|
52396
|
+
* That is why it is a button and not a heuristic -- the reader
|
|
52397
|
+
* turns it off to move the camera, and the toolbar says which
|
|
52398
|
+
* of the two the graph is listening for.
|
|
52399
|
+
************************************************************/
|
|
52400
|
+
function ac_toggle_selection_mode(gobj, event, kw, src) {
|
|
52401
|
+
let priv = gobj.priv;
|
|
52402
|
+
if (!priv.edit_mode) {
|
|
52403
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: selection mode asked outside edition`);
|
|
52404
|
+
return 0;
|
|
52405
|
+
}
|
|
52406
|
+
priv.selection_mode = !priv.selection_mode;
|
|
52407
|
+
if (priv.selection_mode) {
|
|
52408
|
+
deselect_port(gobj);
|
|
52409
|
+
hide_node_icon(gobj);
|
|
52410
|
+
hide_node_popover(gobj);
|
|
52411
|
+
hide_resize_handles(gobj);
|
|
52412
|
+
priv._selected_node_id = null;
|
|
52413
|
+
}
|
|
52414
|
+
configure_behaviour(gobj);
|
|
52415
|
+
update_selection_mode_button(gobj);
|
|
52416
|
+
return 0;
|
|
52417
|
+
}
|
|
52418
|
+
/************************************************************
|
|
52326
52419
|
* Node drag end
|
|
52327
52420
|
************************************************************/
|
|
52328
52421
|
function ac_node_drag_end(gobj, event, kw, src) {
|
|
@@ -52387,7 +52480,7 @@ function ac_node_click$2(gobj, event, kw, src) {
|
|
|
52387
52480
|
topic_name: nodedata.data.desc.topic_name,
|
|
52388
52481
|
record: nodedata.data.record
|
|
52389
52482
|
});
|
|
52390
|
-
if (priv.edit_mode && kw.evt.shiftKey) toggle_in_selection(gobj, node_id);
|
|
52483
|
+
if (priv.edit_mode && (kw.evt.shiftKey || priv.selection_mode)) toggle_in_selection(gobj, node_id);
|
|
52391
52484
|
else if (priv.edit_mode) {
|
|
52392
52485
|
let containerRect = priv.$container.getBoundingClientRect();
|
|
52393
52486
|
let canvasPoint = graph.getCanvasByViewport([kw.evt.client.x - containerRect.left, kw.evt.client.y - containerRect.top]);
|
|
@@ -52685,6 +52778,11 @@ function create_gclass$4(gclass_name) {
|
|
|
52685
52778
|
ac_set_operation_mode$1,
|
|
52686
52779
|
null
|
|
52687
52780
|
],
|
|
52781
|
+
[
|
|
52782
|
+
"EV_TOGGLE_SELECTION_MODE",
|
|
52783
|
+
ac_toggle_selection_mode,
|
|
52784
|
+
null
|
|
52785
|
+
],
|
|
52688
52786
|
[
|
|
52689
52787
|
"EV_SAVE_GRAPH",
|
|
52690
52788
|
ac_save_graph,
|
|
@@ -52759,6 +52857,7 @@ function create_gclass$4(gclass_name) {
|
|
|
52759
52857
|
["EV_FULLSCREEN", 0],
|
|
52760
52858
|
["EV_SET_LAYOUT", 0],
|
|
52761
52859
|
["EV_SET_OPERATION_MODE", 0],
|
|
52860
|
+
["EV_TOGGLE_SELECTION_MODE", 0],
|
|
52762
52861
|
["EV_HISTORY_UNDO", 0],
|
|
52763
52862
|
["EV_HISTORY_REDO", 0],
|
|
52764
52863
|
["EV_SAVE_GRAPH", 0],
|
|
@@ -63610,6 +63709,7 @@ exports.rolling_bounds = rolling_bounds;
|
|
|
63610
63709
|
exports.safe_locale = safe_locale;
|
|
63611
63710
|
exports.set_active_state = set_active_state;
|
|
63612
63711
|
exports.set_cancel_state = set_cancel_state;
|
|
63712
|
+
exports.set_pressed_state = set_pressed_state;
|
|
63613
63713
|
exports.set_submit_state = set_submit_state;
|
|
63614
63714
|
exports.setup_dev = setup_dev;
|
|
63615
63715
|
exports.setup_frontend_view = setup_frontend_view;
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -20584,6 +20584,19 @@ function set_active_state($container, selector, set) {
|
|
|
20584
20584
|
if (set) addClasses($container, selector, "color_active_state");
|
|
20585
20585
|
else removeClasses($container, selector, "color_active_state");
|
|
20586
20586
|
}
|
|
20587
|
+
/************************************************************
|
|
20588
|
+
* Set or reset the 'pressed' state of a TOGGLE.
|
|
20589
|
+
*
|
|
20590
|
+
* Not one of the colours above: each of those names a KIND of
|
|
20591
|
+
* action (create, pending, history, destructive), and a toggle
|
|
20592
|
+
* is not an action -- it is a state the control is IN. So it
|
|
20593
|
+
* looks pressed instead of changing category, which also keeps
|
|
20594
|
+
* it out of the way of a neighbour wearing the same hue.
|
|
20595
|
+
************************************************************/
|
|
20596
|
+
function set_pressed_state($container, selector, set) {
|
|
20597
|
+
if (set) addClasses($container, selector, "pressed_state");
|
|
20598
|
+
else removeClasses($container, selector, "pressed_state");
|
|
20599
|
+
}
|
|
20587
20600
|
/**
|
|
20588
20601
|
* Returns a smart stroke color in `rgba()` format based on:
|
|
20589
20602
|
* - The given fill color (hex or rgb[a])
|
|
@@ -47480,6 +47493,19 @@ var ICONS = `<svg xmlns="http://www.w3.org/2000/svg">
|
|
|
47480
47493
|
<symbol id="g6-icon-toolbar-hide" viewBox="0 0 384 512">
|
|
47481
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"/>
|
|
47482
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>
|
|
47483
47509
|
<!-- floppy-disk (save) -->
|
|
47484
47510
|
<symbol id="g6-icon-save" viewBox="0 0 448 512">
|
|
47485
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"/>
|
|
@@ -47729,6 +47755,7 @@ var PRIVATE_DATA$4 = {
|
|
|
47729
47755
|
toolbar_collapsed: true,
|
|
47730
47756
|
_toolbars_could_collapse: null,
|
|
47731
47757
|
_on_focusout_restore: null,
|
|
47758
|
+
selection_mode: false,
|
|
47732
47759
|
_selected_paint_ids: [],
|
|
47733
47760
|
_pending_focus_topic: null,
|
|
47734
47761
|
_pending_find: null,
|
|
@@ -48052,6 +48079,7 @@ function update_toolbar(gobj) {
|
|
|
48052
48079
|
configure_toolbar_edit(gobj);
|
|
48053
48080
|
if (graph_get_plugin(gobj, "toolbar-edit")) graph.updatePlugin({ key: "toolbar-edit" });
|
|
48054
48081
|
update_zoom_selection_button(gobj);
|
|
48082
|
+
update_selection_mode_button(gobj);
|
|
48055
48083
|
}
|
|
48056
48084
|
/************************************************************
|
|
48057
48085
|
* The floating toolbars follow the theme.
|
|
@@ -48266,7 +48294,8 @@ function configure_toolbar(gobj) {
|
|
|
48266
48294
|
* Contains edit-mode buttons: Undo, Redo, Save
|
|
48267
48295
|
************************************************************/
|
|
48268
48296
|
function configure_toolbar_edit(gobj) {
|
|
48269
|
-
|
|
48297
|
+
let priv = gobj.priv;
|
|
48298
|
+
if (!priv.edit_mode || toolbars_collapsed(gobj)) {
|
|
48270
48299
|
graph_remove_plugin(gobj, "toolbar-edit");
|
|
48271
48300
|
return;
|
|
48272
48301
|
}
|
|
@@ -48285,6 +48314,12 @@ function configure_toolbar_edit(gobj) {
|
|
|
48285
48314
|
className: "EV_CREATE_NODE_BTN color_create_state",
|
|
48286
48315
|
title: t("create node")
|
|
48287
48316
|
},
|
|
48317
|
+
{
|
|
48318
|
+
id: "g6-icon-select-mode",
|
|
48319
|
+
value: "selection-mode",
|
|
48320
|
+
className: "EV_TOGGLE_SELECTION_MODE" + (priv.selection_mode ? " pressed_state" : ""),
|
|
48321
|
+
title: t("selection mode")
|
|
48322
|
+
},
|
|
48288
48323
|
{
|
|
48289
48324
|
id: "g6-icon-save",
|
|
48290
48325
|
value: "save",
|
|
@@ -48313,6 +48348,9 @@ function configure_toolbar_edit(gobj) {
|
|
|
48313
48348
|
case "create-node":
|
|
48314
48349
|
toggle_create_popover(gobj);
|
|
48315
48350
|
break;
|
|
48351
|
+
case "selection-mode":
|
|
48352
|
+
gobj_send_event(gobj, "EV_TOGGLE_SELECTION_MODE", {}, gobj);
|
|
48353
|
+
break;
|
|
48316
48354
|
case "undo":
|
|
48317
48355
|
gobj_send_event(gobj, "EV_HISTORY_UNDO", {}, gobj);
|
|
48318
48356
|
break;
|
|
@@ -48356,7 +48394,7 @@ function configure_behaviour(gobj) {
|
|
|
48356
48394
|
type: "drag-canvas",
|
|
48357
48395
|
key: "drag-canvas",
|
|
48358
48396
|
enable: (event) => {
|
|
48359
|
-
if (event.shiftKey) return false;
|
|
48397
|
+
if (event.shiftKey || priv.selection_mode) return false;
|
|
48360
48398
|
if ("targetType" in event) return event.targetType === "canvas";
|
|
48361
48399
|
return true;
|
|
48362
48400
|
}
|
|
@@ -48366,7 +48404,8 @@ function configure_behaviour(gobj) {
|
|
|
48366
48404
|
{
|
|
48367
48405
|
type: BRUSH_SELECT_OWNED,
|
|
48368
48406
|
key: "brush-select",
|
|
48369
|
-
trigger: ["shift"],
|
|
48407
|
+
trigger: priv.selection_mode ? [] : ["shift"],
|
|
48408
|
+
enable: (event) => event.targetType === "canvas",
|
|
48370
48409
|
enableElements: ["node"],
|
|
48371
48410
|
immediately: false,
|
|
48372
48411
|
onSelect: (states) => {
|
|
@@ -48382,7 +48421,10 @@ function configure_behaviour(gobj) {
|
|
|
48382
48421
|
break;
|
|
48383
48422
|
default: log_error(`operation mode unknown: ${operation_mode}`);
|
|
48384
48423
|
}
|
|
48385
|
-
if (!priv.edit_mode)
|
|
48424
|
+
if (!priv.edit_mode) {
|
|
48425
|
+
priv.selection_mode = false;
|
|
48426
|
+
deselect_node(gobj);
|
|
48427
|
+
}
|
|
48386
48428
|
graph_write_behaviors(gobj, behaviors);
|
|
48387
48429
|
}
|
|
48388
48430
|
/************************************************************
|
|
@@ -49708,6 +49750,23 @@ function update_zoom_selection_button(gobj) {
|
|
|
49708
49750
|
else disableElements($container, ".EV_ZOOM_SELECTION");
|
|
49709
49751
|
}
|
|
49710
49752
|
/************************************************************
|
|
49753
|
+
* The selection mode is a state, so it has to LOOK like one:
|
|
49754
|
+
* a PRESSED toggle, not a button wearing one of the palette's
|
|
49755
|
+
* action colours (see `pressed_state` in lib_graph.css).
|
|
49756
|
+
*
|
|
49757
|
+
* Toggled on the element rather than re-rendered with the
|
|
49758
|
+
* toolbar, for the same reason as the button above: a
|
|
49759
|
+
* re-render rebuilds the innerHTML and drops what every OTHER
|
|
49760
|
+
* button was told.
|
|
49761
|
+
************************************************************/
|
|
49762
|
+
function update_selection_mode_button(gobj) {
|
|
49763
|
+
let priv = gobj.priv;
|
|
49764
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
49765
|
+
if (!$container) return;
|
|
49766
|
+
if (!$container.querySelector(".EV_TOGGLE_SELECTION_MODE")) return;
|
|
49767
|
+
set_pressed_state($container, ".EV_TOGGLE_SELECTION_MODE", priv.selection_mode);
|
|
49768
|
+
}
|
|
49769
|
+
/************************************************************
|
|
49711
49770
|
* Select a SET of nodes: what a marquee and a shift-click do.
|
|
49712
49771
|
*
|
|
49713
49772
|
* It leaves `_selected_node_id` null even for a set of one,
|
|
@@ -52310,6 +52369,40 @@ function ac_set_operation_mode$1(gobj, event, kw, src) {
|
|
|
52310
52369
|
return 0;
|
|
52311
52370
|
}
|
|
52312
52371
|
/************************************************************
|
|
52372
|
+
* Selection mode on/off, from the edit toolbar.
|
|
52373
|
+
*
|
|
52374
|
+
* Shift is what the selection is built on, and a telephone has
|
|
52375
|
+
* no Shift: the marquee and the add-to-selection click were a
|
|
52376
|
+
* desktop feature by construction. This makes that key a MODE
|
|
52377
|
+
* -- while it is on, a tap picks a card and a drag on the
|
|
52378
|
+
* background draws the band, so the same two gestures are
|
|
52379
|
+
* reachable with one finger.
|
|
52380
|
+
*
|
|
52381
|
+
* It costs panning while it is on, and deliberately: G6 binds
|
|
52382
|
+
* both to a plain drag, and a gesture cannot be two things.
|
|
52383
|
+
* That is why it is a button and not a heuristic -- the reader
|
|
52384
|
+
* turns it off to move the camera, and the toolbar says which
|
|
52385
|
+
* of the two the graph is listening for.
|
|
52386
|
+
************************************************************/
|
|
52387
|
+
function ac_toggle_selection_mode(gobj, event, kw, src) {
|
|
52388
|
+
let priv = gobj.priv;
|
|
52389
|
+
if (!priv.edit_mode) {
|
|
52390
|
+
log_error(`${gobj_short_name(gobj)}: selection mode asked outside edition`);
|
|
52391
|
+
return 0;
|
|
52392
|
+
}
|
|
52393
|
+
priv.selection_mode = !priv.selection_mode;
|
|
52394
|
+
if (priv.selection_mode) {
|
|
52395
|
+
deselect_port(gobj);
|
|
52396
|
+
hide_node_icon(gobj);
|
|
52397
|
+
hide_node_popover(gobj);
|
|
52398
|
+
hide_resize_handles(gobj);
|
|
52399
|
+
priv._selected_node_id = null;
|
|
52400
|
+
}
|
|
52401
|
+
configure_behaviour(gobj);
|
|
52402
|
+
update_selection_mode_button(gobj);
|
|
52403
|
+
return 0;
|
|
52404
|
+
}
|
|
52405
|
+
/************************************************************
|
|
52313
52406
|
* Node drag end
|
|
52314
52407
|
************************************************************/
|
|
52315
52408
|
function ac_node_drag_end(gobj, event, kw, src) {
|
|
@@ -52374,7 +52467,7 @@ function ac_node_click$2(gobj, event, kw, src) {
|
|
|
52374
52467
|
topic_name: nodedata.data.desc.topic_name,
|
|
52375
52468
|
record: nodedata.data.record
|
|
52376
52469
|
});
|
|
52377
|
-
if (priv.edit_mode && kw.evt.shiftKey) toggle_in_selection(gobj, node_id);
|
|
52470
|
+
if (priv.edit_mode && (kw.evt.shiftKey || priv.selection_mode)) toggle_in_selection(gobj, node_id);
|
|
52378
52471
|
else if (priv.edit_mode) {
|
|
52379
52472
|
let containerRect = priv.$container.getBoundingClientRect();
|
|
52380
52473
|
let canvasPoint = graph.getCanvasByViewport([kw.evt.client.x - containerRect.left, kw.evt.client.y - containerRect.top]);
|
|
@@ -52672,6 +52765,11 @@ function create_gclass$4(gclass_name) {
|
|
|
52672
52765
|
ac_set_operation_mode$1,
|
|
52673
52766
|
null
|
|
52674
52767
|
],
|
|
52768
|
+
[
|
|
52769
|
+
"EV_TOGGLE_SELECTION_MODE",
|
|
52770
|
+
ac_toggle_selection_mode,
|
|
52771
|
+
null
|
|
52772
|
+
],
|
|
52675
52773
|
[
|
|
52676
52774
|
"EV_SAVE_GRAPH",
|
|
52677
52775
|
ac_save_graph,
|
|
@@ -52746,6 +52844,7 @@ function create_gclass$4(gclass_name) {
|
|
|
52746
52844
|
["EV_FULLSCREEN", 0],
|
|
52747
52845
|
["EV_SET_LAYOUT", 0],
|
|
52748
52846
|
["EV_SET_OPERATION_MODE", 0],
|
|
52847
|
+
["EV_TOGGLE_SELECTION_MODE", 0],
|
|
52749
52848
|
["EV_HISTORY_UNDO", 0],
|
|
52750
52849
|
["EV_HISTORY_REDO", 0],
|
|
52751
52850
|
["EV_SAVE_GRAPH", 0],
|
|
@@ -63539,6 +63638,6 @@ function setup_frontend_view(self) {
|
|
|
63539
63638
|
return win;
|
|
63540
63639
|
}
|
|
63541
63640
|
//#endregion
|
|
63542
|
-
export { EditControl, MarkerControl, YUI_PERIODS, YUI_PERIODS_DEFAULT, YUI_ROLLING, addClasses, apply_dev_traces, attach_clear, build_dev_panel, dev_window_was_open, disableElements, enableElements, epoch_to_local_input, epoch_to_ms, expose_view_container, fmt_epoch, getStrokeColor, infer_period, info_traffic, inject_svg_icons, is_current_period, iso_week, local_input_to_epoch, ms_to_epoch, period_bounds, period_bounds_epoch, period_label, period_name, period_shift, period_spec, period_start, refresh_clear, register_c_g6_nodes_tree, register_c_yui_form, register_c_yui_gobj_tree_js, register_c_yui_json, register_c_yui_json_graph, register_c_yui_map, register_c_yui_nav, register_c_yui_pager, register_c_yui_period, register_c_yui_schema_editor, register_c_yui_service_view, register_c_yui_shell, register_c_yui_treedb_graph, register_c_yui_treedb_schema, register_c_yui_treedb_topic_with_form, register_c_yui_treedb_topics, register_c_yui_uplot, register_c_yui_window, register_c_yui_window_manager, register_c_yui_wizard, removeChildElements, removeClasses, rolling_bounds, safe_locale, set_active_state, set_cancel_state, set_submit_state, setup_dev, setup_frontend_view, toggleClasses, yui_is_dark, yui_mount_service_view, yui_shell_close_drawer, yui_shell_close_dropdown, yui_shell_confirm_danger, yui_shell_confirm_ok, yui_shell_confirm_yesno, yui_shell_confirm_yesnocancel, yui_shell_navigate, yui_shell_open_drawer, yui_shell_overlay_dismissed, yui_shell_pop_escape, yui_shell_push_escape, yui_shell_refresh_avatars, yui_shell_register_event_handler, yui_shell_register_overlay, yui_shell_set_avatar_provider, yui_shell_set_connection_state, yui_shell_set_sub_routes, yui_shell_set_toolbar_item_badge, yui_shell_set_toolbar_item_icon, yui_shell_set_translator, yui_shell_show_error, yui_shell_show_info, yui_shell_show_modal, yui_shell_show_route_map, yui_shell_show_warning, yui_shell_toggle_drawer, yui_shell_unpark_route, yui_theme_now, yui_toolbar, yui_watch_theme };
|
|
63641
|
+
export { EditControl, MarkerControl, YUI_PERIODS, YUI_PERIODS_DEFAULT, YUI_ROLLING, addClasses, apply_dev_traces, attach_clear, build_dev_panel, dev_window_was_open, disableElements, enableElements, epoch_to_local_input, epoch_to_ms, expose_view_container, fmt_epoch, getStrokeColor, infer_period, info_traffic, inject_svg_icons, is_current_period, iso_week, local_input_to_epoch, ms_to_epoch, period_bounds, period_bounds_epoch, period_label, period_name, period_shift, period_spec, period_start, refresh_clear, register_c_g6_nodes_tree, register_c_yui_form, register_c_yui_gobj_tree_js, register_c_yui_json, register_c_yui_json_graph, register_c_yui_map, register_c_yui_nav, register_c_yui_pager, register_c_yui_period, register_c_yui_schema_editor, register_c_yui_service_view, register_c_yui_shell, register_c_yui_treedb_graph, register_c_yui_treedb_schema, register_c_yui_treedb_topic_with_form, register_c_yui_treedb_topics, register_c_yui_uplot, register_c_yui_window, register_c_yui_window_manager, register_c_yui_wizard, removeChildElements, removeClasses, rolling_bounds, safe_locale, set_active_state, set_cancel_state, set_pressed_state, set_submit_state, setup_dev, setup_frontend_view, toggleClasses, yui_is_dark, yui_mount_service_view, yui_shell_close_drawer, yui_shell_close_dropdown, yui_shell_confirm_danger, yui_shell_confirm_ok, yui_shell_confirm_yesno, yui_shell_confirm_yesnocancel, yui_shell_navigate, yui_shell_open_drawer, yui_shell_overlay_dismissed, yui_shell_pop_escape, yui_shell_push_escape, yui_shell_refresh_avatars, yui_shell_register_event_handler, yui_shell_register_overlay, yui_shell_set_avatar_provider, yui_shell_set_connection_state, yui_shell_set_sub_routes, yui_shell_set_toolbar_item_badge, yui_shell_set_toolbar_item_icon, yui_shell_set_translator, yui_shell_show_error, yui_shell_show_info, yui_shell_show_modal, yui_shell_show_route_map, yui_shell_show_warning, yui_shell_toggle_drawer, yui_shell_unpark_route, yui_theme_now, yui_toolbar, yui_watch_theme };
|
|
63543
63642
|
|
|
63544
63643
|
//# sourceMappingURL=gobj-ui.es.js.map
|
package/index.js
CHANGED
|
@@ -114,7 +114,7 @@ export {
|
|
|
114
114
|
/*
|
|
115
115
|
* Libraries and utilities
|
|
116
116
|
*/
|
|
117
|
-
export { addClasses, removeClasses, toggleClasses, removeChildElements, disableElements, enableElements, set_submit_state, set_cancel_state, set_active_state, getStrokeColor } from "./src/lib_graph.js";
|
|
117
|
+
export { addClasses, removeClasses, toggleClasses, removeChildElements, disableElements, enableElements, set_submit_state, set_cancel_state, set_active_state, set_pressed_state, getStrokeColor } from "./src/lib_graph.js";
|
|
118
118
|
export { inject_svg_icons } from "./src/lib_icons.js";
|
|
119
119
|
export { EditControl, MarkerControl } from "./src/lib_maplibre.js";
|
|
120
120
|
export { yui_toolbar } from "./src/yui_toolbar.js";
|
package/package.json
CHANGED
package/src/c_g6_nodes_tree.js
CHANGED
|
@@ -79,6 +79,7 @@ import {
|
|
|
79
79
|
set_submit_state,
|
|
80
80
|
set_cancel_state,
|
|
81
81
|
set_active_state,
|
|
82
|
+
set_pressed_state,
|
|
82
83
|
getStrokeColor,
|
|
83
84
|
} from "./lib_graph.js";
|
|
84
85
|
|
|
@@ -350,6 +351,9 @@ let PRIVATE_DATA = {
|
|
|
350
351
|
toolbar_collapsed: true, // floating toolbars folded (narrow only)
|
|
351
352
|
_toolbars_could_collapse: null, // last answer, to notice it changed
|
|
352
353
|
_on_focusout_restore: null, // ...and putting it back when it goes nowhere
|
|
354
|
+
selection_mode: false, // taps pick cards, a canvas drag is the band
|
|
355
|
+
// (edition only, transient: a mode nobody
|
|
356
|
+
// can see is a mode nobody can leave)
|
|
353
357
|
_selected_paint_ids: [], // node ids whose card is PAINTED selected
|
|
354
358
|
// (G6's 'selected' state is the selection
|
|
355
359
|
// itself; this is what is on screen, and
|
|
@@ -1026,6 +1030,7 @@ function update_toolbar(gobj)
|
|
|
1026
1030
|
/* A re-render rebuilds the innerHTML, so a button whose enabled
|
|
1027
1031
|
* state is not part of getItems() has to be told again. */
|
|
1028
1032
|
update_zoom_selection_button(gobj);
|
|
1033
|
+
update_selection_mode_button(gobj);
|
|
1029
1034
|
}
|
|
1030
1035
|
|
|
1031
1036
|
/************************************************************
|
|
@@ -1326,6 +1331,19 @@ function configure_toolbar_edit(gobj)
|
|
|
1326
1331
|
getItems: () => {
|
|
1327
1332
|
return [
|
|
1328
1333
|
{ id: 'g6-icon-plus', value: 'create-node', className: 'EV_CREATE_NODE_BTN color_create_state', title: t('create node') },
|
|
1334
|
+
/* The mode is carried in the class getItems()
|
|
1335
|
+
* returns, not only pushed onto the element after
|
|
1336
|
+
* the fact: this toolbar is rebuilt whole (a fold,
|
|
1337
|
+
* a language change), and the rebuilt DOM is not
|
|
1338
|
+
* there yet when the rebuild returns -- so a
|
|
1339
|
+
* button told afterwards came back OFF while the
|
|
1340
|
+
* graph was still listening for a selection. */
|
|
1341
|
+
{
|
|
1342
|
+
id: 'g6-icon-select-mode', value: 'selection-mode',
|
|
1343
|
+
className: 'EV_TOGGLE_SELECTION_MODE' +
|
|
1344
|
+
(priv.selection_mode? ' pressed_state' : ''),
|
|
1345
|
+
title: t('selection mode')
|
|
1346
|
+
},
|
|
1329
1347
|
{ id: 'g6-icon-save', value: 'save', className: 'EV_SAVE_GRAPH', title: t('save'), disabled: true },
|
|
1330
1348
|
{ id: 'g6-icon-undo', value: 'undo', className: 'EV_HISTORY_UNDO', title: t('undo'), disabled: true },
|
|
1331
1349
|
{ id: 'g6-icon-redo', value: 'redo', className: 'EV_HISTORY_REDO', title: t('redo'), disabled: true },
|
|
@@ -1336,6 +1354,9 @@ function configure_toolbar_edit(gobj)
|
|
|
1336
1354
|
case 'create-node':
|
|
1337
1355
|
toggle_create_popover(gobj);
|
|
1338
1356
|
break;
|
|
1357
|
+
case 'selection-mode':
|
|
1358
|
+
gobj_send_event(gobj, "EV_TOGGLE_SELECTION_MODE", {}, gobj);
|
|
1359
|
+
break;
|
|
1339
1360
|
case 'undo':
|
|
1340
1361
|
gobj_send_event(gobj, "EV_HISTORY_UNDO", {}, gobj);
|
|
1341
1362
|
break;
|
|
@@ -1429,7 +1450,7 @@ function configure_behaviour(gobj)
|
|
|
1429
1450
|
type: "drag-canvas",
|
|
1430
1451
|
key: "drag-canvas",
|
|
1431
1452
|
enable: (event) => {
|
|
1432
|
-
if(event.shiftKey) {
|
|
1453
|
+
if(event.shiftKey || priv.selection_mode) {
|
|
1433
1454
|
return false;
|
|
1434
1455
|
}
|
|
1435
1456
|
if('targetType' in event) {
|
|
@@ -1458,7 +1479,18 @@ function configure_behaviour(gobj)
|
|
|
1458
1479
|
* button lit on a graph nobody had touched. */
|
|
1459
1480
|
type: BRUSH_SELECT_OWNED,
|
|
1460
1481
|
key: "brush-select",
|
|
1461
|
-
|
|
1482
|
+
/* There is no Shift on a phone. The toolbar's
|
|
1483
|
+
* selection mode is that key made into a state:
|
|
1484
|
+
* with it on, the band needs no modifier -- and
|
|
1485
|
+
* panning stands aside above, because the two
|
|
1486
|
+
* cannot both be a plain drag. */
|
|
1487
|
+
trigger: priv.selection_mode ? [] : ["shift"],
|
|
1488
|
+
/* A band starts on the BACKGROUND. G6's default
|
|
1489
|
+
* (`enable: true`) does not look at what is under
|
|
1490
|
+
* the pointer, so a drag that begins on a card
|
|
1491
|
+
* drew a band and moved the card at the same
|
|
1492
|
+
* time. */
|
|
1493
|
+
enable: (event) => event.targetType === 'canvas',
|
|
1462
1494
|
enableElements: ["node"],
|
|
1463
1495
|
/* Left at G6's default (false): the set is read at
|
|
1464
1496
|
* pointerup, not on every pointermove. Each answer
|
|
@@ -1494,6 +1526,9 @@ function configure_behaviour(gobj)
|
|
|
1494
1526
|
break;
|
|
1495
1527
|
}
|
|
1496
1528
|
if(!priv.edit_mode) {
|
|
1529
|
+
/* The selection and the mode that picks it both belong to
|
|
1530
|
+
* edition, and neither survives leaving it. */
|
|
1531
|
+
priv.selection_mode = false;
|
|
1497
1532
|
deselect_node(gobj);
|
|
1498
1533
|
}
|
|
1499
1534
|
graph_write_behaviors(gobj, behaviors);
|
|
@@ -3573,6 +3608,32 @@ function update_zoom_selection_button(gobj)
|
|
|
3573
3608
|
}
|
|
3574
3609
|
}
|
|
3575
3610
|
|
|
3611
|
+
/************************************************************
|
|
3612
|
+
* The selection mode is a state, so it has to LOOK like one:
|
|
3613
|
+
* a PRESSED toggle, not a button wearing one of the palette's
|
|
3614
|
+
* action colours (see `pressed_state` in lib_graph.css).
|
|
3615
|
+
*
|
|
3616
|
+
* Toggled on the element rather than re-rendered with the
|
|
3617
|
+
* toolbar, for the same reason as the button above: a
|
|
3618
|
+
* re-render rebuilds the innerHTML and drops what every OTHER
|
|
3619
|
+
* button was told.
|
|
3620
|
+
************************************************************/
|
|
3621
|
+
function update_selection_mode_button(gobj)
|
|
3622
|
+
{
|
|
3623
|
+
let priv = gobj.priv;
|
|
3624
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
3625
|
+
|
|
3626
|
+
if(!$container) {
|
|
3627
|
+
return;
|
|
3628
|
+
}
|
|
3629
|
+
|
|
3630
|
+
if(!$container.querySelector(".EV_TOGGLE_SELECTION_MODE")) {
|
|
3631
|
+
return; /* no edit toolbar: not in edition, or folded away */
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3634
|
+
set_pressed_state($container, ".EV_TOGGLE_SELECTION_MODE", priv.selection_mode);
|
|
3635
|
+
}
|
|
3636
|
+
|
|
3576
3637
|
/************************************************************
|
|
3577
3638
|
* Select a SET of nodes: what a marquee and a shift-click do.
|
|
3578
3639
|
*
|
|
@@ -7533,6 +7594,51 @@ function ac_set_operation_mode(gobj, event, kw, src)
|
|
|
7533
7594
|
return 0;
|
|
7534
7595
|
}
|
|
7535
7596
|
|
|
7597
|
+
/************************************************************
|
|
7598
|
+
* Selection mode on/off, from the edit toolbar.
|
|
7599
|
+
*
|
|
7600
|
+
* Shift is what the selection is built on, and a telephone has
|
|
7601
|
+
* no Shift: the marquee and the add-to-selection click were a
|
|
7602
|
+
* desktop feature by construction. This makes that key a MODE
|
|
7603
|
+
* -- while it is on, a tap picks a card and a drag on the
|
|
7604
|
+
* background draws the band, so the same two gestures are
|
|
7605
|
+
* reachable with one finger.
|
|
7606
|
+
*
|
|
7607
|
+
* It costs panning while it is on, and deliberately: G6 binds
|
|
7608
|
+
* both to a plain drag, and a gesture cannot be two things.
|
|
7609
|
+
* That is why it is a button and not a heuristic -- the reader
|
|
7610
|
+
* turns it off to move the camera, and the toolbar says which
|
|
7611
|
+
* of the two the graph is listening for.
|
|
7612
|
+
************************************************************/
|
|
7613
|
+
function ac_toggle_selection_mode(gobj, event, kw, src)
|
|
7614
|
+
{
|
|
7615
|
+
let priv = gobj.priv;
|
|
7616
|
+
|
|
7617
|
+
if(!priv.edit_mode) {
|
|
7618
|
+
log_error(`${gobj_short_name(gobj)}: selection mode asked outside edition`);
|
|
7619
|
+
return 0;
|
|
7620
|
+
}
|
|
7621
|
+
|
|
7622
|
+
priv.selection_mode = !priv.selection_mode;
|
|
7623
|
+
|
|
7624
|
+
if(priv.selection_mode) {
|
|
7625
|
+
/* A set has no handles, no ports and no popover: those hang
|
|
7626
|
+
* off `_selected_node_id`, the node OPENED for editing, and
|
|
7627
|
+
* in this mode a tap no longer opens one. The selection
|
|
7628
|
+
* itself stays -- entering the mode is not a way to lose it. */
|
|
7629
|
+
deselect_port(gobj);
|
|
7630
|
+
hide_node_icon(gobj);
|
|
7631
|
+
hide_node_popover(gobj);
|
|
7632
|
+
hide_resize_handles(gobj);
|
|
7633
|
+
priv._selected_node_id = null;
|
|
7634
|
+
}
|
|
7635
|
+
|
|
7636
|
+
configure_behaviour(gobj);
|
|
7637
|
+
update_selection_mode_button(gobj);
|
|
7638
|
+
|
|
7639
|
+
return 0;
|
|
7640
|
+
}
|
|
7641
|
+
|
|
7536
7642
|
/************************************************************
|
|
7537
7643
|
* Node drag end
|
|
7538
7644
|
************************************************************/
|
|
@@ -7632,11 +7738,13 @@ function ac_node_click(gobj, event, kw, src)
|
|
|
7632
7738
|
record: nodedata.data.record
|
|
7633
7739
|
});
|
|
7634
7740
|
|
|
7635
|
-
if(priv.edit_mode && kw.evt.shiftKey) {
|
|
7741
|
+
if(priv.edit_mode && (kw.evt.shiftKey || priv.selection_mode)) {
|
|
7636
7742
|
/* Shift+click extends the selection, the way it does
|
|
7637
|
-
* everywhere
|
|
7638
|
-
*
|
|
7639
|
-
*
|
|
7743
|
+
* everywhere -- and so does a plain tap while the
|
|
7744
|
+
* toolbar's selection mode is on, which is that key
|
|
7745
|
+
* for a finger. It never looks for a port: a port is
|
|
7746
|
+
* a one-node affordance, and this gesture is about
|
|
7747
|
+
* the set. */
|
|
7640
7748
|
toggle_in_selection(gobj, node_id);
|
|
7641
7749
|
} else if(priv.edit_mode) {
|
|
7642
7750
|
// Check if click hits a port
|
|
@@ -7941,6 +8049,7 @@ function create_gclass(gclass_name)
|
|
|
7941
8049
|
["EV_FULLSCREEN", ac_fullscreen, null],
|
|
7942
8050
|
["EV_SET_LAYOUT", ac_set_layout, null],
|
|
7943
8051
|
["EV_SET_OPERATION_MODE", ac_set_operation_mode, null],
|
|
8052
|
+
["EV_TOGGLE_SELECTION_MODE", ac_toggle_selection_mode, null],
|
|
7944
8053
|
["EV_SAVE_GRAPH", ac_save_graph, null],
|
|
7945
8054
|
["EV_HISTORY_UNDO", ac_history_undo, null],
|
|
7946
8055
|
["EV_HISTORY_REDO", ac_history_redo, null],
|
|
@@ -7991,6 +8100,7 @@ function create_gclass(gclass_name)
|
|
|
7991
8100
|
["EV_FULLSCREEN", 0],
|
|
7992
8101
|
["EV_SET_LAYOUT", 0],
|
|
7993
8102
|
["EV_SET_OPERATION_MODE", 0],
|
|
8103
|
+
["EV_TOGGLE_SELECTION_MODE", 0],
|
|
7994
8104
|
["EV_HISTORY_UNDO", 0],
|
|
7995
8105
|
["EV_HISTORY_REDO", 0],
|
|
7996
8106
|
["EV_SAVE_GRAPH", 0],
|
package/src/lib_graph.css
CHANGED
|
@@ -177,6 +177,32 @@
|
|
|
177
177
|
background-color: var(--bulma-background, #f0f0f0);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
/*
|
|
181
|
+
* A TOGGLE that is on looks PRESSED, it does not take a colour from
|
|
182
|
+
* the palette at the top of this file: each of those names a kind of
|
|
183
|
+
* ACTION, and "the graph is listening for a selection" is not one --
|
|
184
|
+
* borrowing undo/redo's violet for it put the same colour on two
|
|
185
|
+
* neighbouring buttons for two different reasons.
|
|
186
|
+
*
|
|
187
|
+
* Inverted neutral, and deliberately hue-free: it cannot be mistaken
|
|
188
|
+
* for the hover tint declared just above (a much lighter wash of the
|
|
189
|
+
* same surface), it reads at a glance even when the glyph is a thin
|
|
190
|
+
* outline rather than a solid silhouette, and it says what it says
|
|
191
|
+
* without a hue -- which is the same reason the palette above is
|
|
192
|
+
* documented as colour-blind safe.
|
|
193
|
+
*
|
|
194
|
+
* The `:hover` half is not decoration: without it, hovering a pressed
|
|
195
|
+
* button would hand it back to the rule above (equal specificity,
|
|
196
|
+
* declared earlier, so this one wins only where both match) and the
|
|
197
|
+
* toggle would appear to switch off under the pointer.
|
|
198
|
+
*/
|
|
199
|
+
.g6-toolbar.g6-toolbar-large .g6-toolbar-item.pressed_state,
|
|
200
|
+
.g6-toolbar.g6-toolbar-large .g6-toolbar-item.pressed_state:hover {
|
|
201
|
+
background-color: var(--bulma-text, #2e333d);
|
|
202
|
+
color: var(--bulma-background, #ffffff);
|
|
203
|
+
border-radius: 4px;
|
|
204
|
+
}
|
|
205
|
+
|
|
180
206
|
/*
|
|
181
207
|
* Touch: the context menu is a LIST OF COMMANDS, and G6 sizes its
|
|
182
208
|
* rows with `padding: 8px 12px` -- 34px, which is a mouse row. The
|
package/src/lib_graph.js
CHANGED
|
@@ -109,6 +109,24 @@ function set_active_state($container, selector, set)
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
/************************************************************
|
|
113
|
+
* Set or reset the 'pressed' state of a TOGGLE.
|
|
114
|
+
*
|
|
115
|
+
* Not one of the colours above: each of those names a KIND of
|
|
116
|
+
* action (create, pending, history, destructive), and a toggle
|
|
117
|
+
* is not an action -- it is a state the control is IN. So it
|
|
118
|
+
* looks pressed instead of changing category, which also keeps
|
|
119
|
+
* it out of the way of a neighbour wearing the same hue.
|
|
120
|
+
************************************************************/
|
|
121
|
+
function set_pressed_state($container, selector, set)
|
|
122
|
+
{
|
|
123
|
+
if(set) {
|
|
124
|
+
addClasses($container, selector, "pressed_state");
|
|
125
|
+
} else {
|
|
126
|
+
removeClasses($container, selector, "pressed_state");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
112
130
|
/**
|
|
113
131
|
* Returns a smart stroke color in `rgba()` format based on:
|
|
114
132
|
* - The given fill color (hex or rgb[a])
|
|
@@ -187,5 +205,6 @@ export {
|
|
|
187
205
|
set_submit_state,
|
|
188
206
|
set_cancel_state,
|
|
189
207
|
set_active_state,
|
|
208
|
+
set_pressed_state,
|
|
190
209
|
getStrokeColor,
|
|
191
210
|
};
|
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"/>
|