mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Add support for dragging points in PointsPreview
This commit is contained in:
1
newIDE/app/flow-typed/libGD.js
vendored
1
newIDE/app/flow-typed/libGD.js
vendored
@@ -37,6 +37,7 @@ declare type gdSpriteObject = EmscriptenObject;
|
||||
declare type gdSprite = EmscriptenObject;
|
||||
declare type gdDirection = EmscriptenObject;
|
||||
declare type gdAnimation = EmscriptenObject;
|
||||
declare type gdPoint = EmscriptenObject;
|
||||
|
||||
declare type gdVectorEventsSearchResult = EmscriptenObject;
|
||||
declare type gdMapStringPropertyDescriptor = EmscriptenObject;
|
||||
|
@@ -20,7 +20,7 @@ type Props = {|
|
||||
isDefaultBoundingBox: boolean,
|
||||
imageWidth: number,
|
||||
imageHeight: number,
|
||||
onVertexMoved: () => void,
|
||||
onPolygonsUpdated: () => void,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
@@ -36,18 +36,6 @@ export default class CollisionMasksPreview extends React.Component<
|
||||
draggedVertex: null,
|
||||
};
|
||||
|
||||
_onEndDragVertex = () => {
|
||||
const draggingWasDone = !!this.state.draggedVertex;
|
||||
this.setState(
|
||||
{
|
||||
draggedVertex: null,
|
||||
},
|
||||
() => {
|
||||
if (draggingWasDone) this.props.onVertexMoved();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
_onStartDragVertex = (draggedVertex: gdVector2f) => {
|
||||
if (this.state.draggedVertex) return;
|
||||
|
||||
@@ -56,15 +44,34 @@ export default class CollisionMasksPreview extends React.Component<
|
||||
});
|
||||
};
|
||||
|
||||
_onEndDragVertex = () => {
|
||||
const draggingWasDone = !!this.state.draggedVertex;
|
||||
this.setState(
|
||||
{
|
||||
draggedVertex: null,
|
||||
},
|
||||
() => {
|
||||
if (draggingWasDone) this.props.onPolygonsUpdated();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move a vertex with the mouse. A similar dragging implementation is done in
|
||||
* PointsPreview (but with div and img elements).
|
||||
*
|
||||
* If custom zoom is added, this should be adapted to properly set vertex coordinates.
|
||||
* TODO: This could be optimized by avoiding the forceUpdate (not sure if worth it though).
|
||||
*/
|
||||
_onMouseMove = (event: any) => {
|
||||
const { draggedVertex } = this.state;
|
||||
if (!draggedVertex) return;
|
||||
|
||||
var pointOnScreen = this._svg.createSVGPoint();
|
||||
const pointOnScreen = this._svg.createSVGPoint();
|
||||
pointOnScreen.x = event.clientX;
|
||||
pointOnScreen.y = event.clientY;
|
||||
var screenToSvgMatrix = this._svg.getScreenCTM().inverse();
|
||||
var pointOnSvg = pointOnScreen.matrixTransform(screenToSvgMatrix);
|
||||
const screenToSvgMatrix = this._svg.getScreenCTM().inverse();
|
||||
const pointOnSvg = pointOnScreen.matrixTransform(screenToSvgMatrix);
|
||||
|
||||
draggedVertex.set_x(pointOnSvg.x);
|
||||
draggedVertex.set_y(pointOnSvg.y);
|
||||
|
@@ -210,7 +210,7 @@ export default class CollisionMasksEditor extends Component {
|
||||
<CollisionMasksPreview
|
||||
isDefaultBoundingBox={sprite.isCollisionMaskAutomatic()}
|
||||
polygons={sprite.getCustomCollisionMask()}
|
||||
onVertexMoved={this._updateCollisionMasks}
|
||||
onPolygonsUpdated={this._updateCollisionMasks}
|
||||
/>
|
||||
)}
|
||||
</ImagePreview>
|
||||
|
@@ -1,25 +1,114 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import { mapVector } from '../../../../Utils/MapFor';
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
};
|
||||
|
||||
export default class PointsPreview extends React.Component {
|
||||
_renderPoint = (name, x, y, imageSrc = undefined) => {
|
||||
const pointKindIdentifiers = {
|
||||
NORMAL: 1,
|
||||
ORIGIN: 2,
|
||||
CENTER: 3,
|
||||
};
|
||||
type PointKind = 1 | 2 | 3;
|
||||
|
||||
type Props = {|
|
||||
pointsContainer: gdSprite, // Could potentially be generalized to other things than Sprite in the future.
|
||||
imageWidth: number,
|
||||
imageHeight: number,
|
||||
onPointsUpdated: () => void,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
draggedPoint: ?gdPoint,
|
||||
draggedPointKind: ?PointKind,
|
||||
|};
|
||||
|
||||
export default class PointsPreview extends React.Component<Props, State> {
|
||||
_container: ?any;
|
||||
state = {
|
||||
draggedPoint: null,
|
||||
draggedPointKind: null,
|
||||
};
|
||||
|
||||
_onStartDragPoint = (draggedPoint: gdPoint, draggedPointKind: PointKind) => {
|
||||
if (this.state.draggedPoint) return;
|
||||
|
||||
this.setState({
|
||||
draggedPoint,
|
||||
draggedPointKind,
|
||||
});
|
||||
};
|
||||
|
||||
_onEndDragPoint = () => {
|
||||
const draggingWasDone = !!this.state.draggedPoint;
|
||||
this.setState(
|
||||
{
|
||||
draggedPoint: null,
|
||||
draggedPointKind: null,
|
||||
},
|
||||
() => {
|
||||
if (draggingWasDone) this.props.onPointsUpdated();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move a point with the mouse. A similar dragging implementation is done in
|
||||
* CollisionMasksPreview (but with svg elements).
|
||||
*
|
||||
* If custom zoom is added, this should be adapted to properly set point coordinates.
|
||||
* TODO: This could be optimized by avoiding the forceUpdate (not sure if worth it though).
|
||||
*/
|
||||
_onMouseMove = (event: any) => {
|
||||
const { draggedPoint, draggedPointKind } = this.state;
|
||||
if (!draggedPoint || !this._container) return;
|
||||
|
||||
const containerBoundingRect = this._container.getBoundingClientRect();
|
||||
const xOnContainer = event.clientX - containerBoundingRect.left;
|
||||
const yOnContainer = event.clientY - containerBoundingRect.top;
|
||||
|
||||
if (draggedPointKind === pointKindIdentifiers.CENTER) {
|
||||
this.props.pointsContainer.setDefaultCenterPoint(false);
|
||||
}
|
||||
draggedPoint.setX(xOnContainer);
|
||||
draggedPoint.setY(yOnContainer);
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
_renderPoint = (
|
||||
name: string,
|
||||
x: number,
|
||||
y: number,
|
||||
kind: PointKind,
|
||||
point: gdPoint
|
||||
) => {
|
||||
const imageSrc =
|
||||
kind === pointKindIdentifiers.ORIGIN
|
||||
? 'res/originPoint.png'
|
||||
: kind === pointKindIdentifiers.CENTER
|
||||
? 'res/centerPoint.png'
|
||||
: 'res/point.png';
|
||||
return (
|
||||
<img
|
||||
src={imageSrc || 'res/point.png'}
|
||||
src={imageSrc}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: x,
|
||||
top: y,
|
||||
transform: 'translate(-6px, -5px)',
|
||||
cursor: 'move',
|
||||
}}
|
||||
alt=""
|
||||
key={name}
|
||||
onMouseDown={() => {
|
||||
this._onStartDragPoint(point, kind);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -28,7 +117,13 @@ export default class PointsPreview extends React.Component {
|
||||
const { pointsContainer, imageWidth, imageHeight } = this.props;
|
||||
const nonDefaultPoints = pointsContainer.getAllNonDefaultPoints();
|
||||
const points = mapVector(nonDefaultPoints, (point, i) =>
|
||||
this._renderPoint(point.getName(), point.getX(), point.getY())
|
||||
this._renderPoint(
|
||||
point.getName(),
|
||||
point.getX(),
|
||||
point.getY(),
|
||||
pointKindIdentifiers.NORMAL,
|
||||
point
|
||||
)
|
||||
);
|
||||
|
||||
const originPoint = pointsContainer.getOrigin();
|
||||
@@ -36,19 +131,26 @@ export default class PointsPreview extends React.Component {
|
||||
const automaticCenterPosition = pointsContainer.isDefaultCenterPoint();
|
||||
|
||||
return (
|
||||
<div style={styles.container}>
|
||||
<div
|
||||
style={styles.container}
|
||||
onMouseMove={this._onMouseMove}
|
||||
onMouseUp={this._onEndDragPoint}
|
||||
ref={container => (this._container = container)}
|
||||
>
|
||||
{points}
|
||||
{this._renderPoint(
|
||||
'Origin',
|
||||
originPoint.getX(),
|
||||
originPoint.getY(),
|
||||
'res/originPoint.png'
|
||||
pointKindIdentifiers.ORIGIN,
|
||||
originPoint
|
||||
)}
|
||||
{this._renderPoint(
|
||||
'Center',
|
||||
!automaticCenterPosition ? centerPoint.getX() : imageWidth / 2,
|
||||
!automaticCenterPosition ? centerPoint.getY() : imageHeight / 2,
|
||||
'res/centerPoint.png'
|
||||
pointKindIdentifiers.CENTER,
|
||||
centerPoint
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@@ -170,7 +170,12 @@ export default class PointsEditor extends Component {
|
||||
resourcesLoader={resourcesLoader}
|
||||
project={project}
|
||||
>
|
||||
{hasValidSprite && <PointsPreview pointsContainer={sprite} />}
|
||||
{hasValidSprite && (
|
||||
<PointsPreview
|
||||
pointsContainer={sprite}
|
||||
onPointsUpdated={this._updatePoints}
|
||||
/>
|
||||
)}
|
||||
</ImagePreview>
|
||||
<Line>
|
||||
<Column expand>
|
||||
|
Reference in New Issue
Block a user