From ae868325d9e722a41e57f2fe7b6b678262c489c6 Mon Sep 17 00:00:00 2001 From: Valentin Perrelle <valentin.perrelle@cea.fr> Date: Fri, 24 Jul 2020 13:48:22 +0200 Subject: [PATCH] [ivette] Dive: improves selection logic --- ivette/src/frama-c/dive/Dive.tsx | 84 ++++++++++++++------------------ 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/ivette/src/frama-c/dive/Dive.tsx b/ivette/src/frama-c/dive/Dive.tsx index be7a51322ab..18ab59f9bf2 100644 --- a/ivette/src/frama-c/dive/Dive.tsx +++ b/ivette/src/frama-c/dive/Dive.tsx @@ -103,7 +103,7 @@ class Dive { const data = ele.data(); const commands = [{ content: renderToString(ctxmenu.explore), - select: () => this.explore(ele), + select: () => { this.explore(ele); }, enabled: true, }]; if (data.kind === 'composite') { @@ -414,13 +414,13 @@ class Dive { async add(marker: string) { const node = await this.exec(API.add, marker); if (node) - this.selectNode(node); + this.updateNodeSelection(node); } - explore(node: Cytoscape.NodeSingular): void { + async explore(node: Cytoscape.NodeSingular) { const id = parseInt(node.id(), 10); if (id) - this.exec(API.explore, id); + await this.exec(API.explore, id); } show(node: Cytoscape.NodeSingular): void { @@ -435,12 +435,12 @@ class Dive { this.exec(API.hide, id); } - clickNode(node: Cytoscape.NodeSingular): void { - this.selectNode(node); - this.explore(node); + async clickNode(node: Cytoscape.NodeSingular) { + this.updateNodeSelection(node); + await this.explore(node); const writes = node.data()?.writes; - if (writes) + if (writes && writes.length) this.onSelect?.(writes); /* Cytoscape automatically selects the node clicked, and unselects all other @@ -449,18 +449,21 @@ class Dive { node.unselectify(); } - selectLocation(location: States.Location) { - const selectNode = this.cy.$('node:selected'); - const writes = selectNode?.data()?.writes; - if (location.marker && !_.some(writes, location)) { - this.add(location.marker); - } - else { - this.selectNode(selectNode); // Update selection + selectLocation(location: States.Location, doExplore: boolean) { + if (location !== this.selectedLocation) { + this.selectedLocation = location; + const selectNode = this.cy.$('node:selected'); + const writes = selectNode?.data()?.writes; + if (doExplore && location.marker && !_.some(writes, location)) { + this.add(location.marker); + } + else { + this.updateNodeSelection(selectNode); + } } } - selectNode(node: Cytoscape.NodeSingular): void { + updateNodeSelection(node: Cytoscape.NodeSingular): void { const hasOrigin = (ele: Cytoscape.NodeSingular) => ( _.some(ele.data().origins, this.selectedLocation) ); @@ -468,7 +471,11 @@ class Dive { select(node); const edges = node.incomers('edge'); edges.unselect(); - edges.filter(hasOrigin).select(); + const relevantEdges = edges.filter(hasOrigin); + if (relevantEdges.empty()) + edges.select(); + else + relevantEdges.select(); } } @@ -495,40 +502,21 @@ const GraphView = () => { dive.mode = selectionMode === 'follow' ? 'explore' : 'overview'; }, [dive, selectionMode]); - /* When clicking on a node, select its writes locations as a multiple - selection. If these locations were already selected, select the next - location in the multiple selection. */ useEffect(() => { + /* When clicking on a node, select its writes locations as a multiple + selection. If these locations were already selected, select the next + location in the multiple selection. */ dive.onSelect = (locations) => { - if (updateSelection) { - if (_.isEqual(locations, selection?.multiple?.allSelections)) { - updateSelection('MULTIPLE_CYCLE'); - } - else { - updateSelection({ - locations, - index: 0, - }); - } - } + if (_.isEqual(locations, selection?.multiple?.allSelections)) + updateSelection('MULTIPLE_CYCLE'); + else + updateSelection({ locations, index: 0 }); }; - }, [dive, selection, updateSelection]); - useEffect(() => { - const index = selection?.multiple?.index; - const allSelections = selection?.multiple?.allSelections; - if (allSelections && 0 <= index && index < allSelections.length) { - const selected = allSelections[index]; - dive.selectedLocation = selected; - } - }, [dive, selection]); - - // Updates the graph according to the selected marker. - useEffect(() => { - if (!lock && selection?.current) { - dive.selectLocation(selection?.current); - } - }, [dive, lock, selection, selectionMode]); + // Updates the graph according to the selected marker. + if (selection?.current) + dive.selectLocation(selection?.current, !lock); + }, [dive, lock, selection, updateSelection]); // Layout selection const selectLayout = (layout?: string) => { -- GitLab