@yuneta/gobj-ui 7.23.18 → 7.23.20
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/dist/gobj-ui.cjs.js +819 -380
- package/dist/gobj-ui.es.js +811 -372
- package/package.json +1 -1
- package/src/c_g6_nodes_tree.js +135 -3
- package/src/c_yui_gobj_tree_js.js +185 -7
- package/src/c_yui_json_graph.js +269 -24
- package/src/json_view_helpers.js +67 -0
- package/src/json_view_helpers.test.js +67 -0
- package/src/lib_icons.js +7 -0
- package/src/yui_graph_camera.js +95 -0
package/src/yui_graph_camera.js
CHANGED
|
@@ -39,6 +39,8 @@ import {createElement2, gobj_send_event} from "@yuneta/gobj-js";
|
|
|
39
39
|
|
|
40
40
|
import {t} from "i18next";
|
|
41
41
|
|
|
42
|
+
import {set_pressed_state} from "./lib_graph.js";
|
|
43
|
+
|
|
42
44
|
|
|
43
45
|
/************************************************************
|
|
44
46
|
* One icon button that fires `event_name`.
|
|
@@ -141,6 +143,99 @@ export function yui_graph_fold_items(gobj, wide)
|
|
|
141
143
|
];
|
|
142
144
|
}
|
|
143
145
|
|
|
146
|
+
/************************************************************
|
|
147
|
+
* The ANCHOR toggle: pick one element and every camera move
|
|
148
|
+
* from then on leaves it in the MIDDLE.
|
|
149
|
+
*
|
|
150
|
+
* Why it exists: a graph that fits on screen is unreadable at
|
|
151
|
+
* the zoom that makes it fit, and the zoom that makes it
|
|
152
|
+
* readable does not fit -- so the useful view is always a
|
|
153
|
+
* fraction of the document, and which fraction is the whole
|
|
154
|
+
* question. Without an anchor, `1:1` lands wherever the
|
|
155
|
+
* layout's origin happens to be and the reader hunts for the
|
|
156
|
+
* node they were looking at.
|
|
157
|
+
*
|
|
158
|
+
* Crosshairs and not a thumbtack. A tack says "do not move
|
|
159
|
+
* this", which is what a pinned NODE would mean in a graph you
|
|
160
|
+
* can drag nodes around in; this pins the CAMERA to a target,
|
|
161
|
+
* which is what a crosshair says and what every map that
|
|
162
|
+
* offers it draws. It is also in the icon set already, and a
|
|
163
|
+
* `yi-*` class that is not is a black square.
|
|
164
|
+
*
|
|
165
|
+
* Three states, because two would not say what a press does:
|
|
166
|
+
*
|
|
167
|
+
* off no target; the camera behaves as it always did
|
|
168
|
+
* arming waiting for you to click the element you mean
|
|
169
|
+
* on locked; every zoom re-centres on it
|
|
170
|
+
************************************************************/
|
|
171
|
+
export function yui_graph_anchor_item(gobj, wide)
|
|
172
|
+
{
|
|
173
|
+
return camera_button(gobj, "yi-location-crosshairs", "EV_TOGGLE_ANCHOR",
|
|
174
|
+
"anchor view", wide);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/************************************************************
|
|
178
|
+
* Paint the anchor button. `state` is "off" | "arming" | "on".
|
|
179
|
+
*
|
|
180
|
+
* Both live states look PRESSED, because both are states the
|
|
181
|
+
* control is IN rather than actions; what separates them is the
|
|
182
|
+
* colour, and only the waiting one takes a palette colour --
|
|
183
|
+
* it is the one that needs the reader to do something next.
|
|
184
|
+
************************************************************/
|
|
185
|
+
export function yui_graph_update_anchor($container, state)
|
|
186
|
+
{
|
|
187
|
+
if(!$container) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
let $btn = $container.querySelector('.EV_TOGGLE_ANCHOR');
|
|
191
|
+
if(!$btn) {
|
|
192
|
+
return; /* a toolbar without the control: nothing to paint */
|
|
193
|
+
}
|
|
194
|
+
set_pressed_state($container, '.EV_TOGGLE_ANCHOR', state !== "off");
|
|
195
|
+
$btn.classList.toggle('color_pending_state', state === "arming");
|
|
196
|
+
$btn.setAttribute("aria-pressed", (state === "on")? "true": "false");
|
|
197
|
+
|
|
198
|
+
let key = (state === "arming")? "click the element to centre on"
|
|
199
|
+
: (state === "on")? "centred: click to release"
|
|
200
|
+
: "anchor view";
|
|
201
|
+
$btn.setAttribute("title", t(key));
|
|
202
|
+
$btn.setAttribute("data-i18n-title", key);
|
|
203
|
+
$btn.setAttribute("aria-label", t(key));
|
|
204
|
+
$btn.setAttribute("data-i18n-aria-label", key);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/************************************************************
|
|
208
|
+
* Put `node_id` back in the middle of the viewport.
|
|
209
|
+
*
|
|
210
|
+
* Called AFTER the camera moved, never instead of moving it:
|
|
211
|
+
* the zoom is what the reader asked for, the centring is what
|
|
212
|
+
* keeps the thing they are reading under their eyes.
|
|
213
|
+
*
|
|
214
|
+
* Guarded on every side because it runs on every wheel notch:
|
|
215
|
+
* a graph mid-rebuild, an anchor whose node went away with a
|
|
216
|
+
* fold, a G6 version without `focusElement` -- none of those is
|
|
217
|
+
* an error worth a log line per notch, they are all "there is
|
|
218
|
+
* nothing to centre right now".
|
|
219
|
+
************************************************************/
|
|
220
|
+
export function yui_graph_center_on(graph, node_id)
|
|
221
|
+
{
|
|
222
|
+
if(!graph || !node_id) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
if(typeof graph.getElementData === "function" && !graph.getElementData(node_id)) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
if(typeof graph.focusElement !== "function") {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
graph.focusElement(node_id);
|
|
233
|
+
return true;
|
|
234
|
+
} catch(e) {
|
|
235
|
+
return false; /* the element is gone, or the graph is between renders */
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
144
239
|
/************************************************************
|
|
145
240
|
* A refresh button, for the graphs that offer one.
|
|
146
241
|
************************************************************/
|