From 43ca8c4f5b3fd51f139243c9a77b83560bcbe59b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr>
Date: Tue, 23 Jul 2024 09:15:41 +0200
Subject: [PATCH] [Ivette] Adds Eva status icon in the titlebar of all Eva
 components.

EvaStatus defines a default iconSize for titlebar.

Replace cursor by default cursor
---
 ivette/src/frama-c/plugins/dive/graph.tsx     |  5 ++++-
 ivette/src/frama-c/plugins/dive/tree.tsx      |  6 +++++-
 ivette/src/frama-c/plugins/eva/Coverage.tsx   |  5 ++++-
 .../src/frama-c/plugins/eva/DomainStates.tsx  |  5 ++++-
 ivette/src/frama-c/plugins/eva/Summary.tsx    |  6 ++++--
 .../plugins/eva/components/AnalysisStatus.tsx |  6 +++---
 .../frama-c/plugins/eva/components/Tools.tsx  | 21 -------------------
 ivette/src/frama-c/plugins/eva/style.css      |  5 +++++
 ivette/src/frama-c/plugins/eva/valuetable.tsx |  8 +++----
 9 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/ivette/src/frama-c/plugins/dive/graph.tsx b/ivette/src/frama-c/plugins/dive/graph.tsx
index d2bb8b1e2c5..1b3b7fa1065 100644
--- a/ivette/src/frama-c/plugins/dive/graph.tsx
+++ b/ivette/src/frama-c/plugins/dive/graph.tsx
@@ -47,7 +47,8 @@ import { Space } from 'dome/frame/toolbars';
 
 import '@fortawesome/fontawesome-free/js/all';
 
-import { EvaReady } from 'frama-c/plugins/eva/components/AnalysisStatus';
+import { EvaReady, EvaStatus }
+  from 'frama-c/plugins/eva/components/AnalysisStatus';
 import Legend from './legend';
 import style from './style.json';
 import layouts from './layouts.json';
