From 59fc1d83d904b8ae8ac50e8b7bac80874f8cdfca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Wed, 28 Feb 2024 12:11:17 +0100 Subject: [PATCH] [ivette/lab] favorite tabs --- ivette/src/renderer/Laboratory.tsx | 99 +++++++++++++++++++----------- 1 file changed, 62 insertions(+), 37 deletions(-) diff --git a/ivette/src/renderer/Laboratory.tsx b/ivette/src/renderer/Laboratory.tsx index bd77d7a8282..6ef86087ccc 100644 --- a/ivette/src/renderer/Laboratory.tsx +++ b/ivette/src/renderer/Laboratory.tsx @@ -47,7 +47,7 @@ interface Scroll { H: number, V: number } interface Layout { A: compId, B: compId, C: compId, D: compId } interface TabViewState { - view: viewId, + viewId: viewId, custom: number, /* -1: transient, 0: favorite, n: custom */ scroll: Scroll, layout: Layout, @@ -182,7 +182,7 @@ function getLayoutPosition( function findTab(tabs: TabViewState[], viewId: viewId) : number { - return tabs.findIndex(({ view, custom }) => view === viewId && custom <= 0); + return tabs.findIndex(tab => tab.viewId === viewId && tab.custom <= 0); } /* @@ -201,7 +201,7 @@ function newTab( ): TabViewState[] { return tabs.concat({ - view: view.id, custom, + viewId: view.id, custom, scroll: defaultScroll, layout: makeViewLayout(view.layout) }); @@ -219,6 +219,16 @@ function saveTab( } } +function addPanels(panels: Set<compId>, layout: Layout): Set<compId> +{ + const { A, B, C, D } = layout; + if ( panels.has(A) && panels.has(B) && panels.has(C) && panels.has(D) ) + return panels; + else + return copySet(panels).add(A).add(B).add(C).add(D); + +} + /* -------------------------------------------------------------------------- */ /* --- LabView Actions --- */ /* -------------------------------------------------------------------------- */ @@ -252,14 +262,18 @@ function applyTab(index = -1): void { if (old === index) return; const tab = state.tabs[index]; if (tab === undefined) return; - const { view, layout, scroll } = tab; + const { viewId, layout, scroll } = tab; const tabs = [...state.tabs]; saveTab(tabs, state); + const panels = addPanels(state.panels, layout); LAB.setValue({ ...state, + panels, + layout, + scroll, + tabs, tabIndex: index, - tabs, layout, scroll, - sideView: view, + sideView: viewId, sideComp: '', }); } @@ -272,12 +286,7 @@ function applyView(view: Ivette.ViewLayoutProps): void { applyTab(index); } else { const layout = makeViewLayout(view.layout); - const panels = - copySet(state.panels) - .add(layout.A) - .add(layout.B) - .add(layout.C) - .add(layout.D); + const panels = addPanels(state.panels, layout); const tabs = newTab(state.tabs, view, -1); const tabIndex = tabs.length - 1; saveTab(tabs, state); @@ -285,13 +294,29 @@ function applyView(view: Ivette.ViewLayoutProps): void { panels, layout, scroll: state.scroll, docked: state.docked, - tabs, tabIndex, + tabs, + tabIndex, sideView: view.id, sideComp: '', }); } } +function applyFavorite(view: Ivette.ViewLayoutProps, favorite: boolean): void { + const state = LAB.getValue(); + const index = findTab(state.tabs, view.id); + if (0 <= index) { + const tabs = [...state.tabs]; + const tab = tabs[index]; + const custom = favorite ? 0 : -1; + tabs[index] = { ...tab, custom }; + LAB.setValue({ ...state, tabs, sideView: view.id, sideComp: '' }); + } else if (favorite) { + const tabs = newTab(state.tabs, view, 0); + LAB.setValue({ ...state, tabs, sideView: view.id, sideComp: '' }); + } +} + function applyComponent( comp: Ivette.ComponentProps, at?: LayoutPosition @@ -576,21 +601,22 @@ function ViewItem(props: ViewItemProps): JSX.Element { const icon = favorite ? 'FAVORITE' : 'DISPLAY'; const modified = - (scroll !== undefined && !compareScroll(scroll, defaultScroll)) || - (layout !== undefined && !compareLayout(layout, makeViewLayout(view.layout))); - - console.log('MODIFIED', id, displayed, scroll, - scroll !== undefined && compareScroll(scroll, defaultScroll)); + (scroll !== undefined && + !compareScroll(scroll, defaultScroll)) || + (layout !== undefined && + !compareLayout(layout, makeViewLayout(view.layout))); const label = modified ? vname + '*' : vname; - const title = modified ? vtitle + ' (modified)' : vtitle; - - const onDisplay = (): void => applyView(view); + const title = modified ? (vtitle ?? vname) + ' (modified)' : vtitle; const onContextMenu = (): void => { setCurrentView(id); + const onDisplay = (): void => applyView(view); + const onFavorite = (): void => applyFavorite(view, !favorite); + const favAction = !favorite ? 'Add to Favorite' : 'Remove from Favorite'; Dome.popupMenu([ { label: 'Display View', enabled: !displayed, onClick: onDisplay }, + { label: favAction, onClick: onFavorite }, { label: 'Duplicate View' }, { label: 'Restore Default', enabled: modified }, ]); @@ -842,18 +868,17 @@ export function Dock(): JSX.Element { interface TabViewProps { tab: TabViewState; index: number; - selection: number; + tabIndex: number; layout: Layout; scroll: Scroll; } function TabView(props: TabViewProps): JSX.Element | null { - const { tab, index, selection } = props; - const { view: id, custom } = tab; - const view = Ext.useElement(VIEW, id); - if (!view) return null; - const selected = index === selection; - if (custom < 0 && !selected) return null; + const { tab, index, tabIndex } = props; + const { viewId, custom } = tab; + const view = Ext.useElement(VIEW, viewId); + if (!view || custom < 0) return null; + const selected = index === tabIndex; const layout = selected ? props.layout : tab.layout; const scroll = selected ? props.scroll : tab.scroll; const modified = @@ -862,10 +887,10 @@ function TabView(props: TabViewProps): JSX.Element | null { const vname = view.label; const tname = custom > 0 ? `${vname} — ${custom}` : vname; const label = modified ? `${tname}*` : tname; - const tdup = custom > 0 ? 'Custom ' : custom === 0 ? 'Favorite ' : ''; + const tdup = custom > 0 ? 'Custom ' : ''; const tmod = modified ? ' (modified)': ''; const title = tdup + vname + tmod; - const icon = custom < 0 ? 'DISPLAY' : 'FAVORITE'; + const icon = selected ? 'FAVORITE' : 'STAR'; return ( <Toolbar.Button className='labview-tab' @@ -873,22 +898,22 @@ function TabView(props: TabViewProps): JSX.Element | null { label={label} title={title} value={index} - selection={selection} + selection={tabIndex} onClick={applyTab} /> ); } export function Tabs(): JSX.Element { - const [{ tabs, tabIndex, layout, scroll }] = States.useGlobalState(LAB); - const items = tabs.map((tab, k) => ( + const [state] = States.useGlobalState(LAB); + const items = state.tabs.map((tab, k) => ( <TabView - key={tab.view} + key={tab.viewId} tab={tab} index={k} - selection={tabIndex} - layout={layout} - scroll={scroll} + tabIndex={state.tabIndex} + layout={state.layout} + scroll={state.scroll} /> )); return <>{items}</>; -- GitLab