Fix history not working well on the Events Sheet

* Fix changes not being detected for history when editing an event Inline
* Fix losing focus when switching tabs
This commit is contained in:
Clément Pasteau
2022-05-06 12:15:31 +02:00
committed by GitHub
parent 5d35241c4c
commit 0dd10d2fce
9 changed files with 52 additions and 43 deletions

View File

@@ -803,6 +803,7 @@ export default class EventsFunctionsExtensionEditor extends React.Component<
onCreateEventsFunction={this.onCreateEventsFunction}
onOpenSettings={this._editOptions}
unsavedChanges={this.props.unsavedChanges}
isActive={true}
/>
</Background>
) : (

View File

@@ -122,6 +122,7 @@ type Props = {|
) => void,
onBeginCreateEventsFunction: () => void,
unsavedChanges?: ?UnsavedChanges,
isActive: boolean,
|};
type ComponentProps = {|
@@ -154,7 +155,6 @@ type State = {|
inlineEditing: boolean,
inlineEditingAnchorEl: ?HTMLElement,
inlineInstructionEditorAnchorEl: ?HTMLElement,
inlineEditingChangesMade: boolean,
inlineEditingPreviousValue: ?string,
analyzedEventsContextResult: ?EventsContextResult,
@@ -243,7 +243,6 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
inlineEditing: false,
inlineEditingAnchorEl: null,
inlineInstructionEditorAnchorEl: null,
inlineEditingChangesMade: false,
inlineEditingPreviousValue: null,
analyzedEventsContextResult: null,
@@ -284,6 +283,12 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
if (this.state.history !== prevState.history)
if (this.props.unsavedChanges)
this.props.unsavedChanges.triggerUnsavedChanges();
// If the tab becomes active again, we ensure the dom is focused
// allowing the keyboard shortcuts to work.
if (!prevProps.isActive && this.props.isActive) {
this._ensureFocused();
}
}
updateToolbar() {
@@ -805,22 +810,29 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
inlineEditingAnchorEl: parameterContext.domEvent
? parameterContext.domEvent.currentTarget
: null,
inlineEditingChangesMade: false,
inlineEditingPreviousValue: instruction.getParameter(parameterIndex),
});
};
closeParameterEditor = (shouldCancel: boolean) => {
if (shouldCancel) {
const { instruction, parameterIndex } = this.state.editedParameter;
if (!instruction || !this.state.inlineEditingPreviousValue) return;
instruction.setParameter(
parameterIndex,
this.state.inlineEditingPreviousValue
);
} else {
if (this.state.inlineEditingChangesMade) {
const { instruction, parameterIndex } = this.state.editedParameter;
if (instruction) {
// If the user canceled, revert the value to the previous value, if not null.
if (
shouldCancel &&
typeof this.state.inlineEditingPreviousValue === 'string'
) {
instruction.setParameter(
parameterIndex,
this.state.inlineEditingPreviousValue
);
}
// If the user made changes, save the value to history.
if (
!shouldCancel &&
this.state.inlineEditingPreviousValue !==
instruction.getParameter(parameterIndex)
) {
this._saveChangesToHistory();
}
}
@@ -831,7 +843,6 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
{
inlineEditing: false,
inlineEditingAnchorEl: null,
inlineEditingChangesMade: false,
},
() => {
if (inlineEditingAnchorEl) {
@@ -1462,9 +1473,10 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
return;
}
instruction.setParameter(parameterIndex, value);
this.setState({
inlineEditingChangesMade: true,
});
// Ask the component to re-render, so that the new parameter
// set for the instruction in the state
// is taken into account for the InlineParameterEditor.
this.forceUpdate();
if (this._searchPanel)
this._searchPanel.markSearchResultsDirty();
}}

View File

@@ -11,9 +11,10 @@ export class EventsEditorContainer extends React.Component<RenderEditorContainer
editor: ?EventsSheetInterface;
shouldComponentUpdate(nextProps: RenderEditorContainerProps) {
// Prevent any update to the editor if the editor is not active,
// and so not visible to the user.
return nextProps.isActive;
// We stop updates when the component is inactive.
// If it's active, was active or becoming active again we let update propagate.
// Especially important to note that when becoming inactive, a "last" update is allowed.
return this.props.isActive || nextProps.isActive;
}
componentDidMount() {
@@ -97,6 +98,7 @@ export class EventsEditorContainer extends React.Component<RenderEditorContainer
objectsContainer={layout}
events={layout.getEvents()}
onOpenExternalEvents={this.props.onOpenExternalEvents}
isActive={this.props.isActive}
/>
);
}

View File

@@ -33,13 +33,10 @@ export class EventsFunctionsExtensionEditorContainer extends React.Component<Ren
}
shouldComponentUpdate(nextProps: RenderEditorContainerProps) {
// This optimization is a bit more cautious than the traditional one,
// to still be notified when isActive goes from true to false.
if (!this.props.isActive && !nextProps.isActive) {
return false;
}
return true;
// We stop updates when the component is inactive.
// If it's active, was active or becoming active again we let update propagate.
// Especially important to note that when becoming inactive, a "last" update is allowed.
return this.props.isActive || nextProps.isActive;
}
componentDidUpdate(prevProps: *) {

View File

@@ -37,9 +37,10 @@ export class ExternalEventsEditorContainer extends React.Component<
};
shouldComponentUpdate(nextProps: RenderEditorContainerProps) {
// Prevent any update to the editor if the editor is not active,
// and so not visible to the user.
return nextProps.isActive;
// We stop updates when the component is inactive.
// If it's active, was active or becoming active again we let update propagate.
// Especially important to note that when becoming inactive, a "last" update is allowed.
return this.props.isActive || nextProps.isActive;
}
getProject(): ?gdProject {
@@ -157,6 +158,7 @@ export class ExternalEventsEditorContainer extends React.Component<
events={externalEvents.getEvents()}
onOpenSettings={this.openExternalPropertiesDialog}
onOpenExternalEvents={this.props.onOpenExternalEvents}
isActive={this.props.isActive}
/>
)}
{!layout && (

View File

@@ -49,11 +49,7 @@ export class ExternalLayoutEditorContainer extends React.Component<
// children, and in particular SceneEditor and InstancesEditor, to be notified when isActive
// goes from true to false (in which case PIXI rendering is halted). If isActive was false
// and remains false, it's safe to stop update here (PIXI rendering is already halted).
if (!this.props.isActive && !nextProps.isActive) {
return false;
}
return true;
return this.props.isActive || nextProps.isActive;
}
componentDidMount() {

View File

@@ -10,9 +10,10 @@ export class ResourcesEditorContainer extends React.Component<RenderEditorContai
editor: ?ResourcesEditor;
shouldComponentUpdate(nextProps: RenderEditorContainerProps) {
// Prevent any update to the editor if the editor is not active,
// and so not visible to the user.
return nextProps.isActive;
// We stop updates when the component is inactive.
// If it's active, was active or becoming active again we let update propagate.
// Especially important to note that when becoming inactive, a "last" update is allowed.
return this.props.isActive || nextProps.isActive;
}
getProject(): ?gdProject {

View File

@@ -23,11 +23,7 @@ export class SceneEditorContainer extends React.Component<RenderEditorContainerP
// children, and in particular SceneEditor and InstancesEditor, to be notified when isActive
// goes from true to false (in which case PIXI rendering is halted). If isActive was false
// and remains false, it's safe to stop update here (PIXI rendering is already halted).
if (!this.props.isActive && !nextProps.isActive) {
return false;
}
return true;
return this.props.isActive || nextProps.isActive;
}
componentDidMount() {

View File

@@ -2735,6 +2735,7 @@ storiesOf('EventsSheet', module)
openInstructionOrExpression={action('open instruction or expression')}
onCreateEventsFunction={action('create events function')}
onBeginCreateEventsFunction={action('begin create events function')}
isActive={true}
/>
</FixedHeightFlexContainer>
</DragAndDropContextProvider>
@@ -2760,6 +2761,7 @@ storiesOf('EventsSheet', module)
openInstructionOrExpression={action('open instruction or expression')}
onCreateEventsFunction={action('create events function')}
onBeginCreateEventsFunction={action('begin create events function')}
isActive={true}
/>
</FixedHeightFlexContainer>
</DragAndDropContextProvider>