From 2b7252e4548be504e243dc58c7ed78d5c916c7f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 23 Feb 2022 14:24:59 +0100 Subject: [PATCH] [ivette] hooks on hovered selection --- ivette/src/dome/renderer/text/editors.tsx | 5 +++++ ivette/src/frama-c/kernel/ASTview.tsx | 15 ++++++++++++++- ivette/src/frama-c/states.ts | 9 ++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ivette/src/dome/renderer/text/editors.tsx b/ivette/src/dome/renderer/text/editors.tsx index 43df5396e92..464a5e9922d 100644 --- a/ivette/src/dome/renderer/text/editors.tsx +++ b/ivette/src/dome/renderer/text/editors.tsx @@ -72,6 +72,9 @@ export interface TextProps extends CodeMirror.EditorConfiguration { /** The currently selected marker identifier. */ selection?: string; + /** Callback on hovered marker, if some. */ + onHover?: (id?: string) => void; + /** Callback on identified marker selection. */ onSelection?: MarkerCallback; @@ -311,6 +314,8 @@ class CodeMirrorWrapper extends React.Component<TextProps> { if (newMarker && newMarker.hover) this._markElementsWith(newMarker.classNameId, CSS_HOVERED); this.marker = newMarker; + const callback = this.props.onHover; + if (callback) callback(newMarker?.id); } } diff --git a/ivette/src/frama-c/kernel/ASTview.tsx b/ivette/src/frama-c/kernel/ASTview.tsx index e98cb526378..d54fb085d2f 100644 --- a/ivette/src/frama-c/kernel/ASTview.tsx +++ b/ivette/src/frama-c/kernel/ASTview.tsx @@ -161,9 +161,12 @@ export default function ASTview() { const buffer = React.useMemo(() => new RichTextBuffer(), []); const printed = React.useRef<string | undefined>(); const [selection, updateSelection] = States.useSelection(); + const [hoveredLoc] = States.useHovered(); + const selfhover = React.useRef(false); const multipleSelections = selection?.multiple.allSelections; const theFunction = selection?.current?.fct; const theMarker = selection?.current?.marker; + const hovered = hoveredLoc?.marker; const [fontSize] = Settings.useGlobalSettings(Preferences.EditorFontSize); const markersInfo = States.useSyncArray(Ast.markerInfo); @@ -220,16 +223,25 @@ export default function ASTview() { return 'dead-code'; if (deadCode?.nonTerminating?.some((m) => m === marker)) return 'non-terminating'; + if (!selfhover.current && marker === hovered) + return 'hovered-marker'; return undefined; }; buffer.setDecorator(decorator); - }, [buffer, multipleSelections, deadCode]); + }, [buffer, multipleSelections, selfhover, hovered, deadCode]); // Hook: marker scrolling React.useEffect(() => { if (theMarker) buffer.scroll(theMarker); }, [buffer, theMarker]); + function onHover(markerId?: string) { + const marker = Ast.jMarker(markerId); + const fct = selection?.current?.fct; + selfhover.current = (marker !== undefined); + States.setHovered(marker ? { fct, marker } : undefined); + } + function onSelection(markerId: string, meta = false) { const fct = selection?.current?.fct; const location = { fct, marker: Ast.jMarker(markerId) }; @@ -303,6 +315,7 @@ export default function ASTview() { mode="text/x-csrc" fontSize={fontSize} selection={theMarker} + onHover={onHover} onSelection={onSelection} onContextMenu={onContextMenu} gutters={['bullet']} diff --git a/ivette/src/frama-c/states.ts b/ivette/src/frama-c/states.ts index ff7b0310ffc..11b59f05e8a 100644 --- a/ivette/src/frama-c/states.ts +++ b/ivette/src/frama-c/states.ts @@ -188,7 +188,7 @@ export function useRequest<In, Out>( } }); - const signals = options.onSignals ?? rq.signals; + const signals = rq.signals.concat(options.onSignals ?? []); React.useEffect(() => { signals.forEach((s) => Server.onSignal(s, trigger)); return () => { @@ -767,11 +767,18 @@ const emptySelection = { }, }; +export type Hovered = Location | undefined; export const MetaSelection = new Dome.Event<Location>('frama-c-meta-selection'); +export const GlobalHovered = new GlobalState<Hovered>(undefined); export const GlobalSelection = new GlobalState<Selection>(emptySelection); Server.onShutdown(() => GlobalSelection.setValue(emptySelection)); +export function setHovered(h: Hovered) { GlobalHovered.setValue(h); } +export function useHovered(): [Hovered, (h: Hovered) => void] { + return useGlobalState(GlobalHovered); +} + export function setSelection(location: Location, meta = false) { const s = GlobalSelection.getValue(); GlobalSelection.setValue(reducer(s, { location })); -- GitLab