Handle background color changes.

This commit is contained in:
Davy Hélard
2025-07-28 18:20:23 +02:00
parent 46e0301dd0
commit e0d376c15b
12 changed files with 118 additions and 33 deletions

View File

@@ -298,6 +298,32 @@ namespace gdjs {
);
}
}
} else if (data.command === 'setBackgroundColor') {
if (runtimeGame._inGameEditor) {
const editedInstanceContainer =
runtimeGame._inGameEditor._getEditedInstanceContainer();
if (editedInstanceContainer) {
const backgroundColor = data.payload.backgroundColor;
if (
backgroundColor &&
editedInstanceContainer instanceof gdjs.RuntimeScene
) {
const sceneData = runtimeGame.getSceneData(
editedInstanceContainer.getScene().getName()
);
if (sceneData) {
editedInstanceContainer._backgroundColor = gdjs.rgbToHexNumber(
backgroundColor[0],
backgroundColor[1],
backgroundColor[2]
);
sceneData.r = backgroundColor[0];
sceneData.v = backgroundColor[1];
sceneData.b = backgroundColor[2];
}
}
}
}
} else if (data.command === 'hotReloadAllInstances') {
if (runtimeGame._inGameEditor) {
const editedInstanceContainer =

View File

@@ -630,6 +630,22 @@ namespace gdjs {
return false;
}
/**
* Get the data associated to a scene.
*
* @param name The name of the scene.
* @return The data associated to the scene or null if not found.
*/
getSceneData(sceneName: string): LayoutData | null {
for (let i = 0, len = this._data.layouts.length; i < len; ++i) {
const sceneData = this._data.layouts[i];
if (sceneData.name == sceneName) {
return sceneData;
}
}
return null;
}
/**
* Get the data associated to an external layout.
*

View File

@@ -158,7 +158,7 @@ export const EmbeddedGameFrame = ({
neededHotReload.current = 'DataAndResources';
}
}
console.log("onSetEditorHotReloadNeeded", projectDataOnlyExport);
console.log('onSetEditorHotReloadNeeded', projectDataOnlyExport);
};
onSwitchToSceneEdition = (options: SwitchToSceneEditionOptions) => {
if (!previewDebuggerServer) return;

View File

@@ -39,6 +39,7 @@ type LayersListBodyProps = {|
onEditLayerEffects: (layer: ?gdLayer) => void,
onEdit: (layer: ?gdLayer) => void,
onLayersModified: () => void,
onBackgroundColorChanged: () => void,
width: number,
|};
@@ -66,6 +67,7 @@ const LayersListBody = ({
selectedLayer,
onSelectLayer,
onLayersModified,
onBackgroundColorChanged,
}: LayersListBodyProps) => {
const forceUpdate = useForceUpdate();
const gdevelopTheme = React.useContext(GDevelopThemeContext);
@@ -83,6 +85,15 @@ const LayersListBody = ({
[forceUpdate, onLayersModified, unsavedChanges]
);
const triggerOnBackgroundColorChanged = React.useCallback(
() => {
onBackgroundColorChanged();
if (unsavedChanges) unsavedChanges.triggerUnsavedChanges();
forceUpdate();
},
[forceUpdate, onBackgroundColorChanged, unsavedChanges]
);
const onDropLayer = React.useCallback(
(targetIndex: number) => {
const { current: draggedLayerIndex } = draggedLayerIndexRef;
@@ -202,7 +213,7 @@ const LayersListBody = ({
{layout && (
<BackgroundColorRow
layout={layout}
onBackgroundColorChanged={triggerOnLayersModified}
onBackgroundColorChanged={triggerOnBackgroundColorChanged}
/>
)}
</div>
@@ -228,6 +239,7 @@ type Props = {|
onLayerRenamed: () => void,
onCreateLayer: () => void,
onLayersVisibilityInEditorChanged: () => void,
onBackgroundColorChanged: () => void,
unsavedChanges?: ?UnsavedChanges,
// Preview:
@@ -316,6 +328,7 @@ const LayersList = React.forwardRef<Props, LayersListInterface>(
onLayersModified={props.onLayersModified}
onRemoveLayer={props.onRemoveLayer}
onLayerRenamed={props.onLayerRenamed}
onBackgroundColorChanged={props.onBackgroundColorChanged}
unsavedChanges={props.unsavedChanges}
width={width}
/>

View File

@@ -1453,6 +1453,9 @@ const ProjectManager = React.forwardRef<Props, ProjectManagerInterface>(
onOpenLayoutProperties(null);
}}
resourceManagementProps={resourceManagementProps}
onBackgroundColorChanged={() => {
// TODO This can probably wait the rework of scene properties.
}}
/>
)}
{project && !!editedVariablesLayout && (

View File

@@ -67,6 +67,7 @@ export type SceneEditorsDisplayProps = {|
onLayerRenamed: () => void,
onLayersModified: () => void,
onLayersVisibilityInEditorChanged: () => void,
onBackgroundColorChanged: () => void,
onObjectCreated: gdObject => void,
onObjectsModified: (objects: Array<gdObject>) => void,
onObjectEdited: (

View File

@@ -360,6 +360,7 @@ const MosaicEditorsDisplay = React.forwardRef<
unsavedChanges={props.unsavedChanges}
ref={layersListRef}
hotReloadPreviewButtonProps={props.hotReloadPreviewButtonProps}
onBackgroundColorChanged={props.onBackgroundColorChanged}
/>
),
},

View File

@@ -41,6 +41,7 @@ type Props = {|
onOpenMoreSettings?: ?() => void,
onEditVariables: () => void,
resourceManagementProps: ResourceManagementProps,
onBackgroundColorChanged: () => void,
|};
const ScenePropertiesDialog = ({
@@ -52,6 +53,7 @@ const ScenePropertiesDialog = ({
onOpenMoreSettings,
onEditVariables,
resourceManagementProps,
onBackgroundColorChanged,
}: Props) => {
const [windowTitle, setWindowTitle] = React.useState<string>(
layout.getWindowDefaultTitle()
@@ -98,12 +100,20 @@ const ScenePropertiesDialog = ({
layout.setStopSoundsOnStartup(shouldStopSoundsOnStartup);
layout.setResourcesPreloading(resourcesPreloading);
layout.setResourcesUnloading(resourcesUnloading);
const hasBackgroundColorChanged =
backgroundColor &&
layout.getBackgroundColorRed() !== backgroundColor.r &&
layout.getBackgroundColorGreen() !== backgroundColor.g &&
layout.getBackgroundColorBlue() !== backgroundColor.b;
layout.setBackgroundColor(
backgroundColor ? backgroundColor.r : 0,
backgroundColor ? backgroundColor.g : 0,
backgroundColor ? backgroundColor.b : 0
);
onApply();
if (hasBackgroundColorChanged) {
onBackgroundColorChanged();
}
};
const actions = [

View File

@@ -506,6 +506,7 @@ const SwipeableDrawerEditorsDisplay = React.forwardRef<
hotReloadPreviewButtonProps={
props.hotReloadPreviewButtonProps
}
onBackgroundColorChanged={props.onBackgroundColorChanged}
/>
)}
</SwipeableDrawer>

View File

@@ -1333,43 +1333,13 @@ export default class SceneEditor extends React.Component<Props, State> {
this.forceUpdatePropertiesEditor();
};
_onLayersModified = (hasAnyEffectBeenAdded: boolean) => {
const {
previewDebuggerServer,
layersContainer,
onEffectAdded,
} = this.props;
if (hasAnyEffectBeenAdded) {
// This triggers a full hot-reload. We don't need to reload layers specifically.
onEffectAdded();
} else {
if (this.props.project.areEffectsHiddenInEditor()) {
return;
}
if (previewDebuggerServer) {
previewDebuggerServer.getExistingDebuggerIds().forEach(debuggerId => {
previewDebuggerServer.sendMessage(debuggerId, {
command: 'hotReloadLayers',
payload: {
layers: mapFor(0, layersContainer.getLayersCount(), i => {
const layer = layersContainer.getLayerAt(i);
return serializeToJSObject(layer);
}),
},
});
});
}
}
};
_onLayersVisibilityInEditorChanged = () => {
_sendHotReloadLayers = () => {
const { previewDebuggerServer, layersContainer } = this.props;
if (previewDebuggerServer) {
previewDebuggerServer.getExistingDebuggerIds().forEach(debuggerId => {
previewDebuggerServer.sendMessage(debuggerId, {
command: 'hotReloadLayers',
payload: {
areEffectsHidden: this.props.project.areEffectsHiddenInEditor(),
layers: mapFor(0, layersContainer.getLayersCount(), i => {
const layer = layersContainer.getLayerAt(i);
return serializeToJSObject(layer);
@@ -1380,6 +1350,44 @@ export default class SceneEditor extends React.Component<Props, State> {
}
};
_sendSetBackgroundColor = () => {
const { previewDebuggerServer, layout } = this.props;
if (!layout) {
return;
}
if (previewDebuggerServer) {
previewDebuggerServer.getExistingDebuggerIds().forEach(debuggerId => {
previewDebuggerServer.sendMessage(debuggerId, {
command: 'setBackgroundColor',
payload: {
backgroundColor: [
layout.getBackgroundColorRed(),
layout.getBackgroundColorGreen(),
layout.getBackgroundColorBlue(),
],
},
});
});
}
};
_onLayersModified = (hasAnyEffectBeenAdded: boolean) => {
const { onEffectAdded } = this.props;
if (hasAnyEffectBeenAdded) {
// This triggers a full hot-reload. We don't need to reload layers specifically.
onEffectAdded();
} else {
if (this.props.project.areEffectsHiddenInEditor()) {
return;
}
this._sendHotReloadLayers();
}
};
_onLayersVisibilityInEditorChanged = () => {
this._sendHotReloadLayers();
};
_onSelectLayer = (layerName: string) => {
this.setState({ selectedLayer: layerName });
@@ -2522,6 +2530,7 @@ export default class SceneEditor extends React.Component<Props, State> {
}
onLayerRenamed={this._onLayerRenamed}
onLayersModified={() => this._onLayersModified(false)}
onBackgroundColorChanged={this._sendSetBackgroundColor}
onLayersVisibilityInEditorChanged={
this._onLayersVisibilityInEditorChanged
}
@@ -2831,6 +2840,7 @@ export default class SceneEditor extends React.Component<Props, State> {
onEditVariables={() => this.editLayoutVariables(true)}
onOpenMoreSettings={this.props.onOpenMoreSettings}
resourceManagementProps={this.props.resourceManagementProps}
onBackgroundColorChanged={this._sendSetBackgroundColor}
/>
)}
{this.state.scenePropertiesDialogOpen &&

View File

@@ -41,6 +41,7 @@ export const Default = () => {
layout={testProject.testLayout}
layersContainer={testProject.testLayout.getLayers()}
hotReloadPreviewButtonProps={fakeHotReloadPreviewButtonProps}
onBackgroundColorChanged={action('onBackgroundColorChanged')}
/>
</DragAndDropContextProvider>
);
@@ -72,6 +73,7 @@ export const SmallWidthAndHeight = () => {
layout={testProject.testLayout}
layersContainer={testProject.testLayout.getLayers()}
hotReloadPreviewButtonProps={fakeHotReloadPreviewButtonProps}
onBackgroundColorChanged={action('onBackgroundColorChanged')}
/>
</div>
</DragAndDropContextProvider>

View File

@@ -22,6 +22,7 @@ export const Default = () => (
onApply={() => action('Apply changes')}
onEditVariables={() => action('Edit variables')}
resourceManagementProps={fakeResourceManagementProps}
onBackgroundColorChanged={() => action('onBackgroundColorChanged')}
/>
);
@@ -35,5 +36,6 @@ export const MoreSettings = () => (
onEditVariables={() => action('Edit variables')}
onOpenMoreSettings={() => action('Open more settings')}
resourceManagementProps={fakeResourceManagementProps}
onBackgroundColorChanged={() => action('onBackgroundColorChanged')}
/>
);