diff --git a/app/assets/tpl/editEntityDefs.html b/app/assets/tpl/editEntityDefs.html
index 76a5ec15d..0e201cb75 100644
--- a/app/assets/tpl/editEntityDefs.html
+++ b/app/assets/tpl/editEntityDefs.html
@@ -102,6 +102,23 @@
Project entities
Keep aspect ratio
+
+ Flippable:
+
+
+
+
+
+
diff --git a/app/assets/tpl/entityInstanceEditor.html b/app/assets/tpl/entityInstanceEditor.html
index 8d73f2c88..a4ce00fec 100644
--- a/app/assets/tpl/entityInstanceEditor.html
+++ b/app/assets/tpl/entityInstanceEditor.html
@@ -27,6 +27,22 @@
+
+ Flips
+ How this Entity instance is oriented on the X and Y axes.
+
+
+
+
+
+
+
References to this entity
This is a list of all other Entities having a Reference field pointing to this Entity.
@@ -42,4 +58,4 @@
-
\ No newline at end of file
+
diff --git a/src/electron.renderer/GenericLevelElementGroup.hx b/src/electron.renderer/GenericLevelElementGroup.hx
index f5bb1fc4d..841dd2150 100644
--- a/src/electron.renderer/GenericLevelElementGroup.hx
+++ b/src/electron.renderer/GenericLevelElementGroup.hx
@@ -216,8 +216,8 @@ class GenericLevelElementGroup {
case Entity(li, ei):
selectRender.beginFill(c, alpha);
selectRender.drawRect(
- li.pxParallaxX + ( ei.x - ei.width * ei.def.pivotX ) * li.def.getScale(),
- li.pxParallaxY + ( ei.y - ei.height * ei.def.pivotY ) * li.def.getScale(),
+ li.pxParallaxX + ( ei.x - ei.width * ei.getAdjustedPivotX() ) * li.def.getScale(),
+ li.pxParallaxY + ( ei.y - ei.height * ei.getAdjustedPivotY() ) * li.def.getScale(),
ei.width * li.def.getScale(),
ei.height * li.def.getScale()
);
@@ -863,4 +863,4 @@ class GenericLevelElementGroup {
renderSelection();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/electron.renderer/data/def/EntityDef.hx b/src/electron.renderer/data/def/EntityDef.hx
index 87f1275e8..92eb66403 100644
--- a/src/electron.renderer/data/def/EntityDef.hx
+++ b/src/electron.renderer/data/def/EntityDef.hx
@@ -32,6 +32,9 @@ class EntityDef {
public var resizableX : Bool;
public var resizableY : Bool;
+ public var flippableX : Bool;
+ public var flippableY : Bool;
+ public var flipAroundPivot : Bool;
public var minWidth : Null;
public var maxWidth : Null;
public var minHeight : Null;
@@ -66,6 +69,8 @@ class EntityDef {
identifier = "Entity"+uid;
setPivot(0.5,1);
resizableX = resizableY = false;
+ flippableX = flippableY = false;
+ flipAroundPivot = false;
keepAspectRatio = false;
hollow = false;
tags = new Tags();
@@ -97,6 +102,14 @@ class EntityDef {
return null;
}
+ public inline function getFlippedPivotX() {
+ return flipAroundPivot ? ((width - 1) / width) - pivotX : pivotX;
+ }
+
+ public inline function getFlippedPivotY() {
+ return flipAroundPivot ? ((height - 1) / height) - pivotY : pivotY;
+ }
+
function set_identifier(id:String) {
return identifier = Project.isValidIdentifier(id) ? Project.cleanupIdentifier(id, _project.identifierStyle) : identifier;
}
@@ -149,6 +162,9 @@ class EntityDef {
o.height = JsonTools.readInt( json.height, 16 );
o.resizableX = JsonTools.readBool( json.resizableX, false );
o.resizableY = JsonTools.readBool( json.resizableY, false );
+ o.flippableX = JsonTools.readBool( json.flippableX, false );
+ o.flippableY = JsonTools.readBool( json.flippableY, false );
+ o.flipAroundPivot = JsonTools.readBool( json.flipAroundPivot, false );
o.minWidth = JsonTools.readNullableInt( json.minWidth );
o.maxWidth = JsonTools.readNullableInt( json.maxWidth );
o.minHeight = JsonTools.readNullableInt( json.minHeight );
@@ -207,6 +223,9 @@ class EntityDef {
height: height,
resizableX: resizableX,
resizableY: resizableY,
+ flippableX: flippableX,
+ flippableY: flippableY,
+ flipAroundPivot: flipAroundPivot,
minWidth: minWidth,
maxWidth: maxWidth,
minHeight: minHeight,
@@ -329,4 +348,4 @@ class EntityDef {
for(fd in fieldDefs)
fd.tidy(p);
}
-}
\ No newline at end of file
+}
diff --git a/src/electron.renderer/data/inst/EntityInstance.hx b/src/electron.renderer/data/inst/EntityInstance.hx
index bb747edaf..d24d48b2a 100644
--- a/src/electron.renderer/data/inst/EntityInstance.hx
+++ b/src/electron.renderer/data/inst/EntityInstance.hx
@@ -15,6 +15,7 @@ class EntityInstance {
public var worldY(get,never) : Int;
public var customWidth : Null;
public var customHeight: Null;
+ public var flips : Int;
public var width(get,never) : Int;
inline function get_width() return customWidth!=null ? customWidth : def.width;
@@ -24,25 +25,26 @@ class EntityInstance {
public var fieldInstances : Map = new Map();
- public var left(get,never) : Int; inline function get_left() return M.round( x - width*def.pivotX );
+ public var left(get,never) : Int; inline function get_left() return M.round( x - width*getAdjustedPivotX() );
public var right(get,never) : Int; inline function get_right() return left + width;
- public var top(get,never) : Int; inline function get_top() return M.round( y - height*def.pivotY );
+ public var top(get,never) : Int; inline function get_top() return M.round( y - height*getAdjustedPivotY() );
public var bottom(get,never) : Int; inline function get_bottom() return top + height;
- public function new(p:Project, li:LayerInstance, entityDefUid:Int, iid:String) {
+ public function new(p:Project, li:LayerInstance, entityDefUid:Int, iid:String, flips:Int = 0) {
_project = p;
_li = li;
defUid = entityDefUid;
this.iid = iid;
+ this.flips = flips;
}
@:keep public function toString() {
return 'EntityInst "${def.identifier}" @$x,$y';
}
- inline function get_centerX() return M.round( x + (0.5-def.pivotX)*width );
- inline function get_centerY() return M.round( y + (0.5-def.pivotY)*height );
+ inline function get_centerX() return M.round( x + (0.5-getAdjustedPivotX())*width );
+ inline function get_centerY() return M.round( y + (0.5-getAdjustedPivotY())*height );
inline function get_worldX() return Std.int( x + _li.level.worldX );
inline function get_worldY() return Std.int( y + _li.level.worldY );
@@ -70,6 +72,7 @@ class EntityInstance {
height: height,
defUid: defUid,
px: [x,y],
+ f: flips,
fieldInstances: {
var all = [];
for(fd in def.fieldDefs)
@@ -90,6 +93,7 @@ class EntityInstance {
layer: _li.def.identifier,
x : x,
y : y,
+ f: flips,
width: width,
height: height,
color: getSmartColor(false),
@@ -111,6 +115,8 @@ class EntityInstance {
ei.x = JsonTools.readInt( json.px[0], 0 );
ei.y = JsonTools.readInt( json.px[1], 0 );
+ ei.flips = JsonTools.readInt( json.f, 0 );
+
ei.customWidth = JsonTools.readNullableInt( json.width );
if( ei.customWidth==ei.def.width )
ei.customWidth = null;
@@ -127,12 +133,20 @@ class EntityInstance {
return ei;
}
+ public inline function getAdjustedPivotX() {
+ return (def.flipAroundPivot && M.hasBit(flips, 0)) ? ((width - 1) / width) - def.pivotX : def.pivotX;
+ }
+
+ public inline function getAdjustedPivotY() {
+ return (def.flipAroundPivot && M.hasBit(flips, 1)) ? ((height - 1) / height) - def.pivotY : def.pivotY;
+ }
+
public inline function getCx(ld:data.def.LayerDef) {
- return Std.int( ( x + (def.pivotX==1 ? -1 : 0) ) / ld.gridSize );
+ return Std.int( ( x + (getAdjustedPivotX()==1 ? -1 : 0) ) / ld.gridSize );
}
public inline function getCy(ld:data.def.LayerDef) {
- return Std.int( ( y + (def.pivotY==1 ? -1 : 0) ) / ld.gridSize );
+ return Std.int( ( y + (getAdjustedPivotY()==1 ? -1 : 0) ) / ld.gridSize );
}
public inline function getPointOriginX(ld:data.def.LayerDef) {
@@ -365,4 +379,4 @@ class EntityInstance {
}
-}
\ No newline at end of file
+}
diff --git a/src/electron.renderer/display/EntityRender.hx b/src/electron.renderer/display/EntityRender.hx
index 540a1d4a0..01b62e4a6 100644
--- a/src/electron.renderer/display/EntityRender.hx
+++ b/src/electron.renderer/display/EntityRender.hx
@@ -112,15 +112,21 @@ class EntityRender extends dn.Process {
ed = ei.def;
+
var w = ei!=null ? ei.width : ed.width;
var h = ei!=null ? ei.height : ed.height;
var color = ei!=null ? ei.getSmartColor(false) : ed.color;
+ var flipX = (ei!=null && M.hasBit(ei.flips,0));
+ var flipY = (ei!=null && M.hasBit(ei.flips,1));
+ var pivotX = ei!=null ? ei.getAdjustedPivotX() : ed.pivotX;
+ var pivotY = ei!=null ? ei.getAdjustedPivotY() : ed.pivotY;
+
var wrapper = new h2d.Object();
var g = new h2d.Graphics(wrapper);
- g.x = Std.int( -w*ed.pivotX + (ld!=null ? ld.pxOffsetX : 0) );
- g.y = Std.int( -h*ed.pivotY + (ld!=null ? ld.pxOffsetY : 0) );
+ g.x = Std.int( -w*pivotX + (ld!=null ? ld.pxOffsetX : 0));
+ g.y = Std.int( -h*pivotY + (ld!=null ? ld.pxOffsetY : 0));
var zoomScale = 1 / Editor.ME.camera.adjustedZoom;
@@ -145,13 +151,15 @@ class EntityRender extends dn.Process {
// Texture
var td = Editor.ME.project.defs.getTilesetDef(rect.tilesetUid);
var t = td.getTileRect(rect);
+ t.xFlip = flipX;
+ t.yFlip = flipY;
var alpha = ed.tileOpacity;
switch mode {
case Stretch:
var bmp = new h2d.Bitmap(t, wrapper);
if( ld!=null )
bmp.setPosition(ld.pxOffsetX, ld.pxOffsetY);
- bmp.tile.setCenterRatio(ed.pivotX, ed.pivotY);
+ bmp.tile.setCenterRatio(pivotX, pivotY);
bmp.alpha = alpha;
bmp.scaleX = w / bmp.tile.width;
@@ -161,17 +169,21 @@ class EntityRender extends dn.Process {
var bmp = new h2d.Bitmap(t, wrapper);
if( ld!=null )
bmp.setPosition(ld.pxOffsetX, ld.pxOffsetY);
- bmp.tile.setCenterRatio(ed.pivotX, ed.pivotY);
+ bmp.tile.setCenterRatio(pivotX, pivotY);
bmp.alpha = alpha;
var s = M.fmin(w / bmp.tile.width, h / bmp.tile.height);
bmp.setScale(s);
case Repeat:
- var tt = new dn.heaps.TiledTexture(w,h, t, wrapper);
+ // Invert flips to prevent broken rendering.
+ t.xFlip = false;
+ t.yFlip = false;
+ var tt = new dn.heaps.TiledTexture(w, h, t, wrapper);
+
tt.alpha = alpha;
- tt.x = -w*ed.pivotX + (ld==null ? 0 : ld.pxOffsetX);
- tt.y = -h*ed.pivotY + (ld==null ? 0 : ld.pxOffsetY);
+ tt.x = -w*pivotX + (ld==null ? 0 : ld.pxOffsetX);
+ tt.y = -h*pivotY + (ld==null ? 0 : ld.pxOffsetY);
case Cover:
var bmp = new h2d.Bitmap(wrapper);
@@ -183,11 +195,13 @@ class EntityRender extends dn.Process {
final fw = M.fmin(w, t.width*s) / s;
final fh = M.fmin(h, t.height*s) / s;
bmp.tile = t.sub(
- t.width*ed.pivotX - fw*ed.pivotX,
- t.height*ed.pivotY - fh*ed.pivotY,
+ t.width*pivotX - fw*pivotX,
+ t.height*pivotY - fh*pivotY,
fw,fh
);
- bmp.tile.setCenterRatio(ed.pivotX, ed.pivotY);
+ bmp.tile.xFlip = t.xFlip;
+ bmp.tile.yFlip = t.yFlip;
+ bmp.tile.setCenterRatio(pivotX, pivotY);
bmp.setScale(s);
case FullSizeCropped:
@@ -197,11 +211,13 @@ class EntityRender extends dn.Process {
final fw = M.fmin(w, t.width);
final fh = M.fmin(h, t.height);
bmp.tile = t.sub(
- t.width*ed.pivotX - fw*ed.pivotX,
- t.height*ed.pivotY - fh*ed.pivotY,
+ t.width*pivotX - fw*pivotX,
+ t.height*pivotY - fh*pivotY,
fw, fh
);
- bmp.tile.setCenterRatio(ed.pivotX, ed.pivotY);
+ bmp.tile.xFlip = t.xFlip;
+ bmp.tile.yFlip = t.yFlip;
+ bmp.tile.setCenterRatio(pivotX, pivotY);
bmp.alpha = alpha;
case FullSizeUncropped:
@@ -209,7 +225,7 @@ class EntityRender extends dn.Process {
if( ld!=null )
bmp.setPosition(ld.pxOffsetX, ld.pxOffsetY);
- bmp.tile.setCenterRatio(ed.pivotX, ed.pivotY);
+ bmp.tile.setCenterRatio(pivotX, pivotY);
bmp.alpha = alpha;
case NineSlice:
@@ -223,9 +239,8 @@ class EntityRender extends dn.Process {
sg.tileCenter = true;
sg.width = w;
sg.height = h;
- sg.x = -w*ed.pivotX + (ld==null ? 0 : ld.pxOffsetX);
- sg.y = -h*ed.pivotY + (ld==null ? 0 : ld.pxOffsetY);
-
+ sg.x = -w*pivotX + (ld==null ? 0 : ld.pxOffsetX);
+ sg.y = -h*pivotY + (ld==null ? 0 : ld.pxOffsetY);
}
}
}
@@ -266,11 +281,18 @@ class EntityRender extends dn.Process {
}
// Pivot
+
+ // Adjust pivot rendering position based on our flip statuses.
+ var pivotX = ((ed.flipAroundPivot && flipX) ? ((w - 1) / w) - ed.pivotX : ed.pivotX);
+ var pivotY = ((ed.flipAroundPivot && flipY) ? ((h - 1) / h) - ed.pivotY : ed.pivotY);
+
g.lineStyle(0);
+ // Draw pivot background.
g.beginFill(0x0, 0.4);
- g.drawRect(w*ed.pivotX-1, h*ed.pivotY-1, 3,3);
+ g.drawRect(w*pivotX-1, h*pivotY-1, 3,3);
+ // Draw pivot foreground.
g.beginFill(color, 1);
- g.drawRect(w*ed.pivotX, h*ed.pivotY, 1,1);
+ g.drawRect(w*pivotX, h*pivotY, 1,1);
return {
wrapper: wrapper,
@@ -366,13 +388,15 @@ class EntityRender extends dn.Process {
fieldGraphics.alpha = fullVis ? 1 : ei._li.def.inactiveOpacity;
}
+ var pivX = M.hasBit(ei.flips, 0) ? ed.getFlippedPivotX() : ed.pivotX;
+ var pivY = M.hasBit(ei.flips, 1) ? ed.getFlippedPivotY() : ed.pivotY;
// Identifier
if( identifier!=null ) {
identifier.visible = fullVis || !ei._li.def.hideFieldsWhenInactive;
identifier.setScale(zoomScale);
- identifier.x = Std.int( -ei.width*ed.pivotX - identifier.textWidth*0.5*identifier.scaleX + ei.width*0.5 );
- identifier.y = Std.int( -identifier.textHeight*identifier.scaleY - ei.height*ed.pivotY );
+ identifier.x = Std.int( -ei.width*pivX - identifier.textWidth*0.5*identifier.scaleX + ei.width*0.5 );
+ identifier.y = Std.int( -identifier.textHeight*identifier.scaleY - ei.height*pivY );
}
// Update field wrappers
@@ -380,8 +404,8 @@ class EntityRender extends dn.Process {
above.visible = showFields && above.numChildren>0;
if( above.visible ) {
above.setScale(zoomScale);
- above.x = M.round( -ei.width*ed.pivotX - above.outerWidth*0.5*above.scaleX + ei.width*0.5 );
- above.y = Std.int( -above.outerHeight*above.scaleY - ei.height*ed.pivotY );
+ above.x = M.round( -ei.width*pivX - above.outerWidth*0.5*above.scaleX + ei.width*0.5 );
+ above.y = Std.int( -above.outerHeight*above.scaleY - ei.height*pivY );
if( identifier!=null )
above.y -= identifier.textHeight*identifier.scaleY;
above.alpha = 1;
@@ -390,16 +414,16 @@ class EntityRender extends dn.Process {
center.visible = showFields && center.numChildren>0;
if( center.visible ) {
center.setScale(zoomScale);
- center.x = Std.int( -ei.width*ed.pivotX - center.outerWidth*0.5*center.scaleX + ei.width*0.5 );
- center.y = Std.int( -ei.height*ed.pivotY - center.outerHeight*0.5*center.scaleY + ei.height*0.5);
+ center.x = Std.int( -ei.width*pivX - center.outerWidth*0.5*center.scaleX + ei.width*0.5 );
+ center.y = Std.int( -ei.height*pivY - center.outerHeight*0.5*center.scaleY + ei.height*0.5);
center.alpha = 1;
}
beneath.visible = showFields && beneath.numChildren>0;
if( beneath.visible ) {
beneath.setScale(zoomScale);
- beneath.x = Std.int( -ei.width*ed.pivotX - beneath.outerWidth*0.5*beneath.scaleX + ei.width*0.5 );
- beneath.y = Std.int( ei.height*(1-ed.pivotY) );
+ beneath.x = Std.int( -ei.width*pivX - beneath.outerWidth*0.5*beneath.scaleX + ei.width*0.5 );
+ beneath.y = Std.int( ei.height*(1-pivY) );
beneath.alpha = 1;
}
}
diff --git a/src/electron.renderer/display/LevelRender.hx b/src/electron.renderer/display/LevelRender.hx
index 589b0a084..8fca0734e 100644
--- a/src/electron.renderer/display/LevelRender.hx
+++ b/src/electron.renderer/display/LevelRender.hx
@@ -401,8 +401,8 @@ class LevelRender extends dn.Process {
public inline function bleepEntity(ei:data.inst.EntityInstance, ?overrideColor:Int, spd=1.0) : Bleep {
return bleepLayerRectPx(
ei._li,
- Std.int( (ei.x-ei.width*ei.def.pivotX) * ei._li.def.getScale() ),
- Std.int( (ei.y-ei.height*ei.def.pivotY) * ei._li.def.getScale() ),
+ Std.int( (ei.x-ei.width*ei.getAdjustedPivotX()) * ei._li.def.getScale() ),
+ Std.int( (ei.y-ei.height*ei.getAdjustedPivotY()) * ei._li.def.getScale() ),
ei.width,
ei.height,
overrideColor!=null ? overrideColor : ei.getSmartColor(true),
diff --git a/src/electron.renderer/tool/ResizeTool.hx b/src/electron.renderer/tool/ResizeTool.hx
index 337c1c0d0..bfdc874c9 100644
--- a/src/electron.renderer/tool/ResizeTool.hx
+++ b/src/electron.renderer/tool/ResizeTool.hx
@@ -272,14 +272,14 @@ class ResizeTool extends Tool {
if( ei.customHeight==ei.def.height ) ei.customHeight = null;
switch draggedHandle {
- case Left, TopLeft, BottomLeft: if( ei.def.pivotX==0 ) ei.x -= ( ei.width - oldW );
- case Right, TopRight, BottomRight: if( ei.def.pivotX==1 ) ei.x += ( ei.width - oldW );
+ case Left, TopLeft, BottomLeft: if( ei.getAdjustedPivotX()==0 ) ei.x -= ( ei.width - oldW );
+ case Right, TopRight, BottomRight: if( ei.getAdjustedPivotX()==1 ) ei.x += ( ei.width - oldW );
case _:
}
switch draggedHandle {
- case Top, TopLeft, TopRight: if( ei.def.pivotY==0 ) ei.y -= ( ei.height - oldH );
- case Bottom, BottomLeft, BottomRight: if( ei.def.pivotY==1 ) ei.y += ( ei.height - oldH );
+ case Top, TopLeft, TopRight: if( ei.getAdjustedPivotY()==0 ) ei.y -= ( ei.height - oldH );
+ case Bottom, BottomLeft, BottomRight: if( ei.getAdjustedPivotY()==1 ) ei.y += ( ei.height - oldH );
case _:
}
@@ -314,4 +314,4 @@ class ResizeTool extends Tool {
invalidated = false;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/electron.renderer/tool/lt/EntityTool.hx b/src/electron.renderer/tool/lt/EntityTool.hx
index cf6099800..34be439e8 100644
--- a/src/electron.renderer/tool/lt/EntityTool.hx
+++ b/src/electron.renderer/tool/lt/EntityTool.hx
@@ -4,6 +4,9 @@ class EntityTool extends tool.LayerTool {
public var curEntityDef(get,never) : Null;
static var PREV_CHAINABLE_EI: Null;
+ public var flipX = false;
+ public var flipY = false;
+
public function new() {
super();
@@ -41,7 +44,14 @@ class EntityTool extends tool.LayerTool {
inline function get_curEntityDef() return project.defs.getEntityDef( getSelectedValue() );
override function selectValue(v:Int) {
+ var lastEntityDef = curEntityDef;
super.selectValue(v);
+
+ // Clear flip values ONLY if we have changed entity defs.
+ if ( lastEntityDef!=curEntityDef ) {
+ flipX = false;
+ flipY = false;
+ }
}
override function canEdit():Bool {
@@ -66,14 +76,16 @@ class EntityTool extends tool.LayerTool {
}
function getPlacementX(m:Coords) {
+ var pivot = flipX ? curEntityDef.getFlippedPivotX() : curEntityDef.pivotX;
return snapToGrid()
- ? M.round( ( m.cx + curEntityDef.pivotX ) * curLayerInstance.def.gridSize )
+ ? M.round( ( m.cx * curLayerInstance.def.gridSize ) + pivot * curEntityDef.width )
: m.levelX;
}
function getPlacementY(m:Coords) {
+ var pivot = flipY ? curEntityDef.getFlippedPivotY() : curEntityDef.pivotY;
return snapToGrid()
- ? M.round( ( m.cy + curEntityDef.pivotY ) * curLayerInstance.def.gridSize)
+ ? M.round( ( m.cy * curLayerInstance.def.gridSize ) + pivot * curEntityDef.height )
: m.levelY;
}
@@ -113,7 +125,9 @@ class EntityTool extends tool.LayerTool {
// editor.cursor.overrideNativeCursor("grab");
case _:
- editor.cursor.set( Entity(curLayerInstance, curEntityDef, getPlacementX(m), getPlacementY(m), false) );
+ // Create dummy EntityInstance so that we can draw it with transforms for flips.
+ var dummyEi = new data.inst.EntityInstance(project, null, curEntityDef.uid, "", M.makeBitsFromBools(flipX, flipY));
+ editor.cursor.set( Entity(curLayerInstance, curEntityDef, dummyEi, getPlacementX(m), getPlacementY(m), false) );
}
ev.cancel = true;
updateChainRefPreview(m);
@@ -192,6 +206,7 @@ class EntityTool extends tool.LayerTool {
// Finalize entity
ei.x = getPlacementX(m);
ei.y = getPlacementY(m);
+ ei.flips = M.makeBitsFromBools(flipX, flipY);
onEditAnything();
stopUsing(m);
if( ei.def.isResizable() ) {
@@ -405,4 +420,25 @@ class EntityTool extends tool.LayerTool {
if( PREV_CHAINABLE_EI!=null && PREV_CHAINABLE_EI._li!=null && !PREV_CHAINABLE_EI._li.containsEntity(PREV_CHAINABLE_EI) )
cancelRefChaining();
}
-}
\ No newline at end of file
+
+ override function onKeyPress(keyId:Int) {
+ super.onKeyPress(keyId);
+
+ if ( !Editor.ME.hasInputFocus() )
+ switch keyId {
+ case K.X if ( curEntityDef!=null && curEntityDef.flippableX && !App.ME.hasAnyToggleKeyDown() ):
+ flipX = !flipX;
+ N.quick("X-flip: "+L.onOff(flipX));
+ customCursor(new hxd.Event(EMove), lastMouse);
+ // Simulate mouse movement to recenter entity render.
+ editor.cursor.onMouseMove(lastMouse);
+
+ case K.Y if ( curEntityDef!=null && curEntityDef.flippableY && !App.ME.hasAnyToggleKeyDown() ):
+ flipY = !flipY;
+ N.quick("Y-flip: "+L.onOff(flipY));
+ customCursor(new hxd.Event(EMove), lastMouse);
+ // Simulate mouse movement to recenter entity render.
+ editor.cursor.onMouseMove(lastMouse);
+ }
+ }
+}
diff --git a/src/electron.renderer/ui/Cursor.hx b/src/electron.renderer/ui/Cursor.hx
index 31b2080b7..b55cdc151 100644
--- a/src/electron.renderer/ui/Cursor.hx
+++ b/src/electron.renderer/ui/Cursor.hx
@@ -203,14 +203,14 @@ class Cursor {
final ry = ei.height*0.5;
g.lineStyle(1, 0xffcc00, 1);
g.drawEllipse(
- (0.5-def.pivotX)*ei.width, (0.5-def.pivotY)*ei.height,
+ (0.5-ei.getAdjustedPivotX())*ei.width, (0.5-ei.getAdjustedPivotY())*ei.height,
rx+pad, ry+pad,
0, rx<=16 && ry<=16 ? 24 : 0
);
case Rectangle, Tile:
g.lineStyle(1, 0xffcc00, 1);
- renderBeveledRect(g, -def.pivotX*ei.width-pad, -def.pivotY*ei.height-pad, ei.width+pad*2, ei.height+pad*2);
+ renderBeveledRect(g, -ei.getAdjustedPivotX()*ei.width-pad, -ei.getAdjustedPivotY()*ei.height-pad, ei.width+pad*2, ei.height+pad*2);
}
}
@@ -363,4 +363,4 @@ class Cursor {
render();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/electron.renderer/ui/EntityInstanceEditor.hx b/src/electron.renderer/ui/EntityInstanceEditor.hx
index b119c68bb..9005df4d8 100644
--- a/src/electron.renderer/ui/EntityInstanceEditor.hx
+++ b/src/electron.renderer/ui/EntityInstanceEditor.hx
@@ -268,6 +268,33 @@ class EntityInstanceEditor extends dn.Process {
if( UNIT_GRID )
i.setUnit(ei._li.def.gridSize);
+ // Flip block
+ var jFlips = jPropsForm.find(".flips");
+
+ // X
+ var i = new form.input.BoolInput(
+ jFlips.find("[name=x]"),
+ ()->(M.hasBit(ei.flips,0)),
+ (v)->{
+ ei.flips = M.makeBitsFromBools(!M.hasBit(ei.flips, 0), M.hasBit(ei.flips, 1));
+ }
+ );
+ i.setEnabled( ei.def.flippableX );
+ i.linkEvent( EntityInstanceChanged(ei) );
+ i.onChange = ()->onEntityFieldChanged();
+
+ // Y
+ var i = new form.input.BoolInput(
+ jFlips.find("[name=y]"),
+ ()->(M.hasBit(ei.flips,1)),
+ (v)->{
+ ei.flips = M.makeBitsFromBools(M.hasBit(ei.flips, 0), !M.hasBit(ei.flips, 1));
+ }
+ );
+ i.setEnabled( ei.def.flippableY );
+ i.linkEvent( EntityInstanceChanged(ei) );
+ i.onChange = ()->onEntityFieldChanged();
+
// References to this
var refs = project.getEntityInstancesReferingTo(ei);
@@ -327,4 +354,4 @@ class EntityInstanceEditor extends dn.Process {
if( !isOccupied && jWindow.hasClass("faded") )
jWindow.removeClass("faded");
}
-}
\ No newline at end of file
+}
diff --git a/src/electron.renderer/ui/modal/panel/EditEntityDefs.hx b/src/electron.renderer/ui/modal/panel/EditEntityDefs.hx
index 8af6835ea..2245d2e9f 100644
--- a/src/electron.renderer/ui/modal/panel/EditEntityDefs.hx
+++ b/src/electron.renderer/ui/modal/panel/EditEntityDefs.hx
@@ -227,6 +227,15 @@ class EditEntityDefs extends ui.modal.Panel {
i.linkEvent(EntityDefChanged);
i.setEnabled( curEntity.resizableX && curEntity.resizableY );
+ // Flippable
+ var i = Input.linkToHtmlInput( curEntity.flippableX, jEntityForm.find("input#flippableX") );
+ i.onChange = editor.ge.emit.bind(EntityDefChanged);
+ var i = Input.linkToHtmlInput( curEntity.flippableY, jEntityForm.find("input#flippableY") );
+ i.onChange = editor.ge.emit.bind(EntityDefChanged);
+
+ var i = Input.linkToHtmlInput( curEntity.flipAroundPivot, jEntityForm.find("input#flipAroundPivot") );
+ i.onChange = editor.ge.emit.bind(EntityDefChanged);
+
var i = Input.linkToHtmlInput( curEntity.height, jEntityForm.find("input[name='height']") );
i.setBounds(1,2048);
i.onChange = editor.ge.emit.bind(EntityDefChanged);