diff --git a/ivette/src/ivette/display.tsx b/ivette/src/ivette/display.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e5b3cb3744e0e634ac33646c8436309f40145000 --- /dev/null +++ b/ivette/src/ivette/display.tsx @@ -0,0 +1,85 @@ +/* ************************************************************************ */ +/* */ +/* This file is part of Frama-C. */ +/* */ +/* Copyright (C) 2007-2023 */ +/* CEA (Commissariat à l'énergie atomique et aux énergies */ +/* alternatives) */ +/* */ +/* you can redistribute it and/or modify it under the terms of the GNU */ +/* Lesser General Public License as published by the Free Software */ +/* Foundation, version 2.1. */ +/* */ +/* It is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Lesser General Public License for more details. */ +/* */ +/* See the GNU Lesser General Public License version 2.1 */ +/* for more details (enclosed in the file licenses/LGPLv2.1). */ +/* */ +/* ************************************************************************ */ + +/* --------------------------------------------------------------------------*/ +/* --- Display Interaction ---*/ +/* --------------------------------------------------------------------------*/ + +/** + @packageDocumentation + @module ivette/display + */ + +import React from 'react'; +import { VIEW, COMPONENT } from 'ivette'; +import * as State from './state'; +import * as Laboratory from './laboratory'; + +export interface ItemProps { + id: string; + selected?: boolean; +} + +/** + A sidebar item for controlling an Ivette view. + */ +export function ViemItem(props: ItemProps): JSX.Element | null { + const { id, selected=false } = props; + const view = State.useElement(VIEW,id); + const state = Laboratory.useState(); + if (!view) return null; + const status = Laboratory.getViewStatus(state, id); + return ( + <Laboratory.ViewItem + view={view} + selected={selected} + {...status} + /> + ); +} + +/** + A sidebar item for controlling an Ivette component. + */ +export function ComponentItem(props: ItemProps): JSX.Element | null { + const { id, selected=false } = props; + const comp = State.useElement(COMPONENT,id); + const state = Laboratory.useState(); + if (!comp) return null; + const status = Laboratory.getComponentStatus(state, id); + return ( + <Laboratory.ComponentItem + comp={comp} + selected={selected} + {...status} + /> + ); +} + +/** + A bundle of sidebar items for controlling an Ivette group of components. + */ +export function GroupSection(props: ItemProps): JSX.Element | null { + return <>{props.id}</>; +} + +/* --------------------------------------------------------------------------*/ diff --git a/ivette/src/renderer/Laboratory.tsx b/ivette/src/ivette/laboratory.tsx similarity index 96% rename from ivette/src/renderer/Laboratory.tsx rename to ivette/src/ivette/laboratory.tsx index b14654ec66cce24318cdb1dfc0ca563f7492ff58..9515e8c2561b5d83e774d5927728d95e2a430abf 100644 --- a/ivette/src/renderer/Laboratory.tsx +++ b/ivette/src/ivette/laboratory.tsx @@ -620,6 +620,52 @@ Settings.onWindowSettings(() => { } }); +/* -------------------------------------------------------------------------- */ +/* --- Exported API --- */ +/* -------------------------------------------------------------------------- */ + +export function useState(): LabViewState +{ + const [state] = States.useGlobalState(LAB); + return state; +} + +export interface ViewStatus { + favorite: boolean; + displayed: boolean; + layout: Layout; +} + +export function getViewStatus( + state: LabViewState, + viewId: viewId +): ViewStatus +{ + const tab = state.tabs.get(viewId); + const favorite = tab ? tab.custom === 0 : false; + const displayed = tab ? tab.key === state.tabKey : false; + const layout = displayed ? state.stack[0] : tab?.stack[0]; + return { favorite, displayed, layout: layout ?? defaultLayout }; +} + +export interface ComponentStatus { + active: boolean; + docked: boolean; + position: Ivette.LayoutPosition | undefined; +} + +export function getComponentStatus( + state: LabViewState, + compId: compId +): ComponentStatus +{ + const layout = state.stack[0] ?? defaultLayout; + const position= getLayoutPosition(layout, compId); + const active = state.panels.has(compId); + const docked = state.docked.has(compId); + return { position, active, docked }; +} + /* -------------------------------------------------------------------------- */ /* --- Layout Menu State --- */ /* -------------------------------------------------------------------------- */ @@ -873,7 +919,7 @@ interface ViewItemProps { layout: Layout | undefined; } -function ViewItem(props: ViewItemProps): JSX.Element { +export function ViewItem(props: ViewItemProps): JSX.Element { const { view, favorite, displayed, selected, layout } = props; const { id, label: vname, title: vtitle } = view; @@ -960,7 +1006,7 @@ interface ComponentItemProps { docked: boolean; } -function ComponentItem(props: ComponentItemProps): JSX.Element { +export function ComponentItem(props: ComponentItemProps): JSX.Element { const { comp, position, selected, active, docked } = props; const { id, label, title = label } = comp; const icon = diff --git a/ivette/src/renderer/Application.tsx b/ivette/src/renderer/Application.tsx index 7a6c3d7b47af58642e433c8b50abebcc0735370f..b5348cb9f56144783d8d2841bd4f61a64443aba4 100644 --- a/ivette/src/renderer/Application.tsx +++ b/ivette/src/renderer/Application.tsx @@ -33,10 +33,10 @@ import { LSplit } from 'dome/layout/splitters'; import * as Toolbar from 'dome/frame/toolbars'; import * as Sidebar from './Sidebar'; import * as Controller from './Controller'; -import * as Lab from './Laboratory'; +import { TOOLBAR, STATUSBAR } from 'ivette'; import * as State from 'ivette/state'; import * as Search from 'ivette/search'; -import { TOOLBAR, STATUSBAR } from 'ivette'; +import * as Laboratory from 'ivette/laboratory'; import * as IvettePrefs from 'ivette/prefs'; import './loader'; import './sandbox'; @@ -67,7 +67,7 @@ export default function Application(): JSX.Element { <Controller.Control /> <>{ToolBar}</> <Toolbar.Filler /> - <Lab.Tabs /> + <Laboratory.Tabs /> <Toolbar.Filler /> <IvettePrefs.ThemeSwitchTool /> <IvettePrefs.FontTools /> @@ -81,13 +81,13 @@ export default function Application(): JSX.Element { </Toolbar.ToolBar> <LSplit settings="frama-c.sidebar.split" unfold={sidebar}> <Sidebar.Panel /> - <Lab.LabView /> + <Laboratory.LabView /> </LSplit> <Toolbar.ToolBar className="statusbar"> <Controller.Status /> <>{StatusBar}</> <Toolbar.Filler /> - <Lab.Dock /> + <Laboratory.Dock /> </Toolbar.ToolBar> </Vfill> );