@yuneta/gobj-ui 7.23.140 → 7.23.141
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 +99 -26
- package/dist/gobj-ui.cjs.js +304 -106
- package/dist/gobj-ui.es.js +304 -106
- package/package.json +2 -2
- package/src/c_g6_nodes_tree.js +75 -46
- package/src/c_yui_treedb_graph.js +146 -21
- package/src/treedb_fold_model.js +133 -1
- package/src/treedb_fold_model.test.js +80 -0
package/dist/gobj-ui.es.js
CHANGED
|
@@ -13106,7 +13106,7 @@ function ac_find_nodes$3(gobj, event, kw, src) {
|
|
|
13106
13106
|
/************************************************************
|
|
13107
13107
|
* EV_EXPAND_ALL
|
|
13108
13108
|
************************************************************/
|
|
13109
|
-
function ac_expand_all$
|
|
13109
|
+
function ac_expand_all$2(gobj, event, kw, src) {
|
|
13110
13110
|
let priv = gobj.priv;
|
|
13111
13111
|
if (priv.collapsed.size === 0) return 0;
|
|
13112
13112
|
priv.collapsed.clear();
|
|
@@ -13118,7 +13118,7 @@ function ac_expand_all$4(gobj, event, kw, src) {
|
|
|
13118
13118
|
/************************************************************
|
|
13119
13119
|
* EV_COLLAPSE_ALL — fold every card but the root.
|
|
13120
13120
|
************************************************************/
|
|
13121
|
-
function ac_collapse_all$
|
|
13121
|
+
function ac_collapse_all$2(gobj, event, kw, src) {
|
|
13122
13122
|
let priv = gobj.priv;
|
|
13123
13123
|
let json_data = gobj_read_attr(gobj, "json_data");
|
|
13124
13124
|
if (!json_data) return 0;
|
|
@@ -13418,12 +13418,12 @@ function create_gclass$13(gclass_name) {
|
|
|
13418
13418
|
],
|
|
13419
13419
|
[
|
|
13420
13420
|
"EV_EXPAND_ALL",
|
|
13421
|
-
ac_expand_all$
|
|
13421
|
+
ac_expand_all$2,
|
|
13422
13422
|
null
|
|
13423
13423
|
],
|
|
13424
13424
|
[
|
|
13425
13425
|
"EV_COLLAPSE_ALL",
|
|
13426
|
-
ac_collapse_all$
|
|
13426
|
+
ac_collapse_all$2,
|
|
13427
13427
|
null
|
|
13428
13428
|
],
|
|
13429
13429
|
[
|
|
@@ -14495,7 +14495,7 @@ function ac_search$2(gobj, event, kw, src) {
|
|
|
14495
14495
|
/************************************************************
|
|
14496
14496
|
* EV_EXPAND_ALL — expand every already-loaded container
|
|
14497
14497
|
************************************************************/
|
|
14498
|
-
function ac_expand_all$
|
|
14498
|
+
function ac_expand_all$1(gobj, event, kw, src) {
|
|
14499
14499
|
let priv = gobj.priv;
|
|
14500
14500
|
if (priv.root === null || priv.root === void 0) return 0;
|
|
14501
14501
|
let paths = [];
|
|
@@ -14513,7 +14513,7 @@ function ac_expand_all$3(gobj, event, kw, src) {
|
|
|
14513
14513
|
/************************************************************
|
|
14514
14514
|
* EV_COLLAPSE_ALL
|
|
14515
14515
|
************************************************************/
|
|
14516
|
-
function ac_collapse_all$
|
|
14516
|
+
function ac_collapse_all$1(gobj, event, kw, src) {
|
|
14517
14517
|
gobj.priv.expanded.clear();
|
|
14518
14518
|
render_view$1(gobj);
|
|
14519
14519
|
return 0;
|
|
@@ -14698,12 +14698,12 @@ function create_gclass$12(gclass_name) {
|
|
|
14698
14698
|
],
|
|
14699
14699
|
[
|
|
14700
14700
|
"EV_EXPAND_ALL",
|
|
14701
|
-
ac_expand_all$
|
|
14701
|
+
ac_expand_all$1,
|
|
14702
14702
|
null
|
|
14703
14703
|
],
|
|
14704
14704
|
[
|
|
14705
14705
|
"EV_COLLAPSE_ALL",
|
|
14706
|
-
ac_collapse_all$
|
|
14706
|
+
ac_collapse_all$1,
|
|
14707
14707
|
null
|
|
14708
14708
|
],
|
|
14709
14709
|
[
|
|
@@ -19725,7 +19725,7 @@ function ac_toggle_collapse(gobj, event, kw, src) {
|
|
|
19725
19725
|
/************************************************************
|
|
19726
19726
|
* Force every node visible (overrides threshold).
|
|
19727
19727
|
************************************************************/
|
|
19728
|
-
function ac_expand_all
|
|
19728
|
+
function ac_expand_all(gobj, event, kw, src) {
|
|
19729
19729
|
let priv = gobj.priv;
|
|
19730
19730
|
if (!priv.collapse_state) priv.collapse_state = {};
|
|
19731
19731
|
if (priv.node_by_id) for (let id of Object.keys(priv.node_by_id)) {
|
|
@@ -19738,7 +19738,7 @@ function ac_expand_all$2(gobj, event, kw, src) {
|
|
|
19738
19738
|
/************************************************************
|
|
19739
19739
|
* Collapse every node that has children.
|
|
19740
19740
|
************************************************************/
|
|
19741
|
-
function ac_collapse_all
|
|
19741
|
+
function ac_collapse_all(gobj, event, kw, src) {
|
|
19742
19742
|
let priv = gobj.priv;
|
|
19743
19743
|
if (!priv.collapse_state) priv.collapse_state = {};
|
|
19744
19744
|
if (priv.node_by_id) for (let id of Object.keys(priv.node_by_id)) {
|
|
@@ -20090,12 +20090,12 @@ function create_gclass$9(gclass_name) {
|
|
|
20090
20090
|
],
|
|
20091
20091
|
[
|
|
20092
20092
|
"EV_EXPAND_ALL",
|
|
20093
|
-
ac_expand_all
|
|
20093
|
+
ac_expand_all,
|
|
20094
20094
|
null
|
|
20095
20095
|
],
|
|
20096
20096
|
[
|
|
20097
20097
|
"EV_COLLAPSE_ALL",
|
|
20098
|
-
ac_collapse_all
|
|
20098
|
+
ac_collapse_all,
|
|
20099
20099
|
null
|
|
20100
20100
|
],
|
|
20101
20101
|
[
|
|
@@ -27734,7 +27734,7 @@ function fold_build_model(descs, records, opts) {
|
|
|
27734
27734
|
for (let k of reach_from(nodes, [node.key])) reached.add(k);
|
|
27735
27735
|
}
|
|
27736
27736
|
for (let topic_name of topics) if (roots[topic_name].length > 0) groups.set(fold_root_group_key(topic_name), roots[topic_name]);
|
|
27737
|
-
|
|
27737
|
+
let model = {
|
|
27738
27738
|
nodes,
|
|
27739
27739
|
groups,
|
|
27740
27740
|
topics,
|
|
@@ -27743,8 +27743,52 @@ function fold_build_model(descs, records, opts) {
|
|
|
27743
27743
|
main_topic,
|
|
27744
27744
|
linked,
|
|
27745
27745
|
loose,
|
|
27746
|
-
loose_shown
|
|
27746
|
+
loose_shown,
|
|
27747
|
+
level_of: null,
|
|
27748
|
+
levels: 0
|
|
27747
27749
|
};
|
|
27750
|
+
count_levels(model);
|
|
27751
|
+
return model;
|
|
27752
|
+
}
|
|
27753
|
+
/************************************************************
|
|
27754
|
+
* The LEVELS of the main tree: the roots of the main topic --
|
|
27755
|
+
* and of the topics hung from it, whose roots are the loose
|
|
27756
|
+
* records the reader asked for -- are level 1, their children
|
|
27757
|
+
* level 2, and so on down every hook of every topic that is not
|
|
27758
|
+
* hidden. A node reached by two paths takes the shallowest.
|
|
27759
|
+
*
|
|
27760
|
+
* With no main topic every topic is a tree of its own and all
|
|
27761
|
+
* of them count. A topic the schema does not tie to the main
|
|
27762
|
+
* one is a separate tree, and has no level: the stepper of the
|
|
27763
|
+
* toolbar speaks for the main tree and nothing else, those
|
|
27764
|
+
* trees are opened by their own pills.
|
|
27765
|
+
************************************************************/
|
|
27766
|
+
function count_levels(model) {
|
|
27767
|
+
let level_of = /* @__PURE__ */ new Map();
|
|
27768
|
+
let queue = [];
|
|
27769
|
+
let deepest = 0;
|
|
27770
|
+
for (let topic_name of model.topics) {
|
|
27771
|
+
if (model.main_topic && !model.linked.has(topic_name)) continue;
|
|
27772
|
+
let roots = model.groups.get(fold_root_group_key(topic_name)) || [];
|
|
27773
|
+
for (let key of roots) if (!level_of.has(key)) {
|
|
27774
|
+
level_of.set(key, 1);
|
|
27775
|
+
queue.push(key);
|
|
27776
|
+
}
|
|
27777
|
+
}
|
|
27778
|
+
let head = 0;
|
|
27779
|
+
while (head < queue.length) {
|
|
27780
|
+
let key = queue[head++];
|
|
27781
|
+
let lv = level_of.get(key);
|
|
27782
|
+
if (lv > deepest) deepest = lv;
|
|
27783
|
+
let node = model.nodes.get(key);
|
|
27784
|
+
if (!node) continue;
|
|
27785
|
+
for (let hook of Object.keys(node.hooks)) for (let child of node.hooks[hook]) if (!level_of.has(child)) {
|
|
27786
|
+
level_of.set(child, lv + 1);
|
|
27787
|
+
queue.push(child);
|
|
27788
|
+
}
|
|
27789
|
+
}
|
|
27790
|
+
model.level_of = level_of;
|
|
27791
|
+
model.levels = deepest;
|
|
27748
27792
|
}
|
|
27749
27793
|
/************************************************************
|
|
27750
27794
|
* The topic the schema hangs the others from: the one whose hooks
|
|
@@ -27870,14 +27914,6 @@ function fold_show_more(model, state, group_key) {
|
|
|
27870
27914
|
return n;
|
|
27871
27915
|
}
|
|
27872
27916
|
/************************************************************
|
|
27873
|
-
* Every group open on ALL its children. This is the reader
|
|
27874
|
-
* asking for the whole thing; the pages are for the other way in.
|
|
27875
|
-
************************************************************/
|
|
27876
|
-
function fold_expand_all(model, state) {
|
|
27877
|
-
state.shown.clear();
|
|
27878
|
-
for (let [group_key, list] of model.groups) if (list.length > 0) state.shown.set(group_key, list.length);
|
|
27879
|
-
}
|
|
27880
|
-
/************************************************************
|
|
27881
27917
|
* The roots and nothing else -- the first page of each topic's
|
|
27882
27918
|
* roots, the way the graph looks before anything is opened.
|
|
27883
27919
|
************************************************************/
|
|
@@ -27889,40 +27925,51 @@ function fold_collapse_all(model, state) {
|
|
|
27889
27925
|
}
|
|
27890
27926
|
}
|
|
27891
27927
|
/************************************************************
|
|
27892
|
-
*
|
|
27893
|
-
*
|
|
27894
|
-
*
|
|
27895
|
-
*
|
|
27928
|
+
* The toolbar's STEPPER over the levels of the main tree (see
|
|
27929
|
+
* count_levels): level N shows the roots and N-1 levels under
|
|
27930
|
+
* them. A level is a floor of what is open, not a picture that
|
|
27931
|
+
* replaces it:
|
|
27932
|
+
*
|
|
27933
|
+
* opening to N opens, on its first page, every hook of
|
|
27934
|
+
* every node above level N that is folded;
|
|
27935
|
+
* what the reader opened, and every page
|
|
27936
|
+
* already shown, stays
|
|
27937
|
+
* closing to N folds every hook of every node at level N
|
|
27938
|
+
* or below, and touches nothing above it
|
|
27939
|
+
*
|
|
27940
|
+
* A separate tree (a topic not tied to the main one) has no
|
|
27941
|
+
* level, so neither ever touches it.
|
|
27896
27942
|
************************************************************/
|
|
27897
|
-
function
|
|
27898
|
-
|
|
27899
|
-
|
|
27900
|
-
|
|
27901
|
-
|
|
27902
|
-
|
|
27903
|
-
|
|
27904
|
-
|
|
27905
|
-
|
|
27906
|
-
|
|
27907
|
-
}
|
|
27908
|
-
}
|
|
27909
|
-
while (queue.length) {
|
|
27910
|
-
let key = queue.shift();
|
|
27911
|
-
let lv = level.get(key);
|
|
27912
|
-
if (lv >= depth) continue;
|
|
27943
|
+
function fold_level_clamp(model, level) {
|
|
27944
|
+
let top = model.levels > 0 ? model.levels : 1;
|
|
27945
|
+
level = Math.floor(Number(level)) || 1;
|
|
27946
|
+
if (level < 1) return 1;
|
|
27947
|
+
if (level > top) return top;
|
|
27948
|
+
return level;
|
|
27949
|
+
}
|
|
27950
|
+
function fold_open_levels(model, state, level) {
|
|
27951
|
+
for (let [key, lv] of model.level_of) {
|
|
27952
|
+
if (lv >= level) continue;
|
|
27913
27953
|
let node = model.nodes.get(key);
|
|
27914
27954
|
if (!node) continue;
|
|
27915
27955
|
for (let hook of Object.keys(node.hooks)) {
|
|
27916
|
-
let
|
|
27917
|
-
if (
|
|
27918
|
-
state.shown.set(fold_group_key(key, hook), state.page_size);
|
|
27919
|
-
for (let child of children) if (!level.has(child)) {
|
|
27920
|
-
level.set(child, lv + 1);
|
|
27921
|
-
queue.push(child);
|
|
27922
|
-
}
|
|
27956
|
+
let group_key = fold_group_key(key, hook);
|
|
27957
|
+
if (node.hooks[hook].length > 0 && !fold_is_open(state, group_key)) state.shown.set(group_key, state.page_size);
|
|
27923
27958
|
}
|
|
27924
27959
|
}
|
|
27925
27960
|
}
|
|
27961
|
+
function fold_close_levels(model, state, level) {
|
|
27962
|
+
for (let [key, lv] of model.level_of) {
|
|
27963
|
+
if (lv < level) continue;
|
|
27964
|
+
let node = model.nodes.get(key);
|
|
27965
|
+
if (!node) continue;
|
|
27966
|
+
for (let hook of Object.keys(node.hooks)) state.shown.delete(fold_group_key(key, hook));
|
|
27967
|
+
}
|
|
27968
|
+
}
|
|
27969
|
+
function fold_expand_to_level(model, state, level) {
|
|
27970
|
+
fold_collapse_all(model, state);
|
|
27971
|
+
fold_open_levels(model, state, fold_level_clamp(model, level));
|
|
27972
|
+
}
|
|
27926
27973
|
/************************************************************
|
|
27927
27974
|
* The set of node keys on screen, from the roots down through
|
|
27928
27975
|
* every open group -- and only through open groups whose parent
|
|
@@ -55165,8 +55212,9 @@ function ensure_brush_select_owned() {
|
|
|
55165
55212
|
* The graph opens FOLDED, like a JSON viewer.
|
|
55166
55213
|
*
|
|
55167
55214
|
* Every record of every topic is fetched, but only the ones on
|
|
55168
|
-
* screen become G6 nodes: the roots,
|
|
55169
|
-
*
|
|
55215
|
+
* screen become G6 nodes: the roots, and the MAIN tree open to
|
|
55216
|
+
* the reader's level (`fold_level`, `expand_depth` until they
|
|
55217
|
+
* step it), one page (`fold_page_size`) of children per hook. Each
|
|
55170
55218
|
* card carries a pill per hook that has children -- `▸ devices
|
|
55171
55219
|
* 142` -- which opens or folds that hook; an open hook with more
|
|
55172
55220
|
* children than its page ends in a `+N` chip that opens the next
|
|
@@ -55344,7 +55392,8 @@ var attrs_table$4 = [
|
|
|
55344
55392
|
SDATA(data_type_t.DTP_LIST, "layout_names", sdata_flag_t.SDF_RD, JSON.stringify(Object.keys(_layouts)), "Available layout names (read-only, for parent to query)"),
|
|
55345
55393
|
SDATA(data_type_t.DTP_STRING, "hook_port_position", 0, "bottom", "Hook port position"),
|
|
55346
55394
|
SDATA(data_type_t.DTP_STRING, "fkey_port_position", 0, "top", "Fkey port position"),
|
|
55347
|
-
SDATA(data_type_t.DTP_INTEGER, "expand_depth", 0, 2, "Levels open when a treedb loads: 1 = the roots alone, 2 = the roots and their children. Every open hook shows its first page"),
|
|
55395
|
+
SDATA(data_type_t.DTP_INTEGER, "expand_depth", 0, 2, "Levels open when a treedb loads, until the reader steps (`fold_level`): 1 = the roots alone, 2 = the roots and their children. Every open hook shows its first page"),
|
|
55396
|
+
SDATA(data_type_t.DTP_INTEGER, "fold_level", 0, 0, "The level of the MAIN tree the toolbar's stepper stands on: 1 = its roots, N = N-1 levels under them; 0 = `expand_depth`. The host persists it and sends EV_SET_FOLD_LEVEL; it is published back in EV_LEGEND_STATE (`fold`) with the levels the tree has"),
|
|
55348
55397
|
SDATA(data_type_t.DTP_INTEGER, "fold_page_size", 0, 24, "Children of one hook shown per page; the `+N` chip after the page opens the next one"),
|
|
55349
55398
|
SDATA(data_type_t.DTP_LIST, "hidden_topics", 0, "[]", "Topics left out of the tree: no card, no pill counts them, no edge reaches them"),
|
|
55350
55399
|
SDATA(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"),
|
|
@@ -55436,6 +55485,7 @@ var PRIVATE_DATA$4 = {
|
|
|
55436
55485
|
_nodes_total: 0,
|
|
55437
55486
|
_nodes_placed: 0,
|
|
55438
55487
|
expand_depth: 2,
|
|
55488
|
+
fold_level: 0,
|
|
55439
55489
|
fold_page_size: 24,
|
|
55440
55490
|
hidden_topics: null,
|
|
55441
55491
|
main_topic: "",
|
|
@@ -61320,7 +61370,12 @@ function publish_legend_state(gobj, visible) {
|
|
|
61320
61370
|
gobj_publish_event(gobj, "EV_LEGEND_STATE", {
|
|
61321
61371
|
main_topic: model.main_topic,
|
|
61322
61372
|
main_chosen: !!gobj_read_str_attr(gobj, "main_topic"),
|
|
61323
|
-
topics
|
|
61373
|
+
topics,
|
|
61374
|
+
fold: {
|
|
61375
|
+
topic: model.main_topic,
|
|
61376
|
+
level: current_fold_level(gobj),
|
|
61377
|
+
levels: model.levels
|
|
61378
|
+
}
|
|
61324
61379
|
});
|
|
61325
61380
|
}
|
|
61326
61381
|
async function reconcile_fold_apply(gobj, opts, visible) {
|
|
@@ -61625,7 +61680,7 @@ function ac_load_data(gobj, event, kw, src) {
|
|
|
61625
61680
|
}
|
|
61626
61681
|
if (all_loaded && priv.graph) {
|
|
61627
61682
|
rebuild_fold_model(gobj);
|
|
61628
|
-
|
|
61683
|
+
fold_expand_to_level(priv._fold_model, priv._fold_state, current_fold_level(gobj));
|
|
61629
61684
|
count_placed_records(gobj);
|
|
61630
61685
|
let auto_laid = false;
|
|
61631
61686
|
try {
|
|
@@ -62029,19 +62084,46 @@ function ac_show_more(gobj, event, kw, src) {
|
|
|
62029
62084
|
return 0;
|
|
62030
62085
|
}
|
|
62031
62086
|
/************************************************************
|
|
62032
|
-
* The
|
|
62033
|
-
*
|
|
62034
|
-
* the
|
|
62087
|
+
* The level of the main tree the toolbar's stepper stands on:
|
|
62088
|
+
* `fold_level` once the reader has stepped, `expand_depth`
|
|
62089
|
+
* until then, clamped to the levels the tree has.
|
|
62035
62090
|
************************************************************/
|
|
62036
|
-
function
|
|
62091
|
+
function current_fold_level(gobj) {
|
|
62037
62092
|
let priv = gobj.priv;
|
|
62038
|
-
|
|
62039
|
-
|
|
62093
|
+
let level = gobj_read_integer_attr(gobj, "fold_level");
|
|
62094
|
+
if (!(level > 0)) level = gobj_read_integer_attr(gobj, "expand_depth");
|
|
62095
|
+
if (!priv._fold_model) return level;
|
|
62096
|
+
return fold_level_clamp(priv._fold_model, level);
|
|
62097
|
+
}
|
|
62098
|
+
/************************************************************
|
|
62099
|
+
* The toolbar's stepper: one level more or one less of the
|
|
62100
|
+
* MAIN tree (the host owns the number and persists it; this
|
|
62101
|
+
* applies it). Deeper opens the hooks above the new level,
|
|
62102
|
+
* shallower folds from it down -- a level is a floor, not a
|
|
62103
|
+
* picture, so what the reader opened by its pill stays (see
|
|
62104
|
+
* treedb_fold_model). Replaces expand all / collapse all
|
|
62105
|
+
* (7.23.141): the whole treedb at once was the pile, and
|
|
62106
|
+
* closing threw away everything the reader had opened.
|
|
62107
|
+
************************************************************/
|
|
62108
|
+
function ac_set_fold_level(gobj, event, kw, src) {
|
|
62109
|
+
let priv = gobj.priv;
|
|
62110
|
+
let level = Number(kw && kw.level);
|
|
62111
|
+
if (!(level > 0)) {
|
|
62112
|
+
log_error(`${gobj_short_name(gobj)}: fold level '${kw && kw.level}' is not a level`);
|
|
62040
62113
|
return -1;
|
|
62041
62114
|
}
|
|
62115
|
+
if (!priv._fold_model) {
|
|
62116
|
+
gobj_write_attr(gobj, "fold_level", level);
|
|
62117
|
+
return 0;
|
|
62118
|
+
}
|
|
62119
|
+
let from = current_fold_level(gobj);
|
|
62120
|
+
level = fold_level_clamp(priv._fold_model, level);
|
|
62121
|
+
gobj_write_attr(gobj, "fold_level", level);
|
|
62122
|
+
if (level === from) return 0;
|
|
62042
62123
|
let keep = fold_keep_node(gobj);
|
|
62043
62124
|
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
62044
|
-
|
|
62125
|
+
if (level > from) fold_open_levels(priv._fold_model, priv._fold_state, level);
|
|
62126
|
+
else fold_close_levels(priv._fold_model, priv._fold_state, level);
|
|
62045
62127
|
reconcile_fold(gobj, {
|
|
62046
62128
|
keep,
|
|
62047
62129
|
keep_vp: vp
|
|
@@ -62069,29 +62151,11 @@ function fold_keep_node(gobj) {
|
|
|
62069
62151
|
return "";
|
|
62070
62152
|
}
|
|
62071
62153
|
/************************************************************
|
|
62072
|
-
* The roots alone.
|
|
62073
|
-
************************************************************/
|
|
62074
|
-
function ac_collapse_all$1(gobj, event, kw, src) {
|
|
62075
|
-
let priv = gobj.priv;
|
|
62076
|
-
if (!priv._fold_model) {
|
|
62077
|
-
log_error(`${gobj_short_name(gobj)}: collapse all with no tree loaded`);
|
|
62078
|
-
return -1;
|
|
62079
|
-
}
|
|
62080
|
-
let keep = fold_keep_node(gobj);
|
|
62081
|
-
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
62082
|
-
fold_collapse_all(priv._fold_model, priv._fold_state);
|
|
62083
|
-
reconcile_fold(gobj, {
|
|
62084
|
-
keep,
|
|
62085
|
-
keep_vp: vp
|
|
62086
|
-
});
|
|
62087
|
-
return 0;
|
|
62088
|
-
}
|
|
62089
|
-
/************************************************************
|
|
62090
62154
|
* The legend's three settings, from the host, which persists
|
|
62091
62155
|
* them. Each rebuilds the tree; the fold state is kept -- it is
|
|
62092
62156
|
* keyed by group, and a group that is gone is never read -- except
|
|
62093
62157
|
* for a new MAIN topic, whose roots are other roots: the tree
|
|
62094
|
-
* opens again at
|
|
62158
|
+
* opens again at the reader's level, now counted from them.
|
|
62095
62159
|
************************************************************/
|
|
62096
62160
|
function ac_set_hidden_topics(gobj, event, kw, src) {
|
|
62097
62161
|
let priv = gobj.priv;
|
|
@@ -62109,7 +62173,7 @@ function ac_set_main_topic(gobj, event, kw, src) {
|
|
|
62109
62173
|
let keep = fold_keep_node(gobj);
|
|
62110
62174
|
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
62111
62175
|
rebuild_fold_model(gobj);
|
|
62112
|
-
|
|
62176
|
+
fold_expand_to_level(priv._fold_model, priv._fold_state, current_fold_level(gobj));
|
|
62113
62177
|
reconcile_fold(gobj, {
|
|
62114
62178
|
relayout: true,
|
|
62115
62179
|
keep,
|
|
@@ -62670,13 +62734,8 @@ function create_gclass$4(gclass_name) {
|
|
|
62670
62734
|
null
|
|
62671
62735
|
],
|
|
62672
62736
|
[
|
|
62673
|
-
"
|
|
62674
|
-
|
|
62675
|
-
null
|
|
62676
|
-
],
|
|
62677
|
-
[
|
|
62678
|
-
"EV_COLLAPSE_ALL",
|
|
62679
|
-
ac_collapse_all$1,
|
|
62737
|
+
"EV_SET_FOLD_LEVEL",
|
|
62738
|
+
ac_set_fold_level,
|
|
62680
62739
|
null
|
|
62681
62740
|
],
|
|
62682
62741
|
[
|
|
@@ -62819,8 +62878,7 @@ function create_gclass$4(gclass_name) {
|
|
|
62819
62878
|
["EV_CAMERA_CHANGED", event_flag_t.EVF_OUTPUT_EVENT | event_flag_t.EVF_NO_WARN_SUBS],
|
|
62820
62879
|
["EV_TOGGLE_FOLD", 0],
|
|
62821
62880
|
["EV_SHOW_MORE", 0],
|
|
62822
|
-
["
|
|
62823
|
-
["EV_COLLAPSE_ALL", 0],
|
|
62881
|
+
["EV_SET_FOLD_LEVEL", 0],
|
|
62824
62882
|
["EV_SET_HIDDEN_TOPICS", 0],
|
|
62825
62883
|
["EV_SET_MAIN_TOPIC", 0],
|
|
62826
62884
|
["EV_SET_LOOSE_TOPICS", 0],
|
|
@@ -62904,6 +62962,7 @@ var attrs_table$3 = [
|
|
|
62904
62962
|
SDATA(data_type_t.DTP_STRING, "node_mode", 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"),
|
|
62905
62963
|
SDATA(data_type_t.DTP_BOOLEAN, "node_labels", sdata_flag_t.SDF_PERSIST, true, "A `shape` node says its name under its figure. User preference"),
|
|
62906
62964
|
SDATA(data_type_t.DTP_DICT, "camera", 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"),
|
|
62965
|
+
SDATA(data_type_t.DTP_INTEGER, "fold_level", 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"),
|
|
62907
62966
|
SDATA(data_type_t.DTP_POINTER, "gobj_remote_yuno", 0, null, "Remote Yuno to request data"),
|
|
62908
62967
|
SDATA(data_type_t.DTP_STRING, "treedb_name", 0, null, "Remote service treedb name"),
|
|
62909
62968
|
SDATA(data_type_t.DTP_DICT, "descs", 0, null, "Descriptions of topics obtained"),
|
|
@@ -62979,6 +63038,7 @@ function mt_create$3(gobj) {
|
|
|
62979
63038
|
hook_port_position: "bottom",
|
|
62980
63039
|
fkey_port_position: "top",
|
|
62981
63040
|
expand_depth: gobj_read_integer_attr(gobj, "expand_depth"),
|
|
63041
|
+
fold_level: gobj_read_integer_attr(gobj, "fold_level"),
|
|
62982
63042
|
fold_page_size: gobj_read_integer_attr(gobj, "fold_page_size"),
|
|
62983
63043
|
minimap_min_nodes: gobj_read_integer_attr(gobj, "minimap_min_nodes"),
|
|
62984
63044
|
with_gridline: gobj_read_bool_attr(gobj, "with_gridline"),
|
|
@@ -63286,6 +63346,127 @@ function refresh_node_shape_buttons(gobj, $root) {
|
|
|
63286
63346
|
$labels.disabled = mode !== "shape";
|
|
63287
63347
|
}
|
|
63288
63348
|
}
|
|
63349
|
+
/************************************************************
|
|
63350
|
+
* The fold STEPPER: one level less, where the tree stands, one
|
|
63351
|
+
* level more.
|
|
63352
|
+
*
|
|
63353
|
+
* It replaces the fold pair (7.23.141). `expand all` opened every
|
|
63354
|
+
* hook of the treedb -- the pile, on purpose, which on a treedb
|
|
63355
|
+
* of thousands is a pile nobody reads -- and `collapse all` threw
|
|
63356
|
+
* away everything the reader had opened. The stepper walks the
|
|
63357
|
+
* MAIN tree a level at a time, the way the frontend view opens
|
|
63358
|
+
* one level per press: `+` opens the next level under the main
|
|
63359
|
+
* topic's roots, through every topic that is not hidden; `-`
|
|
63360
|
+
* folds the deepest one. Pages and pills the reader opened stay.
|
|
63361
|
+
*
|
|
63362
|
+
* The readout says what the two buttons act on, which no chevron
|
|
63363
|
+
* can: the main topic -- its swatch and its name, which is DATA
|
|
63364
|
+
* and never translated -- and `level/levels`. On a phone the name
|
|
63365
|
+
* goes and the numbers stay. The level is the reader's, per
|
|
63366
|
+
* treedb: persisted (`fold_level`) and handed to the engine on
|
|
63367
|
+
* creation, so a reload opens where it was left.
|
|
63368
|
+
*
|
|
63369
|
+
* Both buttons are born disabled: nothing can be stepped until
|
|
63370
|
+
* the engine has said how deep the tree goes (EV_LEGEND_STATE).
|
|
63371
|
+
************************************************************/
|
|
63372
|
+
function fold_level_items(gobj, wide) {
|
|
63373
|
+
let step_button = (cls, icon, key, event_name) => {
|
|
63374
|
+
return [
|
|
63375
|
+
"button",
|
|
63376
|
+
{
|
|
63377
|
+
class: `${cls} button`,
|
|
63378
|
+
type: "button",
|
|
63379
|
+
style: {
|
|
63380
|
+
height: wide,
|
|
63381
|
+
width: "2.5em"
|
|
63382
|
+
},
|
|
63383
|
+
disabled: true,
|
|
63384
|
+
title: t(key),
|
|
63385
|
+
"data-i18n-title": key,
|
|
63386
|
+
"aria-label": t(key),
|
|
63387
|
+
"data-i18n-aria-label": key
|
|
63388
|
+
},
|
|
63389
|
+
yui_toolbar_icon(icon),
|
|
63390
|
+
{ click: (evt) => {
|
|
63391
|
+
evt.stopPropagation();
|
|
63392
|
+
gobj_send_event(gobj, event_name, {}, gobj);
|
|
63393
|
+
} }
|
|
63394
|
+
];
|
|
63395
|
+
};
|
|
63396
|
+
return [[
|
|
63397
|
+
"div",
|
|
63398
|
+
{
|
|
63399
|
+
class: "GRAPH_FOLD_STEPPER buttons has-addons",
|
|
63400
|
+
style: "margin:0; flex:0 0 auto; flex-wrap:nowrap; align-items:stretch;"
|
|
63401
|
+
},
|
|
63402
|
+
[
|
|
63403
|
+
step_button("GRAPH_FOLD_COLLAPSE", "yi-chevron-right", "collapse one level", "EV_COLLAPSE_LEVEL"),
|
|
63404
|
+
[
|
|
63405
|
+
"div",
|
|
63406
|
+
{
|
|
63407
|
+
class: "GRAPH_FOLD_LEVEL button",
|
|
63408
|
+
style: {
|
|
63409
|
+
height: wide,
|
|
63410
|
+
cursor: "default",
|
|
63411
|
+
gap: ".35rem"
|
|
63412
|
+
},
|
|
63413
|
+
role: "status",
|
|
63414
|
+
title: t("fold level"),
|
|
63415
|
+
"data-i18n-title": "fold level"
|
|
63416
|
+
},
|
|
63417
|
+
[
|
|
63418
|
+
["span", {
|
|
63419
|
+
class: "GRAPH_FOLD_SWATCH",
|
|
63420
|
+
style: "display:none; width:.8rem; height:.8rem; border-radius:3px; flex:0 0 auto; border:1px solid rgba(0,0,0,.25);"
|
|
63421
|
+
}],
|
|
63422
|
+
["span", {
|
|
63423
|
+
class: "GRAPH_FOLD_TOPIC is-hidden-mobile",
|
|
63424
|
+
style: "max-width:10em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:600;"
|
|
63425
|
+
}],
|
|
63426
|
+
[
|
|
63427
|
+
"span",
|
|
63428
|
+
{
|
|
63429
|
+
class: "GRAPH_FOLD_WORD",
|
|
63430
|
+
i18n: "level"
|
|
63431
|
+
},
|
|
63432
|
+
"level"
|
|
63433
|
+
],
|
|
63434
|
+
[
|
|
63435
|
+
"span",
|
|
63436
|
+
{
|
|
63437
|
+
class: "GRAPH_FOLD_COUNT",
|
|
63438
|
+
style: "font-variant-numeric:tabular-nums;"
|
|
63439
|
+
},
|
|
63440
|
+
"–"
|
|
63441
|
+
]
|
|
63442
|
+
]
|
|
63443
|
+
],
|
|
63444
|
+
step_button("GRAPH_FOLD_EXPAND", "yi-chevron-down", "expand one level", "EV_EXPAND_LEVEL")
|
|
63445
|
+
]
|
|
63446
|
+
]];
|
|
63447
|
+
}
|
|
63448
|
+
function refresh_fold_level(gobj) {
|
|
63449
|
+
let priv = gobj.priv;
|
|
63450
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
63451
|
+
if (!$container) return;
|
|
63452
|
+
let $readout = $container.querySelector(".GRAPH_FOLD_LEVEL");
|
|
63453
|
+
if (!$readout) return;
|
|
63454
|
+
let state = priv._legend_state || {};
|
|
63455
|
+
let fold = state.fold || {};
|
|
63456
|
+
let levels = fold.levels > 0 ? fold.levels : 0;
|
|
63457
|
+
let level = fold.level > 0 ? fold.level : 0;
|
|
63458
|
+
let topic = fold.topic || "";
|
|
63459
|
+
let entry = (is_array(state.topics) ? state.topics : []).find((e) => e.topic === topic);
|
|
63460
|
+
let $swatch = $readout.querySelector(".GRAPH_FOLD_SWATCH");
|
|
63461
|
+
$swatch.style.display = topic ? "inline-block" : "none";
|
|
63462
|
+
$swatch.style.background = entry && entry.color || "#94a3b8";
|
|
63463
|
+
$readout.querySelector(".GRAPH_FOLD_TOPIC").textContent = topic;
|
|
63464
|
+
$readout.querySelector(".GRAPH_FOLD_COUNT").textContent = levels ? `${level}/${levels}` : "–";
|
|
63465
|
+
let $collapse = $container.querySelector(".GRAPH_FOLD_COLLAPSE");
|
|
63466
|
+
let $expand = $container.querySelector(".GRAPH_FOLD_EXPAND");
|
|
63467
|
+
if ($collapse) $collapse.disabled = !(levels && level > 1);
|
|
63468
|
+
if ($expand) $expand.disabled = !(levels && level < levels);
|
|
63469
|
+
}
|
|
63289
63470
|
function make_toolbar(gobj) {
|
|
63290
63471
|
let priv = gobj.priv;
|
|
63291
63472
|
let modes = gobj_read_attr(gobj, "operation_modes");
|
|
@@ -63352,7 +63533,7 @@ function make_toolbar(gobj) {
|
|
|
63352
63533
|
} }
|
|
63353
63534
|
]
|
|
63354
63535
|
];
|
|
63355
|
-
let center_items = [...
|
|
63536
|
+
let center_items = [...fold_level_items(gobj, gobj_read_str_attr(gobj, "wide")), ...node_shape_items(gobj, gobj_read_str_attr(gobj, "wide"))];
|
|
63356
63537
|
let backend_items = [[
|
|
63357
63538
|
"button",
|
|
63358
63539
|
{
|
|
@@ -64608,6 +64789,7 @@ function ac_legend_state(gobj, event, kw, src) {
|
|
|
64608
64789
|
let priv = gobj.priv;
|
|
64609
64790
|
priv._legend_state = kw || null;
|
|
64610
64791
|
refresh_legend(gobj);
|
|
64792
|
+
refresh_fold_level(gobj);
|
|
64611
64793
|
return 0;
|
|
64612
64794
|
}
|
|
64613
64795
|
/************************************************************
|
|
@@ -64720,17 +64902,33 @@ function ac_find_nodes(gobj, event, kw, src) {
|
|
|
64720
64902
|
return 0;
|
|
64721
64903
|
}
|
|
64722
64904
|
/************************************************************
|
|
64723
|
-
*
|
|
64724
|
-
*
|
|
64905
|
+
* One press of the fold stepper (EV_EXPAND_LEVEL /
|
|
64906
|
+
* EV_COLLAPSE_LEVEL): the level moves by one, is SAVED (the
|
|
64907
|
+
* reader's, per treedb) and reaches the G6 child, which owns
|
|
64908
|
+
* the tree.
|
|
64909
|
+
*
|
|
64910
|
+
* The readout moves at once, not when the engine speaks again:
|
|
64911
|
+
* a reconcile is asynchronous, and a second press that came
|
|
64912
|
+
* before it would step from the level already left -- two
|
|
64913
|
+
* presses, one level.
|
|
64725
64914
|
************************************************************/
|
|
64726
|
-
function
|
|
64915
|
+
function ac_fold_level_step(gobj, event, kw, src) {
|
|
64727
64916
|
let priv = gobj.priv;
|
|
64728
|
-
|
|
64729
|
-
|
|
64730
|
-
}
|
|
64731
|
-
|
|
64732
|
-
|
|
64733
|
-
|
|
64917
|
+
let fold = priv._legend_state && priv._legend_state.fold;
|
|
64918
|
+
if (!fold || !(fold.levels > 0)) {
|
|
64919
|
+
log_error(`${gobj_short_name(gobj)}: ${event} with no tree to step through`);
|
|
64920
|
+
return -1;
|
|
64921
|
+
}
|
|
64922
|
+
let level = fold.level + (event === "EV_EXPAND_LEVEL" ? 1 : -1);
|
|
64923
|
+
if (level < 1 || level > fold.levels) {
|
|
64924
|
+
log_error(`${gobj_short_name(gobj)}: ${event}: level ${level} out of 1..${fold.levels}`);
|
|
64925
|
+
return -1;
|
|
64926
|
+
}
|
|
64927
|
+
gobj_write_attr(gobj, "fold_level", level);
|
|
64928
|
+
gobj_save_persistent_attrs(gobj, "fold_level");
|
|
64929
|
+
fold.level = level;
|
|
64930
|
+
refresh_fold_level(gobj);
|
|
64931
|
+
if (priv.gobj_nodes_tree) gobj_send_event(priv.gobj_nodes_tree, "EV_SET_FOLD_LEVEL", { level }, gobj);
|
|
64734
64932
|
return 0;
|
|
64735
64933
|
}
|
|
64736
64934
|
/************************************************************
|
|
@@ -64967,13 +65165,13 @@ function create_gclass$3(gclass_name) {
|
|
|
64967
65165
|
null
|
|
64968
65166
|
],
|
|
64969
65167
|
[
|
|
64970
|
-
"
|
|
64971
|
-
|
|
65168
|
+
"EV_EXPAND_LEVEL",
|
|
65169
|
+
ac_fold_level_step,
|
|
64972
65170
|
null
|
|
64973
65171
|
],
|
|
64974
65172
|
[
|
|
64975
|
-
"
|
|
64976
|
-
|
|
65173
|
+
"EV_COLLAPSE_LEVEL",
|
|
65174
|
+
ac_fold_level_step,
|
|
64977
65175
|
null
|
|
64978
65176
|
],
|
|
64979
65177
|
[
|
|
@@ -65058,8 +65256,8 @@ function create_gclass$3(gclass_name) {
|
|
|
65058
65256
|
["EV_SET_OPERATION_MODE", 0],
|
|
65059
65257
|
["EV_SET_FOCUS_TOPIC", 0],
|
|
65060
65258
|
["EV_FIND_NODES", 0],
|
|
65061
|
-
["
|
|
65062
|
-
["
|
|
65259
|
+
["EV_EXPAND_LEVEL", 0],
|
|
65260
|
+
["EV_COLLAPSE_LEVEL", 0],
|
|
65063
65261
|
["EV_SET_NODE_MODE", 0],
|
|
65064
65262
|
["EV_TOGGLE_NODE_LABELS", 0],
|
|
65065
65263
|
["EV_FIND_RESULT", 0],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuneta/gobj-ui",
|
|
3
|
-
"version": "7.23.
|
|
3
|
+
"version": "7.23.141",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/gobj-ui.cjs.js",
|
|
6
6
|
"module": "dist/gobj-ui.es.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"src/",
|
|
21
21
|
"vite-plugin-yuneta-html.js"
|
|
22
22
|
],
|
|
23
|
-
"description": "Yuneta UI Library
|
|
23
|
+
"description": "Yuneta UI Library — the active line: declarative shell (C_YUI_SHELL+NAV+PAGER+WIZARD) + windows, TreeDB views, forms, charts and maps. Consumed by wattyzer and the yunetas JS yunos (gui_agent, gui_treedb). The frozen legacy GClass GUI stack (C_YUI_MAIN/TABS/ROUTING) lives on the v1 branch, npm dist-tag 'legacy' (consumed by estadodelaire and hidraulia).",
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "vite build",
|
|
26
26
|
"test": "vitest run",
|