mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
9 Commits
v5.4.217
...
rename-obj
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4c5f624b34 | ||
![]() |
0928247ee1 | ||
![]() |
2ae7b1a862 | ||
![]() |
00e664ef52 | ||
![]() |
ed8e272740 | ||
![]() |
84e9373f7e | ||
![]() |
d31e816790 | ||
![]() |
9b26c82597 | ||
![]() |
0054324df8 |
@@ -237,7 +237,7 @@ const commandsList: { [CommandName]: CommandMetadata } = {
|
||||
},
|
||||
RENAME_SCENE_OBJECT: {
|
||||
area: 'SCENE',
|
||||
displayText: t`Rename the selected object`,
|
||||
displayText: t`Rename the selected object or group`,
|
||||
},
|
||||
DELETE_INSTANCES: {
|
||||
area: 'SCENE',
|
||||
|
@@ -27,12 +27,13 @@ const styles = {
|
||||
type Props = {|
|
||||
...InstancesEditorPropsWithoutSizeAndScroll,
|
||||
wrappedEditorRef: ?(?InstancesEditor) => void,
|
||||
onEditorActive?: () => void,
|
||||
|};
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
const FullSizeInstancesEditorWithScrollbars = (props: Props) => {
|
||||
const { wrappedEditorRef, ...otherProps } = props;
|
||||
const { wrappedEditorRef, onEditorActive, ...otherProps } = props;
|
||||
|
||||
const editorRef = React.useRef<?InstancesEditor>(null);
|
||||
const xScrollbarTrack = React.useRef<?HTMLDivElement>(null);
|
||||
@@ -361,7 +362,7 @@ const FullSizeInstancesEditorWithScrollbars = (props: Props) => {
|
||||
return (
|
||||
<FullSizeMeasurer>
|
||||
{({ width, height }) => (
|
||||
<div style={styles.container}>
|
||||
<div style={styles.container} onClick={onEditorActive}>
|
||||
{width !== undefined && height !== undefined && (
|
||||
<InstancesEditor
|
||||
onViewPositionChanged={
|
||||
|
@@ -32,6 +32,7 @@ type Props = {|
|
||||
unsavedChanges?: ?UnsavedChanges,
|
||||
i18n: I18nType,
|
||||
historyHandler?: HistoryHandler,
|
||||
onEditorActive?: () => void,
|
||||
|};
|
||||
|
||||
export default class InstancePropertiesEditor extends React.Component<Props> {
|
||||
@@ -238,7 +239,7 @@ export default class InstancePropertiesEditor extends React.Component<Props> {
|
||||
const { instances } = this.props;
|
||||
|
||||
return (
|
||||
<Background>
|
||||
<Background onClick={this.props.onEditorActive}>
|
||||
{!instances || !instances.length
|
||||
? this._renderEmpty()
|
||||
: this._renderInstancesProperties()}
|
||||
|
@@ -26,6 +26,7 @@ type Props = {|
|
||||
instances: gdInitialInstancesContainer,
|
||||
selectedInstances: Array<gdInitialInstance>,
|
||||
onSelectInstances: (Array<gdInitialInstance>, boolean) => void,
|
||||
onEditorActive?: () => void,
|
||||
|};
|
||||
|
||||
type RenderedRowInfo = {
|
||||
@@ -223,7 +224,7 @@ export default class InstancesList extends Component<Props, State> {
|
||||
return (
|
||||
<ThemeConsumer>
|
||||
{muiTheme => (
|
||||
<div style={styles.container}>
|
||||
<div style={styles.container} onClick={this.props.onEditorActive}>
|
||||
<div
|
||||
style={{ flex: 1 }}
|
||||
onKeyDown={this._keyboardShortcuts.onKeyDown}
|
||||
|
@@ -175,6 +175,7 @@ type Props = {|
|
||||
|
||||
// Preview:
|
||||
hotReloadPreviewButtonProps: HotReloadPreviewButtonProps,
|
||||
onEditorActive?: () => void,
|
||||
|};
|
||||
|
||||
export type LayersListInterface = {
|
||||
@@ -234,7 +235,7 @@ const LayersList = React.forwardRef<Props, LayersListInterface>(
|
||||
const isLightingLayerPresent = hasLightingLayer(props.layersContainer);
|
||||
|
||||
return (
|
||||
<Background>
|
||||
<Background onClick={props.onEditorActive}>
|
||||
<ScrollView autoHideScrollbar>
|
||||
<FullSizeMeasurer>
|
||||
{({ width }) => (
|
||||
|
@@ -25,6 +25,11 @@ import {
|
||||
serializeToJSObject,
|
||||
unserializeFromJSObject,
|
||||
} from '../Utils/Serializer';
|
||||
import { getShortcutDisplayName } from '../KeyboardShortcuts';
|
||||
import PreferencesContext, {
|
||||
type PreferencesValues,
|
||||
} from '../MainFrame/Preferences/PreferencesContext';
|
||||
import defaultShortcuts from '../KeyboardShortcuts/DefaultShortcuts';
|
||||
|
||||
export const groupWithContextReactDndType = 'GD_GROUP_WITH_CONTEXT';
|
||||
|
||||
@@ -61,9 +66,10 @@ type Props = {|
|
||||
onGroupRenamed?: () => void,
|
||||
canSetAsGlobalGroup?: boolean,
|
||||
unsavedChanges?: ?UnsavedChanges,
|
||||
onEditorActive?: () => void,
|
||||
|};
|
||||
|
||||
export default class GroupsListContainer extends React.Component<Props, State> {
|
||||
export default class ObjectGroupsList extends React.Component<Props, State> {
|
||||
static defaultProps = {
|
||||
onDeleteGroup: (groupWithContext: GroupWithContext, cb: Function) =>
|
||||
cb(true),
|
||||
@@ -328,7 +334,7 @@ export default class GroupsListContainer extends React.Component<Props, State> {
|
||||
if (this.sortableList) this.sortableList.forceUpdateGrid();
|
||||
};
|
||||
|
||||
_renderGroupMenuTemplate = (i18n: I18nType) => (
|
||||
_renderGroupMenuTemplate = (i18n: I18nType, values: PreferencesValues) => (
|
||||
groupWithContext: GroupWithContext,
|
||||
index: number
|
||||
) => [
|
||||
@@ -345,6 +351,10 @@ export default class GroupsListContainer extends React.Component<Props, State> {
|
||||
{
|
||||
label: i18n._(t`Rename`),
|
||||
click: () => this._onEditName(groupWithContext),
|
||||
accelerator: getShortcutDisplayName(
|
||||
values.userShortcutMap['RENAME_SCENE_OBJECT'] ||
|
||||
defaultShortcuts.RENAME_SCENE_OBJECT
|
||||
),
|
||||
},
|
||||
{
|
||||
label: i18n._(t`Set as global group`),
|
||||
@@ -363,6 +373,12 @@ export default class GroupsListContainer extends React.Component<Props, State> {
|
||||
},
|
||||
];
|
||||
|
||||
startEditingSelectedGroup = () => {
|
||||
if (this.state.selectedGroupWithContext) {
|
||||
this._onEditName(this.state.selectedGroupWithContext);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { globalObjectGroups, objectGroups } = this.props;
|
||||
const { searchText } = this.state;
|
||||
@@ -399,59 +415,73 @@ export default class GroupsListContainer extends React.Component<Props, State> {
|
||||
: null;
|
||||
|
||||
return (
|
||||
<Background>
|
||||
<div style={styles.listContainer}>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<SortableVirtualizedItemList
|
||||
key={listKey}
|
||||
ref={sortableList => (this.sortableList = sortableList)}
|
||||
fullList={fullList}
|
||||
width={width}
|
||||
height={height}
|
||||
getItemName={getGroupWithContextName}
|
||||
getItemId={(groupWithContext, index) => {
|
||||
return 'group-item-' + index;
|
||||
}}
|
||||
isItemBold={isGroupWithContextGlobal}
|
||||
onEditItem={groupWithContext =>
|
||||
this.props.onEditGroup(groupWithContext.group)
|
||||
}
|
||||
onAddNewItem={this.addGroup}
|
||||
addNewItemLabel={<Trans>Add a new group</Trans>}
|
||||
addNewItemId="add-new-group-button"
|
||||
selectedItems={[]}
|
||||
onItemSelected={groupWithContext => {
|
||||
this.setState({
|
||||
selectedGroupWithContext: groupWithContext,
|
||||
});
|
||||
}}
|
||||
renamedItem={renamedGroupWithContext}
|
||||
onRename={this._onRename}
|
||||
buildMenuTemplate={this._renderGroupMenuTemplate(i18n)}
|
||||
onMoveSelectionToItem={this._moveSelectionTo}
|
||||
canMoveSelectionToItem={this._canMoveSelectionTo}
|
||||
reactDndType={groupWithContextReactDndType}
|
||||
/>
|
||||
<PreferencesContext.Consumer>
|
||||
{({ values }) => (
|
||||
<Background onClick={this.props.onEditorActive}>
|
||||
<div style={styles.listContainer}>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<SortableVirtualizedItemList
|
||||
key={listKey}
|
||||
ref={sortableList => (this.sortableList = sortableList)}
|
||||
fullList={fullList}
|
||||
width={width}
|
||||
height={height}
|
||||
getItemName={getGroupWithContextName}
|
||||
getItemId={(groupWithContext, index) => {
|
||||
return 'group-item-' + index;
|
||||
}}
|
||||
isItemBold={isGroupWithContextGlobal}
|
||||
onEditItem={groupWithContext =>
|
||||
this.props.onEditGroup(groupWithContext.group)
|
||||
}
|
||||
onAddNewItem={this.addGroup}
|
||||
addNewItemLabel={<Trans>Add a new group</Trans>}
|
||||
addNewItemId="add-new-group-button"
|
||||
selectedItems={
|
||||
this.state.selectedGroupWithContext
|
||||
? [this.state.selectedGroupWithContext]
|
||||
: []
|
||||
}
|
||||
onItemSelected={groupWithContext => {
|
||||
this.setState({
|
||||
selectedGroupWithContext: groupWithContext,
|
||||
});
|
||||
}}
|
||||
areItemsEqual={(a, b) =>
|
||||
a.group.ptr === b.group.ptr && a.global === b.global
|
||||
}
|
||||
renamedItem={renamedGroupWithContext}
|
||||
onRename={this._onRename}
|
||||
buildMenuTemplate={this._renderGroupMenuTemplate(
|
||||
i18n,
|
||||
values
|
||||
)}
|
||||
onMoveSelectionToItem={this._moveSelectionTo}
|
||||
canMoveSelectionToItem={this._canMoveSelectionTo}
|
||||
reactDndType={groupWithContextReactDndType}
|
||||
/>
|
||||
)}
|
||||
</I18n>
|
||||
)}
|
||||
</I18n>
|
||||
)}
|
||||
</AutoSizer>
|
||||
</div>
|
||||
<SearchBar
|
||||
value={searchText}
|
||||
onRequestSearch={() => {}}
|
||||
onChange={text =>
|
||||
this.setState({
|
||||
searchText: text,
|
||||
})
|
||||
}
|
||||
aspect="integrated-search-bar"
|
||||
placeholder={t`Search object groups`}
|
||||
/>
|
||||
</Background>
|
||||
</AutoSizer>
|
||||
</div>
|
||||
<SearchBar
|
||||
value={searchText}
|
||||
onRequestSearch={() => {}}
|
||||
onChange={text =>
|
||||
this.setState({
|
||||
searchText: text,
|
||||
})
|
||||
}
|
||||
aspect="integrated-search-bar"
|
||||
placeholder={t`Search object groups`}
|
||||
/>
|
||||
</Background>
|
||||
)}
|
||||
</PreferencesContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -137,6 +137,7 @@ type Props = {|
|
||||
) => string,
|
||||
unsavedChanges?: ?UnsavedChanges,
|
||||
hotReloadPreviewButtonProps: HotReloadPreviewButtonProps,
|
||||
onEditorActive?: () => void,
|
||||
|};
|
||||
|
||||
const ObjectsList = React.forwardRef<Props, ObjectsListInterface>(
|
||||
@@ -169,6 +170,7 @@ const ObjectsList = React.forwardRef<Props, ObjectsListInterface>(
|
||||
getThumbnail,
|
||||
unsavedChanges,
|
||||
hotReloadPreviewButtonProps,
|
||||
onEditorActive,
|
||||
}: Props,
|
||||
ref
|
||||
) => {
|
||||
@@ -798,7 +800,7 @@ const ObjectsList = React.forwardRef<Props, ObjectsListInterface>(
|
||||
const screenType = useScreenType();
|
||||
|
||||
return (
|
||||
<Background maxWidth>
|
||||
<Background maxWidth onClick={onEditorActive}>
|
||||
<TagChips
|
||||
tags={selectedObjectTags}
|
||||
onChange={onChangeSelectedObjectTags}
|
||||
|
@@ -41,8 +41,7 @@ type Props = {|
|
||||
getContextMenuZoomItems: I18nType => Array<MenuItemTemplate>,
|
||||
setZoomFactor: number => void,
|
||||
onOpenSettings?: ?() => void,
|
||||
canRenameObject: boolean,
|
||||
onRenameObject: () => void,
|
||||
onRenameObjectOrGroup: () => void,
|
||||
|};
|
||||
|
||||
const Toolbar = (props: Props) => {
|
||||
@@ -65,8 +64,7 @@ const Toolbar = (props: Props) => {
|
||||
canDeleteSelection={
|
||||
props.instancesSelection.getSelectedInstances().length !== 0
|
||||
}
|
||||
canRenameObject={props.canRenameObject}
|
||||
onRenameObject={props.onRenameObject}
|
||||
onRenameObjectOrGroup={props.onRenameObjectOrGroup}
|
||||
/>
|
||||
<ToolbarGroup lastChild>
|
||||
<IconButton
|
||||
|
@@ -16,8 +16,7 @@ type Props = {|
|
||||
toggleWindowMask: () => void,
|
||||
toggleGrid: () => void,
|
||||
setupGrid: () => void,
|
||||
canRenameObject: boolean,
|
||||
onRenameObject: () => void,
|
||||
onRenameObjectOrGroup: () => void,
|
||||
|};
|
||||
|
||||
const ToolbarCommands = (props: Props) => {
|
||||
@@ -65,8 +64,8 @@ const ToolbarCommands = (props: Props) => {
|
||||
handler: props.setupGrid,
|
||||
});
|
||||
|
||||
useCommand('RENAME_SCENE_OBJECT', props.canRenameObject, {
|
||||
handler: props.onRenameObject,
|
||||
useCommand('RENAME_SCENE_OBJECT', true, {
|
||||
handler: props.onRenameObjectOrGroup,
|
||||
});
|
||||
|
||||
return null;
|
||||
|
@@ -154,6 +154,14 @@ type State = {|
|
||||
|
||||
renamedObjectWithContext: ?ObjectWithContext,
|
||||
selectedObjectsWithContext: Array<ObjectWithContext>,
|
||||
activeEditor:
|
||||
| 'instance-properties-editor'
|
||||
| 'layers-list'
|
||||
| 'instances-list'
|
||||
| 'instances-editor'
|
||||
| 'objects-list'
|
||||
| 'object-groups-list'
|
||||
| null,
|
||||
|};
|
||||
|
||||
type CopyCutPasteOptions = {|
|
||||
@@ -171,6 +179,7 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
contextMenu: ?ContextMenuInterface;
|
||||
editorMosaic: ?EditorMosaic;
|
||||
_objectsList: ?ObjectsListInterface;
|
||||
_objectGroupsList: ?ObjectGroupsList;
|
||||
_layersList: ?LayersListInterface;
|
||||
_propertiesEditor: ?InstancePropertiesEditor;
|
||||
_instancesList: ?InstancesList;
|
||||
@@ -217,6 +226,8 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
|
||||
renamedObjectWithContext: null,
|
||||
selectedObjectsWithContext: [],
|
||||
|
||||
activeEditor: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -254,8 +265,7 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
undo={this.undo}
|
||||
redo={this.redo}
|
||||
onOpenSettings={this.openSceneProperties}
|
||||
canRenameObject={this.state.selectedObjectsWithContext.length === 1}
|
||||
onRenameObject={this._startRenamingSelectedObject}
|
||||
onRenameObjectOrGroup={this._startRenamingSelectedObjectOrGroup}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -718,8 +728,15 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
);
|
||||
};
|
||||
|
||||
_startRenamingSelectedObject = () => {
|
||||
this._onRenameObjectStart(this.state.selectedObjectsWithContext[0]);
|
||||
_startRenamingSelectedObjectOrGroup = () => {
|
||||
if (this.state.activeEditor === 'objects-list') {
|
||||
this._onRenameObjectStart(this.state.selectedObjectsWithContext[0]);
|
||||
} else if (
|
||||
this.state.activeEditor === 'object-groups-list' &&
|
||||
this._objectGroupsList
|
||||
) {
|
||||
this._objectGroupsList.startEditingSelectedGroup();
|
||||
}
|
||||
};
|
||||
|
||||
_onRenameLayer = (
|
||||
@@ -1354,6 +1371,9 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
i18n={i18n}
|
||||
project={project}
|
||||
layout={layout}
|
||||
onEditorActive={() =>
|
||||
this.setState({ activeEditor: 'instance-properties-editor' })
|
||||
}
|
||||
instances={selectedInstances}
|
||||
editInstanceVariables={this.editInstanceVariables}
|
||||
onEditObjectByName={this.editObjectByName}
|
||||
@@ -1388,6 +1408,9 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
renderEditor: () => (
|
||||
<LayersList
|
||||
project={project}
|
||||
onEditorActive={() =>
|
||||
this.setState({ activeEditor: 'layers-list' })
|
||||
}
|
||||
onEditLayerEffects={this.editLayerEffects}
|
||||
onEditLayer={this.editLayer}
|
||||
onRemoveLayer={this._onRemoveLayer}
|
||||
@@ -1405,6 +1428,9 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
title: t`Instances List`,
|
||||
renderEditor: () => (
|
||||
<InstancesList
|
||||
onEditorActive={() =>
|
||||
this.setState({ activeEditor: 'instances-list' })
|
||||
}
|
||||
instances={initialInstances}
|
||||
selectedInstances={selectedInstances}
|
||||
onSelectInstances={this._onSelectInstances}
|
||||
@@ -1419,6 +1445,9 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
<FullSizeInstancesEditorWithScrollbars
|
||||
project={project}
|
||||
layout={layout}
|
||||
onEditorActive={() =>
|
||||
this.setState({ activeEditor: 'instances-editor' })
|
||||
}
|
||||
initialInstances={initialInstances}
|
||||
instancesEditorSettings={this.state.instancesEditorSettings}
|
||||
onChangeInstancesEditorSettings={this.setInstancesEditorSettings}
|
||||
@@ -1474,6 +1503,9 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
ObjectsRenderingService
|
||||
)}
|
||||
project={project}
|
||||
onEditorActive={() =>
|
||||
this.setState({ activeEditor: 'objects-list' })
|
||||
}
|
||||
objectsContainer={layout}
|
||||
layout={layout}
|
||||
onSelectAllInstancesOfObjectInLayout={
|
||||
@@ -1522,6 +1554,9 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<ObjectGroupsList
|
||||
onEditorActive={() =>
|
||||
this.setState({ activeEditor: 'object-groups-list' })
|
||||
}
|
||||
globalObjectGroups={project.getObjectGroups()}
|
||||
objectGroups={layout.getObjectGroups()}
|
||||
onEditGroup={this.editGroup}
|
||||
@@ -1531,6 +1566,9 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
this._canObjectOrGroupUseNewName(newName, i18n)
|
||||
}
|
||||
unsavedChanges={this.props.unsavedChanges}
|
||||
ref={objectGroupsList =>
|
||||
(this._objectGroupsList = objectGroupsList)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</I18n>
|
||||
|
@@ -19,6 +19,7 @@ type Props = {|
|
||||
/** Sometimes required on Safari */
|
||||
noFullHeight?: boolean,
|
||||
noExpand?: boolean,
|
||||
onClick?: () => void,
|
||||
|};
|
||||
|
||||
/**
|
||||
@@ -36,6 +37,7 @@ const Background = (props: Props) => (
|
||||
...(props.maxWidth ? styles.maxWidth : undefined),
|
||||
}}
|
||||
background="dark"
|
||||
onClick={props.onClick}
|
||||
>
|
||||
{props.children}
|
||||
</Paper>
|
||||
|
@@ -13,6 +13,7 @@ type Props = {|
|
||||
background: 'light' | 'medium' | 'dark',
|
||||
style?: Object,
|
||||
square?: boolean,
|
||||
onClick?: () => void,
|
||||
|};
|
||||
|
||||
const Paper = ({
|
||||
@@ -22,6 +23,7 @@ const Paper = ({
|
||||
variant,
|
||||
style,
|
||||
square,
|
||||
onClick,
|
||||
}: Props) => {
|
||||
const gdevelopTheme = React.useContext(GDevelopThemeContext);
|
||||
const backgroundColor =
|
||||
@@ -39,6 +41,7 @@ const Paper = ({
|
||||
...style,
|
||||
}}
|
||||
square={!!square}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</MuiPaper>
|
||||
|
@@ -27,6 +27,7 @@ type Props<Item> = {|
|
||||
getItemData?: (Item, index: number) => HTMLDataset,
|
||||
isItemBold?: Item => boolean,
|
||||
onItemSelected: (?Item) => void,
|
||||
areItemsEqual?: (Item, Item) => boolean,
|
||||
onEditItem?: Item => void,
|
||||
renamedItem: ?Item,
|
||||
erroredItems?: { [string]: '' | 'error' | 'warning' },
|
||||
@@ -67,6 +68,7 @@ export default class SortableVirtualizedItemList<Item> extends React.Component<
|
||||
getItemData,
|
||||
renderItemLabel,
|
||||
scaleUpItemIconWhenSelected,
|
||||
areItemsEqual,
|
||||
} = this.props;
|
||||
|
||||
const nameBeingEdited = renamedItem === item;
|
||||
@@ -87,7 +89,13 @@ export default class SortableVirtualizedItemList<Item> extends React.Component<
|
||||
getThumbnail={
|
||||
getItemThumbnail ? () => getItemThumbnail(item) : undefined
|
||||
}
|
||||
selected={selectedItems.indexOf(item) !== -1}
|
||||
selected={
|
||||
areItemsEqual
|
||||
? selectedItems.some(selectedItem =>
|
||||
areItemsEqual(selectedItem, item)
|
||||
)
|
||||
: selectedItems.indexOf(item) !== -1
|
||||
}
|
||||
onItemSelected={this.props.onItemSelected}
|
||||
errorStatus={erroredItems ? erroredItems[itemName] || '' : ''}
|
||||
buildMenuTemplate={() => this.props.buildMenuTemplate(item, index)}
|
||||
|
Reference in New Issue
Block a user