mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Refactor editor tabs management in EditorsPane and MainFrame
Co-authored-by: florian <florian@gdevelop.io>
This commit is contained in:
@@ -15,6 +15,12 @@ import {
|
||||
type EditorTabsState,
|
||||
type EditorTab,
|
||||
hasEditorTabOpenedWithKey,
|
||||
changeCurrentTab,
|
||||
closeEditorTab,
|
||||
closeOtherEditorTabs,
|
||||
closeAllEditorTabs,
|
||||
moveTabToTheRightOfHoveredTab,
|
||||
saveUiSettings,
|
||||
} from './EditorTabs/EditorTabsHandler';
|
||||
import type { PreviewState } from './PreviewState';
|
||||
import type {
|
||||
@@ -49,17 +55,6 @@ type Props = {|
|
||||
|
||||
// Callbacks from MainFrame
|
||||
toggleProjectManager: () => void,
|
||||
onChangeEditorTab: (id: number) => void,
|
||||
onCloseEditorTab: (editorTab: EditorTab) => void,
|
||||
onCloseOtherEditorTabs: (editorTab: EditorTab) => void,
|
||||
onCloseAllEditorTabs: () => void,
|
||||
onEditorTabActivated: (editorTab: EditorTab) => void,
|
||||
onDropEditorTab: (
|
||||
draggedEditorTab: EditorTab,
|
||||
targetEditorTab: EditorTab
|
||||
) => void,
|
||||
updateToolbar: () => void,
|
||||
setEditorToolbar: (toolbar: any, isCurrentTab: boolean) => void,
|
||||
saveProject: () => Promise<void>,
|
||||
openShareDialog: (tab?: string) => void,
|
||||
launchDebuggerAndPreview: () => void,
|
||||
@@ -121,6 +116,7 @@ type Props = {|
|
||||
onExtensionInstalled: any,
|
||||
gamesList: GamesList,
|
||||
inAppTutorialOrchestratorRef: {| current: ?InAppTutorialOrchestrator |},
|
||||
setEditorTabs: (editorTabs: EditorTabsState) => void,
|
||||
|};
|
||||
|
||||
const EditorsPane = React.forwardRef<Props, ToolbarInterface>((props, ref) => {
|
||||
@@ -139,14 +135,6 @@ const EditorsPane = React.forwardRef<Props, ToolbarInterface>((props, ref) => {
|
||||
canDoNetworkPreview,
|
||||
gamesPlatformFrameTools,
|
||||
toggleProjectManager,
|
||||
onChangeEditorTab,
|
||||
onCloseEditorTab,
|
||||
onCloseOtherEditorTabs,
|
||||
onCloseAllEditorTabs,
|
||||
onEditorTabActivated,
|
||||
onDropEditorTab,
|
||||
updateToolbar,
|
||||
setEditorToolbar,
|
||||
saveProject,
|
||||
openShareDialog,
|
||||
launchDebuggerAndPreview,
|
||||
@@ -204,11 +192,74 @@ const EditorsPane = React.forwardRef<Props, ToolbarInterface>((props, ref) => {
|
||||
onExtensionInstalled,
|
||||
gamesList,
|
||||
inAppTutorialOrchestratorRef,
|
||||
setEditorTabs,
|
||||
} = props;
|
||||
|
||||
const toolbarRef = React.useRef<?ToolbarInterface>(null);
|
||||
const unsavedChanges = React.useContext(UnsavedChangesContext);
|
||||
const hasAskAiOpened = hasEditorTabOpenedWithKey(editorTabs, 'ask-ai');
|
||||
|
||||
// Internal editor toolbar management
|
||||
const setEditorToolbar = React.useCallback((editorToolbar: any, isCurrentTab: boolean = true) => {
|
||||
if (!toolbarRef.current || !isCurrentTab) return;
|
||||
|
||||
toolbarRef.current.setEditorToolbar(editorToolbar);
|
||||
}, []);
|
||||
|
||||
const updateToolbar = React.useCallback(() => {
|
||||
const editorTab = getCurrentTab(editorTabs);
|
||||
if (!editorTab || !editorTab.editorRef) {
|
||||
setEditorToolbar(null);
|
||||
return;
|
||||
}
|
||||
|
||||
editorTab.editorRef.updateToolbar();
|
||||
}, [editorTabs, setEditorToolbar]);
|
||||
|
||||
React.useEffect(() => {
|
||||
updateToolbar();
|
||||
}, [updateToolbar]);
|
||||
|
||||
// Tab management functions
|
||||
const _onEditorTabActivated = React.useCallback((editorTab: EditorTab) => {
|
||||
updateToolbar();
|
||||
// Ensure the editors shown on the screen are updated. This is for
|
||||
// example useful if global objects have been updated in another editor.
|
||||
if (editorTab.editorRef) {
|
||||
editorTab.editorRef.forceUpdateEditor();
|
||||
}
|
||||
}, [updateToolbar]);
|
||||
|
||||
const _onChangeEditorTab = React.useCallback((value: number) => {
|
||||
const newEditorTabs = changeCurrentTab(editorTabs, value);
|
||||
setEditorTabs(newEditorTabs);
|
||||
_onEditorTabActivated(getCurrentTab(newEditorTabs));
|
||||
}, [editorTabs, setEditorTabs, _onEditorTabActivated]);
|
||||
|
||||
const _onCloseEditorTab = React.useCallback((editorTab: EditorTab) => {
|
||||
saveUiSettings(editorTabs);
|
||||
setEditorTabs(closeEditorTab(editorTabs, editorTab));
|
||||
}, [editorTabs, setEditorTabs]);
|
||||
|
||||
const _onCloseOtherEditorTabs = React.useCallback((editorTab: EditorTab) => {
|
||||
saveUiSettings(editorTabs);
|
||||
setEditorTabs(closeOtherEditorTabs(editorTabs, editorTab));
|
||||
}, [editorTabs, setEditorTabs]);
|
||||
|
||||
const _onCloseAllEditorTabs = React.useCallback(() => {
|
||||
saveUiSettings(editorTabs);
|
||||
setEditorTabs(closeAllEditorTabs(editorTabs));
|
||||
}, [editorTabs, setEditorTabs]);
|
||||
|
||||
const onDropEditorTab = React.useCallback((fromIndex: number, toHoveredIndex: number) => {
|
||||
setEditorTabs(moveTabToTheRightOfHoveredTab(editorTabs, fromIndex, toHoveredIndex));
|
||||
}, [editorTabs, setEditorTabs]);
|
||||
|
||||
// Expose toolbar interface methods
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
setEditorToolbar,
|
||||
}), [setEditorToolbar]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TabsTitlebar
|
||||
@@ -218,24 +269,24 @@ const EditorsPane = React.forwardRef<Props, ToolbarInterface>((props, ref) => {
|
||||
<DraggableEditorTabs
|
||||
hideLabels={false}
|
||||
editorTabs={editorTabs}
|
||||
onClickTab={(id: number) => onChangeEditorTab(id)}
|
||||
onClickTab={(id: number) => _onChangeEditorTab(id)}
|
||||
onCloseTab={(editorTab: EditorTab) => {
|
||||
// Call onEditorTabClosing before to ensure any tooltip is removed before the tab is closed.
|
||||
onEditorTabClosing();
|
||||
onCloseEditorTab(editorTab);
|
||||
_onCloseEditorTab(editorTab);
|
||||
}}
|
||||
onCloseOtherTabs={(editorTab: EditorTab) => {
|
||||
// Call onEditorTabClosing before to ensure any tooltip is removed before the tab is closed.
|
||||
onEditorTabClosing();
|
||||
onCloseOtherEditorTabs(editorTab);
|
||||
_onCloseOtherEditorTabs(editorTab);
|
||||
}}
|
||||
onCloseAll={() => {
|
||||
// Call onEditorTabClosing before to ensure any tooltip is removed before the tab is closed.
|
||||
onEditorTabClosing();
|
||||
onCloseAllEditorTabs();
|
||||
_onCloseAllEditorTabs();
|
||||
}}
|
||||
onTabActivated={(editorTab: EditorTab) =>
|
||||
onEditorTabActivated(editorTab)
|
||||
_onEditorTabActivated(editorTab)
|
||||
}
|
||||
onDropTab={onDropEditorTab}
|
||||
onHoverTab={(
|
||||
@@ -248,7 +299,7 @@ const EditorsPane = React.forwardRef<Props, ToolbarInterface>((props, ref) => {
|
||||
onOpenAskAi={openAskAi}
|
||||
/>
|
||||
<Toolbar
|
||||
ref={ref}
|
||||
ref={toolbarRef}
|
||||
hidden={tabsTitleBarAndEditorToolbarHidden}
|
||||
showProjectButtons={
|
||||
!['start page', 'debugger', 'ask-ai', null].includes(
|
||||
|
@@ -27,10 +27,6 @@ import EditorsPane from './EditorsPane';
|
||||
import {
|
||||
getEditorTabsInitialState,
|
||||
openEditorTab,
|
||||
closeEditorTab,
|
||||
closeOtherEditorTabs,
|
||||
closeAllEditorTabs,
|
||||
changeCurrentTab,
|
||||
getEditors,
|
||||
getCurrentTabIndex,
|
||||
getCurrentTab,
|
||||
@@ -47,7 +43,6 @@ import {
|
||||
type EditorKind,
|
||||
getEventsFunctionsExtensionEditor,
|
||||
notifyPreviewOrExportWillStart,
|
||||
moveTabToTheRightOfHoveredTab,
|
||||
getCustomObjectEditor,
|
||||
hasEditorTabOpenedWithKey,
|
||||
getOpenedAskAiEditor,
|
||||
@@ -773,25 +768,7 @@ const MainFrame = (props: Props) => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateToolbar = React.useCallback(
|
||||
(newEditorTabs = state.editorTabs) => {
|
||||
const editorTab = getCurrentTab(newEditorTabs);
|
||||
if (!editorTab || !editorTab.editorRef) {
|
||||
setEditorToolbar(null);
|
||||
return;
|
||||
}
|
||||
|
||||
editorTab.editorRef.updateToolbar();
|
||||
},
|
||||
[state.editorTabs]
|
||||
);
|
||||
|
||||
React.useEffect(
|
||||
() => {
|
||||
updateToolbar();
|
||||
},
|
||||
[updateToolbar]
|
||||
);
|
||||
|
||||
const _languageDidChange = () => {
|
||||
// A change in the language will automatically be applied
|
||||
@@ -1290,12 +1267,6 @@ const MainFrame = (props: Props) => {
|
||||
[openProjectManager]
|
||||
);
|
||||
|
||||
const setEditorToolbar = (editorToolbar: any, isCurrentTab = true) => {
|
||||
if (!editorsPaneRef.current || !isCurrentTab) return;
|
||||
|
||||
editorsPaneRef.current.setEditorToolbar(editorToolbar);
|
||||
};
|
||||
|
||||
const deleteLayout = (layout: gdLayout) => {
|
||||
const { currentProject } = state;
|
||||
const { i18n } = props;
|
||||
@@ -3249,61 +3220,7 @@ const MainFrame = (props: Props) => {
|
||||
[currentProject, hasUnsavedChanges, i18n, closeProject]
|
||||
);
|
||||
|
||||
const _onChangeEditorTab = (value: number) => {
|
||||
setState(state => ({
|
||||
...state,
|
||||
editorTabs: changeCurrentTab(state.editorTabs, value),
|
||||
})).then(state =>
|
||||
_onEditorTabActivated(getCurrentTab(state.editorTabs), state)
|
||||
);
|
||||
};
|
||||
|
||||
const _onEditorTabActivated = (
|
||||
editorTab: EditorTab,
|
||||
newState: State = state
|
||||
) => {
|
||||
updateToolbar(newState.editorTabs);
|
||||
// Ensure the editors shown on the screen are updated. This is for
|
||||
// example useful if global objects have been updated in another editor.
|
||||
if (editorTab.editorRef) {
|
||||
editorTab.editorRef.forceUpdateEditor();
|
||||
}
|
||||
};
|
||||
|
||||
const _onCloseEditorTab = (editorTab: EditorTab) => {
|
||||
saveUiSettings(state.editorTabs);
|
||||
setState(state => ({
|
||||
...state,
|
||||
editorTabs: closeEditorTab(state.editorTabs, editorTab),
|
||||
}));
|
||||
};
|
||||
|
||||
const _onCloseOtherEditorTabs = (editorTab: EditorTab) => {
|
||||
saveUiSettings(state.editorTabs);
|
||||
setState(state => ({
|
||||
...state,
|
||||
editorTabs: closeOtherEditorTabs(state.editorTabs, editorTab),
|
||||
}));
|
||||
};
|
||||
|
||||
const _onCloseAllEditorTabs = () => {
|
||||
saveUiSettings(state.editorTabs);
|
||||
setState(state => ({
|
||||
...state,
|
||||
editorTabs: closeAllEditorTabs(state.editorTabs),
|
||||
}));
|
||||
};
|
||||
|
||||
const onDropEditorTab = (fromIndex: number, toHoveredIndex: number) => {
|
||||
setState(state => ({
|
||||
...state,
|
||||
editorTabs: moveTabToTheRightOfHoveredTab(
|
||||
state.editorTabs,
|
||||
fromIndex,
|
||||
toHoveredIndex
|
||||
),
|
||||
}));
|
||||
};
|
||||
|
||||
const endTutorial = React.useCallback(
|
||||
async (shouldCloseProject?: boolean) => {
|
||||
@@ -3932,14 +3849,7 @@ const MainFrame = (props: Props) => {
|
||||
}
|
||||
gamesPlatformFrameTools={gamesPlatformFrameTools}
|
||||
toggleProjectManager={toggleProjectManager}
|
||||
onChangeEditorTab={_onChangeEditorTab}
|
||||
onCloseEditorTab={_onCloseEditorTab}
|
||||
onCloseOtherEditorTabs={_onCloseOtherEditorTabs}
|
||||
onCloseAllEditorTabs={_onCloseAllEditorTabs}
|
||||
onEditorTabActivated={_onEditorTabActivated}
|
||||
onDropEditorTab={onDropEditorTab}
|
||||
updateToolbar={updateToolbar}
|
||||
setEditorToolbar={setEditorToolbar}
|
||||
setEditorTabs={setEditorTabs}
|
||||
saveProject={saveProject}
|
||||
openShareDialog={openShareDialog}
|
||||
launchDebuggerAndPreview={launchDebuggerAndPreview}
|
||||
|
Reference in New Issue
Block a user