@@ -745,6 +746,8 @@ export default function GraphComponent(): JSX.Element {
           onClick={() => graph.current?.clear()}
           title="Clear the graph"
         />
+        <Space />
+        <EvaStatus />
       </Ivette.TitleBar>
       <EvaReady>
         <>
diff --git a/ivette/src/frama-c/plugins/dive/tree.tsx b/ivette/src/frama-c/plugins/dive/tree.tsx
index e522cddb910..1761bb0a60a 100644
--- a/ivette/src/frama-c/plugins/dive/tree.tsx
+++ b/ivette/src/frama-c/plugins/dive/tree.tsx
@@ -25,12 +25,14 @@ import React, { useEffect } from 'react';
 import { Icon } from 'dome/controls/icons';
 import { classes } from 'dome/misc/utils';
 import { IconButton } from 'dome/controls/buttons';
+import { Inset } from 'dome/frame/toolbars';
 import * as Ivette from 'ivette';
 
 import * as Server from 'frama-c/server';
 import * as States from 'frama-c/states';
 
-import { EvaReady } from 'frama-c/plugins/eva/components/AnalysisStatus';
+import { EvaReady, EvaStatus }
+  from 'frama-c/plugins/eva/components/AnalysisStatus';
 import * as API from './api';
 import type { marker } from 'frama-c/kernel/api/ast';
 
@@ -233,6 +235,8 @@ export default function TreeComponent(): JSX.Element {
         onClick={() => setRoot(null)}
         title="Clear the graph"
       />
+      <Inset />
+      <EvaStatus />
     </Ivette.TitleBar>
     <EvaReady>
       {
diff --git a/ivette/src/frama-c/plugins/eva/Coverage.tsx b/ivette/src/frama-c/plugins/eva/Coverage.tsx
index 92c6c2050ea..b8e6a693205 100644
--- a/ivette/src/frama-c/plugins/eva/Coverage.tsx
+++ b/ivette/src/frama-c/plugins/eva/Coverage.tsx
@@ -29,6 +29,7 @@ import * as States from 'frama-c/states';
 import * as Eva from 'frama-c/plugins/eva/api/general';
 
 import CoverageMeter, { percent } from './CoverageMeter';
+import { EvaStatus } from './components/AnalysisStatus';
 
 type stats = Eva.functionStatsData;
 
@@ -165,7 +166,9 @@ export function CoverageTable(): JSX.Element {
 export default function CoverageComponent(): JSX.Element {
   return (
     <>
-      <Ivette.TitleBar />
+      <Ivette.TitleBar>
+        <EvaStatus />
+      </Ivette.TitleBar>
       <CoverageTable />
     </>
   );
diff --git a/ivette/src/frama-c/plugins/eva/DomainStates.tsx b/ivette/src/frama-c/plugins/eva/DomainStates.tsx
index bad51ee797c..e1451da587d 100644
--- a/ivette/src/frama-c/plugins/eva/DomainStates.tsx
+++ b/ivette/src/frama-c/plugins/eva/DomainStates.tsx
@@ -31,6 +31,7 @@ import { HSplit } from 'dome/layout/splitters';
 import { Text } from 'frama-c/richtext';
 import { Checkbox, SelectMenu } from 'dome/controls/buttons';
 import { Label } from 'dome/controls/labels';
+import { EvaStatus } from './components/AnalysisStatus';
 
 const globalSelectedDomain = new GlobalState("");
 const globalFilter = new GlobalState(true);
@@ -111,7 +112,9 @@ export function EvaStates(): JSX.Element {
 function EvaStatesComponent(): JSX.Element {
   return (
     <>
-      <Ivette.TitleBar />
+      <Ivette.TitleBar>
+        <EvaStatus />
+      </Ivette.TitleBar>
       <EvaStates />
     </>
   );
diff --git a/ivette/src/frama-c/plugins/eva/Summary.tsx b/ivette/src/frama-c/plugins/eva/Summary.tsx
index 4a29d895d57..f31f0335a9f 100644
--- a/ivette/src/frama-c/plugins/eva/Summary.tsx
+++ b/ivette/src/frama-c/plugins/eva/Summary.tsx
@@ -28,7 +28,7 @@ import * as Eva from 'frama-c/plugins/eva/api/general';
 import CoverageMeter, { percent } from './CoverageMeter';
 
 import './style_summary.css';
-import { EvaReady } from 'frama-c/plugins/eva/components/AnalysisStatus';
+import { EvaReady, EvaStatus } from './components/AnalysisStatus';
 
 function CoverageTable(data: Eva.programStatsType): JSX.Element {
   const { progFunCoverage: functions, progStmtCoverage: statements } = data;
@@ -223,7 +223,9 @@ export function EvaSummary(): JSX.Element {
 function EvaSummaryComponent(): JSX.Element {
   return (
     <>
-      <Ivette.TitleBar />
+      <Ivette.TitleBar>
+        <EvaStatus />
+      </Ivette.TitleBar>
       <EvaReady>
         <EvaSummary />
       </EvaReady>
diff --git a/ivette/src/frama-c/plugins/eva/components/AnalysisStatus.tsx b/ivette/src/frama-c/plugins/eva/components/AnalysisStatus.tsx
index 600c65ca4a1..9d7c1bf0a30 100644
--- a/ivette/src/frama-c/plugins/eva/components/AnalysisStatus.tsx
+++ b/ivette/src/frama-c/plugins/eva/components/AnalysisStatus.tsx
@@ -32,8 +32,8 @@ interface EvaReadyProps {
 }
 
 interface EvaStatusProp {
-  iconSize: number;
-  showStatus?: Eva.computationStateType[];
+  iconSize?: number; // default size for titlebar
+  showStatus?: Eva.computationStateType[]; // all status shown by default
 }
 
 interface StatusIconProp {
@@ -56,7 +56,7 @@ function StatusIcon(props: StatusIconProp):JSX.Element {
 }
 
 export function EvaStatus(props: EvaStatusProp): JSX.Element | null {
-  const { iconSize, showStatus } = props;
+  const { iconSize = 12, showStatus } = props;
   const status = useSyncValue(Eva.computationState);
 
   if(!showStatus || status && showStatus?.includes(status)) {
diff --git a/ivette/src/frama-c/plugins/eva/components/Tools.tsx b/ivette/src/frama-c/plugins/eva/components/Tools.tsx
index f371da2bfa2..01d9340ce68 100644
--- a/ivette/src/frama-c/plugins/eva/components/Tools.tsx
+++ b/ivette/src/frama-c/plugins/eva/components/Tools.tsx
@@ -23,13 +23,11 @@
 import React from 'react';
 import { IconButton } from 'dome/controls/buttons';
 import { Hbox } from 'dome/layout/boxes';
-// import { Icon } from 'dome/controls/icons';
 import * as Forms from 'dome/layout/forms';
 import * as Server from 'frama-c/server';
 import * as States from 'frama-c/states';
 import * as Eva from 'frama-c/plugins/eva/api/general';
 import { EvaStatus } from 'frama-c/plugins/eva/components/AnalysisStatus';
-// import * as EvaReady from 'frama-c/plugins/eva/EvaReady';
 
 
 export interface EvaToolsProps {
@@ -37,25 +35,6 @@ export interface EvaToolsProps {
   iconSize: number;
 }
 
-// function EvaState(
-//   state: Eva.computationStateType | undefined
-// ): JSX.Element {
-//   let id, title;
-//   switch(state) {
-//     case "computed": id="CHECK"; title="Computed"; break;
-//     case "aborted": id="CROSS"; title="Aborted"; break;
-//     case "not_computed": id="CROSS"; title="Not computed"; break;
-//     case "computing": id="SPINNER"; title="Computing"; break;
-//     default: id="CROSS"; title="Status undefined"; break;
-//   }
-//   return <Icon
-//     id={id}
-//     title={title}
-//     className={"eva-status-icon eva-"+state}
-//     size={18}
-//   />;
-// }
-
 export default function EvaTools(
   props: EvaToolsProps
 ): JSX.Element {
diff --git a/ivette/src/frama-c/plugins/eva/style.css b/ivette/src/frama-c/plugins/eva/style.css
index 5096365be5e..41fb3879bf8 100644
--- a/ivette/src/frama-c/plugins/eva/style.css
+++ b/ivette/src/frama-c/plugins/eva/style.css
@@ -500,6 +500,11 @@ tr:first-of-type > .eva-table-callsite-box {
   max-width: 90%;
   max-height: 200px;
   fill: var(--info-text-discrete);
+  cursor: default;
+}
+
+.labview-titlebar .dome-xIcon.eva-status-icon {
+  cursor: default;
 }
 
 .eva-status-computing {
diff --git a/ivette/src/frama-c/plugins/eva/valuetable.tsx b/ivette/src/frama-c/plugins/eva/valuetable.tsx
index bbe4235bead..ce863e2b538 100644
--- a/ivette/src/frama-c/plugins/eva/valuetable.tsx
+++ b/ivette/src/frama-c/plugins/eva/valuetable.tsx
@@ -32,10 +32,7 @@ import * as Server from 'frama-c/server';
 import * as Ast from 'frama-c/kernel/api/ast';
 import * as Eva from 'frama-c/plugins/eva/api/general';
 import * as Values from 'frama-c/plugins/eva/api/values';
-import {
-  EvaReady,
-  EvaStatus
-} from 'frama-c/plugins/eva/components/AnalysisStatus';
+import { EvaReady, EvaStatus } from './components/AnalysisStatus';
 
 import { classes } from 'dome/misc/utils';
 import { Icon } from 'dome/controls/icons';
@@ -1141,13 +1138,14 @@ function EvaTable(): JSX.Element {
   return (
     <>
       <Ivette.TitleBar>
-        <EvaStatus iconSize={12} showStatus={["computed", "aborted"]}/>
         <IconButton
           icon="ITEMS.LIST"
           title="Show values by callstack by default"
           selected={showCallstacks}
           onClick={flipCallstacks}
         />
+        <Inset />
+        <EvaStatus />
       </Ivette.TitleBar>
       <EvaReady>
         <div className="eva-functions-section">
-- 
GitLab