Skip to content

Commit 007d56e

Browse files
authored
Display the scene editors more conveniently on mobile (#5441)
1 parent 577c4ad commit 007d56e

File tree

31 files changed

+2175
-711
lines changed

31 files changed

+2175
-711
lines changed

newIDE/app/scripts/theme-templates/theme.json

+61
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,67 @@
4848
}
4949
}
5050
},
51+
"swipeable-drawer": {
52+
"top-bar": {
53+
"pill-color": {
54+
"value": "#1D1D26"
55+
}
56+
}
57+
},
58+
"icon-button": {
59+
"selected": {
60+
"color": {
61+
"value": "#1D1D26",
62+
"comment": "Palette/Grey/100"
63+
},
64+
"background-color": {
65+
"value": "#C9B6FC",
66+
"comment:": "Palette/Purple/20"
67+
}
68+
}
69+
},
70+
"link": {
71+
"color": {
72+
"value": "#DDD1FF",
73+
"comment": "Palette/Purple/10"
74+
},
75+
"hover-color": {
76+
"value": "#C9B6FC",
77+
"comment": "Palette/Purple/20"
78+
}
79+
},
80+
"switch": {
81+
"default": {
82+
"thumb-color": {
83+
"value": "#EBEBED",
84+
"comment": "Palette/Grey/10"
85+
},
86+
"track-color": {
87+
"value": "#606066",
88+
"comment": "Palette/Grey/60"
89+
}
90+
},
91+
"toggled": {
92+
"thumb-color": {
93+
"value": "#DDD1FF",
94+
"comment": "Palette/Purple/10"
95+
},
96+
"track-color": {
97+
"value": "#7046EC",
98+
"comment": "Palette/Purple/40"
99+
}
100+
},
101+
"disabled": {
102+
"thumb-color": {
103+
"value": "#494952",
104+
"comment": "Palette/Grey/70"
105+
},
106+
"track-color": {
107+
"value": "#32323B",
108+
"comment": "Palette/Grey/80"
109+
}
110+
}
111+
},
51112
"search-bar": {
52113
"default": {
53114
"background-color": {

newIDE/app/src/InstancesEditor/InstancesList/index.js

+37-12
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,17 @@ import SearchBar, { type SearchBarInterface } from '../../UI/SearchBar';
1414
import RemoveCircle from '../../UI/CustomSvgIcons/RemoveCircle';
1515
import Lock from '../../UI/CustomSvgIcons/Lock';
1616
import LockOpen from '../../UI/CustomSvgIcons/LockOpen';
17+
import { toFixedWithoutTrailingZeros } from '../../Utils/Mathematics';
1718
const gd = global.gd;
1819

20+
const minimumWidths = {
21+
table: 400,
22+
objectName: 80,
23+
icon: 40,
24+
numberProperty: 40,
25+
layerName: 50,
26+
};
27+
1928
type State = {|
2029
searchText: string,
2130
sortBy: string,
@@ -46,6 +55,7 @@ const styles = {
4655
flexDirection: 'column',
4756
alignItems: 'stretch',
4857
},
58+
tableContainer: { flex: 1, overflowX: 'auto', overflowY: 'hidden' },
4959
};
5060

5161
const compareStrings = (x: string, y: string, direction: number): number => {
@@ -89,9 +99,9 @@ export default class InstancesList extends Component<Props, State> {
8999
instance,
90100
name,
91101
locked: instance.isLocked(),
92-
x: instance.getX().toFixed(2),
93-
y: instance.getY().toFixed(2),
94-
angle: instance.getAngle().toFixed(2),
102+
x: toFixedWithoutTrailingZeros(instance.getX(), 2),
103+
y: toFixedWithoutTrailingZeros(instance.getY(), 2),
104+
angle: toFixedWithoutTrailingZeros(instance.getAngle(), 2),
95105
layer: instance.getLayer(),
96106
zOrder: instance.getZOrder(),
97107
});
@@ -225,7 +235,7 @@ export default class InstancesList extends Component<Props, State> {
225235
{gdevelopTheme => (
226236
<div style={styles.container}>
227237
<div
228-
style={{ flex: 1 }}
238+
style={styles.tableContainer}
229239
onKeyDown={this._keyboardShortcuts.onKeyDown}
230240
onKeyUp={this._keyboardShortcuts.onKeyUp}
231241
>
@@ -246,49 +256,64 @@ export default class InstancesList extends Component<Props, State> {
246256
sort={this._sort}
247257
sortBy={sortBy}
248258
sortDirection={sortDirection}
249-
width={width}
259+
width={Math.max(width, minimumWidths.table)}
250260
>
251261
<RVColumn
252262
label={<Trans>Object name</Trans>}
253263
dataKey="name"
254-
width={width * 0.35}
264+
width={Math.max(width * 0.35, minimumWidths.objectName)}
255265
className={'tableColumn'}
256266
/>
257267
<RVColumn
258268
label=""
259269
dataKey="locked"
260-
width={width * 0.05}
270+
width={Math.max(
271+
width * 0.05,
272+
minimumWidths.numberProperty
273+
)}
261274
className={'tableColumn'}
262275
cellRenderer={this._renderLockCell}
263276
/>
264277
<RVColumn
265278
label={<Trans>X</Trans>}
266279
dataKey="x"
267-
width={width * 0.1}
280+
width={Math.max(
281+
width * 0.1,
282+
minimumWidths.numberProperty
283+
)}
268284
className={'tableColumn'}
269285
/>
270286
<RVColumn
271287
label={<Trans>Y</Trans>}
272288
dataKey="y"
273-
width={width * 0.1}
289+
width={Math.max(
290+
width * 0.1,
291+
minimumWidths.numberProperty
292+
)}
274293
className={'tableColumn'}
275294
/>
276295
<RVColumn
277296
label={<Trans>Angle</Trans>}
278297
dataKey="angle"
279-
width={width * 0.1}
298+
width={Math.max(
299+
width * 0.1,
300+
minimumWidths.numberProperty
301+
)}
280302
className={'tableColumn'}
281303
/>
282304
<RVColumn
283305
label={<Trans>Layer</Trans>}
284306
dataKey="layer"
285-
width={width * 0.2}
307+
width={Math.max(width * 0.2, minimumWidths.layerName)}
286308
className={'tableColumn'}
287309
/>
288310
<RVColumn
289311
label={<Trans>Z Order</Trans>}
290312
dataKey="zOrder"
291-
width={width * 0.1}
313+
width={Math.max(
314+
width * 0.1,
315+
minimumWidths.numberProperty
316+
)}
292317
className={'tableColumn'}
293318
/>
294319
</RVTable>

newIDE/app/src/InstancesEditor/SelectedInstances.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ export default class SelectedInstances {
190190
);
191191
}
192192

193-
getSelectionAABB(): Rectangle {
193+
getSelectionAABB = (): Rectangle => {
194194
const selectionAABB = new Rectangle();
195195
const selection = this.instancesSelection.getSelectedInstances();
196196
let instanceRect = new Rectangle();
@@ -208,7 +208,7 @@ export default class SelectedInstances {
208208
}
209209
}
210210
return selectionAABB;
211-
}
211+
};
212212

213213
render() {
214214
const {

newIDE/app/src/InstancesEditor/ViewPosition.js

+8
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ export default class ViewPosition {
8383
return [x + this.viewX, y + this.viewY];
8484
};
8585

86+
/**
87+
* Convert a length from canvas referential to scene referential.
88+
*/
89+
toSceneScale = (a: number): number =>
90+
this.instancesEditorSettings.zoomFactor === 0
91+
? a
92+
: a / Math.abs(this.instancesEditorSettings.zoomFactor);
93+
8694
/**
8795
* Convert a point from the "world" coordinates (for example, an object position) to the
8896
* canvas coordinates.

newIDE/app/src/InstancesEditor/index.js

+33-26
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ type Props = {|
9696
...InstancesEditorPropsWithoutSizeAndScroll,
9797
width: number,
9898
height: number,
99-
onViewPositionChanged: ViewPosition => void,
100-
onMouseMove: MouseEvent => void,
101-
onMouseLeave: MouseEvent => void,
99+
onViewPositionChanged?: ViewPosition => void,
100+
onMouseMove?: MouseEvent => void,
101+
onMouseLeave?: MouseEvent => void,
102102
screenType: ScreenType,
103103
showObjectInstancesIn3D: boolean,
104104
|};
@@ -161,7 +161,7 @@ export default class InstancesEditor extends Component<Props> {
161161
// project can be used here for initializing stuff, but don't keep references to it.
162162
// Instead, create editors in _mountEditorComponents (as they will be destroyed/recreated
163163
// if the project changes).
164-
const { project } = this.props;
164+
const { project, onMouseMove, onMouseLeave } = this.props;
165165

166166
this.keyboardShortcuts = new KeyboardShortcuts({
167167
shortcutCallbacks: {
@@ -257,12 +257,14 @@ export default class InstancesEditor extends Component<Props> {
257257
'mouseup',
258258
this.keyboardShortcuts.onMouseUp
259259
);
260-
this.pixiRenderer.view.addEventListener('mousemove', event => {
261-
this.props.onMouseMove(event);
262-
});
263-
this.pixiRenderer.view.addEventListener('mouseout', event => {
264-
this.props.onMouseLeave(event);
265-
});
260+
if (onMouseMove)
261+
this.pixiRenderer.view.addEventListener('mousemove', event => {
262+
onMouseMove(event);
263+
});
264+
if (onMouseLeave)
265+
this.pixiRenderer.view.addEventListener('mouseout', event => {
266+
onMouseLeave(event);
267+
});
266268
this.pixiRenderer.view.addEventListener('focusout', event => {
267269
if (this.keyboardShortcuts) {
268270
this.keyboardShortcuts.resetModifiers();
@@ -368,9 +370,9 @@ export default class InstancesEditor extends Component<Props> {
368370
* this when the initial instances were recreated to ensure that there
369371
* is not mismatch between renderers and the instances that were updated.
370372
*/
371-
forceRemount() {
373+
forceRemount = () => {
372374
this._mountEditorComponents(this.props);
373-
}
375+
};
374376

375377
_mountEditorComponents(props: Props) {
376378
//Remove and delete any existing editor component
@@ -558,14 +560,14 @@ export default class InstancesEditor extends Component<Props> {
558560
* See also ResourcesLoader and PixiResourcesLoader.
559561
* @param {string} objectName The name of the object for which instance must be re-rendered.
560562
*/
561-
resetInstanceRenderersFor(objectName: string) {
563+
resetInstanceRenderersFor = (objectName: string) => {
562564
if (this.instancesRenderer)
563565
this.instancesRenderer.resetInstanceRenderersFor(objectName);
564-
}
566+
};
565567

566-
zoomBy(value: number) {
568+
zoomBy = (value: number) => {
567569
this.setZoomFactor(this.getZoomFactor() * value);
568-
}
570+
};
569571

570572
/**
571573
* Zoom and scroll so that the cursor stays on the same position scene-wise.
@@ -642,7 +644,8 @@ export default class InstancesEditor extends Component<Props> {
642644

643645
if (
644646
!this.keyboardShortcuts.shouldMultiSelect() &&
645-
!this.keyboardShortcuts.shouldMoveView()
647+
!this.keyboardShortcuts.shouldMoveView() &&
648+
this.props.instancesSelection.hasSelectedInstances()
646649
) {
647650
this.props.instancesSelection.clearSelection();
648651
this.props.onInstancesSelected([]);
@@ -925,7 +928,7 @@ export default class InstancesEditor extends Component<Props> {
925928
return this.canvasArea.getBoundingClientRect();
926929
}
927930

928-
zoomToFitContent() {
931+
zoomToFitContent = () => {
929932
const { initialInstances } = this.props;
930933
if (initialInstances.getInstancesCount() === 0) return;
931934

@@ -954,9 +957,9 @@ export default class InstancesEditor extends Component<Props> {
954957
initialInstances.iterateOverInstances(getInstanceRectangle);
955958
getInstanceRectangle.delete();
956959
if (contentAABB) this.fitViewToRectangle(contentAABB, { adaptZoom: true });
957-
}
960+
};
958961

959-
zoomToInitialPosition() {
962+
zoomToInitialPosition = () => {
960963
const width = this.props.project.getGameResolutionWidth();
961964
const height = this.props.project.getGameResolutionHeight();
962965
const x = width / 2;
@@ -965,9 +968,9 @@ export default class InstancesEditor extends Component<Props> {
965968
getRecommendedInitialZoomFactor(Math.max(height, width))
966969
);
967970
this.scrollTo(x, y);
968-
}
971+
};
969972

970-
zoomToFitSelection(instances: Array<gdInitialInstance>) {
973+
zoomToFitSelection = (instances: Array<gdInitialInstance>) => {
971974
if (instances.length === 0) return;
972975
const [firstInstance, ...otherInstances] = instances;
973976
const instanceMeasurer = this.instancesRenderer.getInstanceMeasurer();
@@ -981,9 +984,12 @@ export default class InstancesEditor extends Component<Props> {
981984
);
982985
});
983986
this.fitViewToRectangle(selectedInstancesRectangle, { adaptZoom: true });
984-
}
987+
};
985988

986-
centerViewOnLastInstance(instances: Array<gdInitialInstance>) {
989+
centerViewOnLastInstance = (
990+
instances: Array<gdInitialInstance>,
991+
offset?: ?[number, number]
992+
) => {
987993
if (instances.length === 0) return;
988994

989995
const instanceMeasurer = this.instancesRenderer.getInstanceMeasurer();
@@ -992,7 +998,8 @@ export default class InstancesEditor extends Component<Props> {
992998
new Rectangle()
993999
);
9941000
this.fitViewToRectangle(lastInstanceRectangle, { adaptZoom: false });
995-
}
1001+
if (offset) this.scrollBy(offset[0], offset[1]);
1002+
};
9961003

9971004
getLastContextMenuSceneCoordinates = () => {
9981005
return this.viewPosition.toSceneCoordinates(
@@ -1008,7 +1015,7 @@ export default class InstancesEditor extends Component<Props> {
10081015
);
10091016
};
10101017

1011-
getViewPosition = () /*: ?ViewPosition */ => {
1018+
getViewPosition = (): ?ViewPosition => {
10121019
return this.viewPosition;
10131020
};
10141021

newIDE/app/src/ObjectsList/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -941,4 +941,4 @@ const areEqual = (prevProps: Props, nextProps: Props): boolean =>
941941
prevProps.project === nextProps.project &&
942942
prevProps.objectsContainer === nextProps.objectsContainer;
943943

944-
export default React.memo<Props>(ObjectsList, areEqual);
944+
export default React.memo<Props, ObjectsListInterface>(ObjectsList, areEqual);

0 commit comments

Comments
 (0)