@@ -79824,9 +79824,14 @@ class JSRootMenu {
7982479824 * @param {string} [kind] - use 'text' (default), 'number', 'float' or 'int'
7982579825 * @protected */
7982679826 async input(title, value, kind, min, max) {
79827+ let onchange = null;
79828+ if (isFunc(kind)) {
79829+ onchange = kind;
79830+ kind = '';
79831+ }
7982779832 if (!kind)
7982879833 kind = 'text';
79829- const inp_type = (kind === 'int') ? 'number' : 'text';
79834+ const inp_type = (kind === 'int') ? 'number' : 'text', value0 = value ;
7983079835 let ranges = '';
7983179836 if ((value === undefined) || (value === null))
7983279837 value = '';
@@ -79839,24 +79844,33 @@ class JSRootMenu {
7983979844
7984079845 const main_content =
7984179846 '<form><fieldset style="padding:0; border:0">' +
79842- `<input type="${inp_type}" value="${value}" ${ranges} style="width:98%;display:block" class="jsroot_dlginp"/>` +
79843- '</fieldset></form>';
79847+ `<input type="${inp_type}" value="${value}" ${ranges} style="width:98%;display:block" class="jsroot_dlginp"/>` +
79848+ '</fieldset></form>', oninit = !onchange ? null : elem => {
79849+ const inp = elem.querySelector('.jsroot_dlginp');
79850+ if (inp)
79851+ inp.oninput = () => onchange(inp.value);
79852+ };
7984479853
7984579854 return new Promise(resolveFunc => {
79846- this.runModal(title, main_content, { btns: true, height: 150, width: 400 }).then(element => {
79847- if (!element)
79855+ this.runModal(title, main_content, { btns: true, height: 150, width: 400, oninit }).then(element => {
79856+ if (!element) {
79857+ if (onchange)
79858+ onchange(value0);
7984879859 return;
79849- let val = element.querySelector('.jsroot_dlginp').value;
79860+ }
79861+ let val = element.querySelector('.jsroot_dlginp').value, isok = true;
7985079862 if (kind === 'float') {
7985179863 val = Number.parseFloat(val);
79852- if (Number.isFinite(val))
79853- resolveFunc(val);
79864+ isok = Number.isFinite(val);
7985479865 } else if (kind === 'int') {
7985579866 val = parseInt(val);
79856- if (Number.isInteger(val))
79857- resolveFunc(val);
79858- } else
79867+ isok = Number.isInteger(val);
79868+ }
79869+ if (isok) {
79870+ if (onchange)
79871+ onchange(val);
7985979872 resolveFunc(val);
79873+ }
7986079874 });
7986179875 });
7986279876 }
@@ -80393,6 +80407,8 @@ class StandaloneMenu extends JSRootMenu {
8039380407 f = modal.element.select('.jsroot_dialog_footer').select('button');
8039480408 if (!f.empty())
8039580409 f.node().focus();
80410+ if (isFunc(args.oninit))
80411+ args.oninit(modal.element.node());
8039680412 return modal;
8039780413 }
8039880414
@@ -164688,6 +164704,8 @@ class HierarchyPainter extends BasePainter {
164688164704 #one_by_one; // process drop items one by one
164689164705 #topname; // top item name
164690164706 #cached_draw_object; // cached object for first draw
164707+ #draw_func; // alternative draw function
164708+ #redraw_func; // alternative redraw function
164691164709
164692164710 /** @summary Create painter
164693164711 * @param {string} name - symbolic name
@@ -164718,6 +164736,23 @@ class HierarchyPainter extends BasePainter {
164718164736 this.textcolor = settings.DarkMode ? '#eee' : '#111';
164719164737 }
164720164738
164739+ /** @summary Set alternative draw/redraw functions
164740+ * @desc If only only draw function specified - it also will be used for re-drawing
164741+ * @protected */
164742+ setDrawFunc(_draw, _redraw) {
164743+ if (isFunc(_draw)) {
164744+ this.#draw_func = _draw;
164745+ this.#redraw_func = isFunc(_redraw) ? _redraw : _draw;
164746+ }
164747+ }
164748+
164749+ /** @summary Invoke configured draw or redraw function
164750+ * @protected */
164751+ async callDrawFunc(dom, obj, opt, doredraw) {
164752+ const func = doredraw ? (this.#redraw_func || redraw) : (this.#draw_func || draw);
164753+ return func(dom, obj, opt);
164754+ }
164755+
164721164756 /** @summary Cleanup hierarchy painter
164722164757 * @desc clear drawing and browser */
164723164758 cleanup() {
@@ -165281,6 +165316,9 @@ class HierarchyPainter extends BasePainter {
165281165316 if (!element_title)
165282165317 element_title = element_name;
165283165318
165319+ if (hitem._filter)
165320+ element_name += ' *';
165321+
165284165322 d3a.attr('title', element_title)
165285165323 .text(element_name + ('_value' in hitem ? ':' : ''))
165286165324 .style('background', hitem._background ? hitem._background : null);
@@ -165300,6 +165338,8 @@ class HierarchyPainter extends BasePainter {
165300165338 for (let i = 0; i < hitem._childs.length; ++i) {
165301165339 const chld = hitem._childs[i];
165302165340 chld._parent = hitem;
165341+ if (hitem._filter && chld._name && chld._name.indexOf(hitem._filter) < 0)
165342+ continue;
165303165343 if (!this.addItemHtml(chld, d3chlds, i))
165304165344 break; // if too many items, skip rest
165305165345 }
@@ -165963,6 +166003,15 @@ class HierarchyPainter extends BasePainter {
165963166003 if (hitem._childs === undefined)
165964166004 menu.add('Expand', () => this.expandItem(itemname), 'Expand content of object');
165965166005 else {
166006+ if (sett.handle?.pm && hitem._childs.length) {
166007+ menu.add('Filter...', () => menu.input('Enter items to select', hitem._filter, f => {
166008+ const changed = hitem._filter !== f;
166009+ hitem._filter = f;
166010+ if (changed)
166011+ this.updateTreeNode(hitem);
166012+ }), 'Filter out items based on input pattern');
166013+ }
166014+
165966166015 menu.add('Unexpand', () => {
165967166016 hitem._more = true;
165968166017 delete hitem._childs;
@@ -166140,10 +166189,8 @@ class HierarchyPainter extends BasePainter {
166140166189 if (use_dflt_opt && !drawopt && handle?.dflt && (handle.dflt !== kExpand))
166141166190 drawopt = handle.dflt;
166142166191
166143- if (dom) {
166144- const func = updating ? redraw : draw;
166145- return func(dom, obj, drawopt).then(p => complete(p)).catch(err => complete(null, err));
166146- }
166192+ if (dom)
166193+ return this.callDrawFunc(dom, obj, drawopt, updating).then(p => complete(p)).catch(err => complete(null, err));
166147166194
166148166195 let did_activate = false;
166149166196 const arr = [];
@@ -166187,9 +166234,9 @@ class HierarchyPainter extends BasePainter {
166187166234 cleanup(frame);
166188166235 mdi.activateFrame(frame);
166189166236
166190- return draw (frame, obj, drawopt)
166191- .then(p => complete(p))
166192- .catch(err => complete(null, err));
166237+ return this.callDrawFunc (frame, obj, drawopt)
166238+ .then(p => complete(p))
166239+ .catch(err => complete(null, err));
166193166240 });
166194166241 });
166195166242 }
@@ -166295,7 +166342,7 @@ class HierarchyPainter extends BasePainter {
166295166342 if (isFunc(dom?.addPadButtons))
166296166343 dom.addPadButtons();
166297166344
166298- return draw (dom, res.obj, opt).then(p => drop_complete(p, mp === p));
166345+ return this.callDrawFunc (dom, res.obj, opt).then(p => drop_complete(p, mp === p));
166299166346 });
166300166347 }
166301166348
@@ -167462,7 +167509,7 @@ class HierarchyPainter extends BasePainter {
167462167509 }
167463167510
167464167511 // check that we can found frame where drawing should be done
167465- if (!document.getElementById(this.disp_frameid))
167512+ if (!this.disp_frameid || ! document.getElementById(this.disp_frameid))
167466167513 return null;
167467167514
167468167515 if (isBatchMode())
0 commit comments