diff --git a/assets/images/editors/ui/context-bg-debug.png b/assets/images/editors/ui/context-bg-debug.png
new file mode 100644
index 00000000..aa83123f
Binary files /dev/null and b/assets/images/editors/ui/context-bg-debug.png differ
diff --git a/assets/images/editors/ui/context-bg-debug.xml b/assets/images/editors/ui/context-bg-debug.xml
new file mode 100644
index 00000000..6eb3c21a
--- /dev/null
+++ b/assets/images/editors/ui/context-bg-debug.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/funkin/editors/UIDebugState.hx b/source/funkin/editors/UIDebugState.hx
index 3a0bf57f..6b621e92 100644
--- a/source/funkin/editors/UIDebugState.hx
+++ b/source/funkin/editors/UIDebugState.hx
@@ -101,11 +101,8 @@ class UIDebugState extends UIState {
}, 130, 48));
add(new UITextBox(10, 220, ""));
- var spliceSprite:UISliceSprite = new UISliceSprite(650, 350, 30, 30, "editors/ui/context-bg");
+ var spliceSprite:UISliceSprite = new UISliceSprite(650, 300, 200, 200, "editors/ui/context-bg-debug");
add(spliceSprite);
- FlxTween.num(0, 1, 2, {type: PINGPONG}, function (v:Float) {
- spliceSprite.bWidth = Std.int(lerp(12, 200, v)); spliceSprite.bHeight = Std.int(lerp(12, 200, v));
- });
}
public override function update(elapsed:Float) {
diff --git a/source/funkin/editors/ui/UISliceSprite.hx b/source/funkin/editors/ui/UISliceSprite.hx
index 256c574d..63bea2b2 100644
--- a/source/funkin/editors/ui/UISliceSprite.hx
+++ b/source/funkin/editors/ui/UISliceSprite.hx
@@ -1,10 +1,13 @@
package funkin.editors.ui;
+import flixel.math.FlxRect;
import flixel.graphics.frames.FlxFrame;
+import flixel.graphics.tile.FlxGraphicsShader;
+import flixel.graphics.tile.FlxDrawTrianglesItem.DrawData;
class UISliceSprite extends UISprite {
- public var bWidth:Int = 120;
- public var bHeight:Int = 20;
+ public var bWidth(default, set):Int = 120;
+ public var bHeight(default, set):Int = 20;
public var framesOffset(default, set):Int = 0;
public var incorporeal:Bool = false;
@@ -14,7 +17,9 @@ class UISliceSprite extends UISprite {
frames = Paths.getFrames(path);
resize(w, h);
+
calculateFrames();
+ __genMesh();
}
public override function updateButton() {
@@ -56,14 +61,15 @@ class UISliceSprite extends UISprite {
override function set_frames(val) {
super.set_frames(val);
- calculateFrames();
+ __framesDirty = true;
+ __meshDirty = true;
return val;
}
function set_framesOffset(value:Int) {
if(value != framesOffset) {
framesOffset = value;
- calculateFrames();
+ __framesDirty = true;
}
return value;
}
@@ -84,125 +90,226 @@ class UISliceSprite extends UISprite {
rightWidth = Std.int(Math.max(topright.frame.width, Math.max(middleright.frame.width, bottomright.frame.width)));
topHeight = Std.int(Math.max(topleft.frame.height, Math.max(top.frame.height, topright.frame.height)));
bottomHeight = Std.int(Math.max(topleft.frame.height, Math.max(top.frame.height, topright.frame.height)));
+
+ __genUVs();
}
public override function draw() @:privateAccess {
- var lastPixelPerfect:Bool = cameras[0] != null ? cameras[0].pixelPerfectRender : false;
- if (cameras[0] != null) cameras[0].pixelPerfectRender = false;
-
- var x:Float = this.x;
- var y:Float = this.y;
+ checkEmptyFrame();
- if (visible && !(bWidth == 0 || bHeight == 0)) {
- var oldAlpha = alpha;
- // TOP
- if (drawTop) {
- // TOP LEFT
- if(topAlpha != null) alpha = topAlpha;
- frame = topleft;
- setPosition(x, y);
- __setSize(
- topleft.frame.width * Math.min(bWidth/(topleft.frame.width*2), 1),
- topleft.frame.height * Math.min(bHeight/(topleft.frame.height*2), 1)
+ if (alpha == 0 || _frame.type == FlxFrameType.EMPTY)
+ return;
+
+ if (__framesDirty) calculateFrames();
+ if (__meshDirty) __genMesh();
+
+ for (camera in cameras)
+ {
+ if (!camera.visible || !camera.exists || !isOnScreen(camera))
+ continue;
+
+ getScreenPosition(_point, camera).subtractPoint(offset);
+
+ #if !flash
+ camera.drawTriangles(graphic, vertices, indices, uvtData, colors, _point, blend, false, antialiasing, colorTransform, shader);
+ #else
+ camera.drawTriangles(graphic, vertices, indices, uvtData, colors, _point, blend, false, antialiasing);
+ #end
+
+ #if FLX_DEBUG
+ FlxBasic.visibleCount++;
+ #end
+ }
+
+ super.drawMembers();
+ __lastDrawCameras = cameras.copy();
+ }
+
+ var vertices:DrawData = new DrawData();
+ var indices:DrawData = new DrawData();
+ var uvtData:DrawData = new DrawData();
+ var colors:DrawData = new DrawData();
+
+ var __framesDirty:Bool = false;
+ var __meshDirty:Bool = false;
+
+ public function set_bWidth(value:Int):Int {
+ if(value != bWidth) {
+ bWidth = value;
+ __meshDirty = true;
+ }
+ return value;
+ }
+
+ public function set_bHeight(value:Int):Int {
+ if(value != bHeight) {
+ bHeight = value;
+ __meshDirty = true;
+ }
+ return value;
+ }
+
+ private inline function __genMesh() {
+ indices.length = 0;
+ vertices.length = 0;
+
+ // TOP PART
+ if (drawTop) {
+ // TOP LEFT
+ var topLeftWidth:Float = topleft.frame.width * Math.min(bWidth / (topleft.frame.width * 2), 1);
+ var topLeftHeight:Float = topleft.frame.height * Math.min(bHeight / (topleft.frame.height * 2), 1);
+ __genSliceTri(
+ 0, 0,
+ topLeftWidth, topLeftHeight
+ );
+
+ // TOP MIDDLE
+ if (bWidth > topleft.frame.width + topright.frame.width) {
+ var topWidth:Float = bWidth - topleft.frame.width - topright.frame.width;
+ var topHeight:Float = top.frame.height * Math.min(bHeight / (top.frame.height * 2), 1);
+ __genSliceTri(
+ topLeftWidth, 0,
+ topWidth, topHeight
);
- super.drawSuper();
-
- // TOP
- if (bWidth > topleft.frame.width + topright.frame.width) {
- frame = top;
- setPosition(x + topleft.frame.width, y);
- __setSize(bWidth - topleft.frame.width - topright.frame.width, top.frame.height * Math.min(bHeight/(top.frame.height*2), 1));
- super.drawSuper();
- }
-
- // TOP RIGHT
- setPosition(x + bWidth - (topright.frame.width * Math.min(bWidth/(topright.frame.width*2), 1)), y);
- frame = topright;
- __setSize(
- topright.frame.width * Math.min(bWidth/(topright.frame.width*2), 1),
- topright.frame.height * Math.min(bHeight/(topright.frame.height*2), 1)
- );
- super.drawSuper();
}
+ // TOP RIGHT
+ var topRightWidth:Float = topright.frame.width * Math.min(bWidth/(topright.frame.width*2), 1);
+ var topRightHeight:Float = topright.frame.height * Math.min(bHeight/(topright.frame.height*2), 1);
+ __genSliceTri(
+ bWidth - (topright.frame.width * Math.min(bWidth/(topright.frame.width*2), 1)), 0,
+ topRightWidth, topRightHeight
+ );
+ }
+
+ if (drawMiddle && bHeight > top.frame.height + bottom.frame.height) {
+ var middleHeight:Float = bHeight - (topleft.frame.height * Math.min(bHeight/(topleft.frame.height*2), 1)) -
+ bottomleft.frame.height * Math.min(bHeight/(bottomleft.frame.height*2), 1);
+
+ // MIDDLE LEFT
+ var middleLeftWidth:Float = middleleft.frame.width * Math.min(bWidth/(middleleft.frame.width*2), 1);
+ __genSliceTri(
+ 0, top.frame.height,
+ middleLeftWidth, middleHeight
+ );
+
// MIDDLE
- if (drawMiddle && bHeight > top.frame.height + bottom.frame.height) {
- if(middleAlpha != null) alpha = middleAlpha;
- var middleHeight:Float = bHeight - (topleft.frame.height * Math.min(bHeight/(topleft.frame.height*2), 1)) -
- bottomleft.frame.height * Math.min(bHeight/(bottomleft.frame.height*2), 1);
-
- // MIDDLE LEFT
- frame = middleleft;
- setPosition(x, y + top.frame.height);
- __setSize(middleleft.frame.width * Math.min(bWidth/(middleleft.frame.width*2), 1), middleHeight);
- super.drawSuper();
-
- if (bWidth > (middleleft.frame.width * Math.min(bWidth/(middleleft.frame.width*2), 1)) + middleright.frame.width) {
- // MIDDLE
- frame = middle;
- setPosition(x + topleft.frame.width, y + top.frame.height);
- __setSize(bWidth - middleleft.frame.width - middleright.frame.width, middleHeight);
- super.drawSuper();
- }
-
- // MIDDLE RIGHT
- frame = middleright;
- setPosition(x + bWidth - (topright.frame.width * Math.min(bWidth/(topright.frame.width*2), 1)), y + top.frame.height);
- __setSize(middleright.frame.width * Math.min(bWidth/(middleright.frame.width*2), 1), middleHeight);
- super.drawSuper();
+ if (bWidth > (middleleft.frame.width * Math.min(bWidth/(middleleft.frame.width*2), 1)) + middleright.frame.width) {
+ var middleWidth:Float = bWidth - middleleft.frame.width - middleright.frame.width;
+ __genSliceTri(
+ topleft.frame.width, top.frame.height,
+ middleWidth, middleHeight
+ );
}
- // BOTTOM
- if (drawBottom) {
- if(bottomAlpha != null) alpha = bottomAlpha;
- // BOTTOM LEFT
- frame = bottomleft;
- setPosition(x, y + bHeight - (bottomleft.frame.height * Math.min(bHeight/(bottomleft.frame.height*2), 1)));
- __setSize(
- bottomleft.frame.width * Math.min(bWidth/(bottomleft.frame.width*2), 1),
- bottomleft.frame.height * Math.min(bHeight/(bottomleft.frame.height*2), 1)
- );
- super.drawSuper();
-
- if (bWidth > bottomleft.frame.width + bottomright.frame.width) {
- // BOTTOM
- frame = bottom;
- setPosition(x + bottomleft.frame.width, y + bHeight - (bottom.frame.height * Math.min(bHeight/(bottom.frame.height*2), 1)));
- __setSize(bWidth - bottomleft.frame.width - bottomright.frame.width, bottom.frame.height * Math.min(bHeight/(bottom.frame.height*2), 1));
- super.drawSuper();
- }
-
- // BOTTOM RIGHT
- frame = bottomright;
- setPosition(
- x + bWidth - (bottomright.frame.width * Math.min(bWidth/(bottomright.frame.width*2), 1)),
- y + bHeight - (bottomright.frame.height * Math.min(bHeight/(bottomright.frame.height*2), 1))
- );
- __setSize(
- bottomright.frame.width * Math.min(bWidth/(bottomright.frame.width*2), 1),
- bottomright.frame.height * Math.min(bHeight/(bottomright.frame.height*2), 1)
- );
- super.drawSuper();
-
- }
- alpha = oldAlpha;
+ // MIDDLE RIGHT
+ var middleRightWidth:Float = middleright.frame.width * Math.min(bWidth/(middleright.frame.width*2), 1);
+ __genSliceTri(
+ bWidth - (topright.frame.width * Math.min(bWidth/(topright.frame.width*2), 1)), top.frame.height,
+ middleRightWidth, middleHeight
+ );
}
- if (cameras[0] != null) cameras[0].pixelPerfectRender = lastPixelPerfect;
- setPosition(x, y);
- super.drawMembers();
+ // BOTTOM
+ if (drawBottom) {
+ // BOTTOM LEFT
+ var bottomLeftWidth:Float = bottomleft.frame.width * Math.min(bWidth/(bottomleft.frame.width*2), 1);
+ var bottomLeftHeight:Float = bottomleft.frame.height * Math.min(bHeight/(bottomleft.frame.height*2), 1);
+ __genSliceTri(
+ 0, bHeight - (bottomleft.frame.height * Math.min(bHeight/(bottomleft.frame.height*2), 1)),
+ bottomLeftWidth, bottomLeftHeight
+ );
+
+ // BOTTOM MIDDLE
+ if (bWidth > bottomleft.frame.width + bottomright.frame.width) {
+ var bottomMiddleWidth:Float = bWidth - bottomleft.frame.width - bottomright.frame.width;
+ var bottomMiddleHeight:Float = bottom.frame.height * Math.min(bHeight/(bottom.frame.height*2), 1);
+ __genSliceTri(
+ bottomleft.frame.width, bHeight - (bottom.frame.height * Math.min(bHeight/(bottom.frame.height*2), 1)),
+ bottomMiddleWidth, bottomMiddleHeight
+ );
+ }
+
+ // BOTTOM RIGHT
+ var bottomRightWidth:Float = bottomright.frame.width * Math.min(bWidth/(bottomright.frame.width*2), 1);
+ var bottomRightHeight:Float = bottomright.frame.height * Math.min(bHeight/(bottomright.frame.height*2), 1);
+ __genSliceTri(
+ bWidth - (bottomright.frame.width * Math.min(bWidth/(bottomright.frame.width*2), 1)),
+ bHeight - (bottomright.frame.height * Math.min(bHeight/(bottomright.frame.height*2), 1)),
+ bottomRightWidth, bottomRightHeight
+ );
+ }
+
+ __meshDirty = false;
}
- private function __setSize(Width:Float, Height:Float) {
- var newScaleX:Float = Width / frameWidth;
- var newScaleY:Float = Height / frameHeight;
- scale.set(newScaleX, newScaleY);
+ private inline function __genUVs() {
+ uvtData.length = 0;
- if (Width <= 0)
- scale.x = newScaleY;
- else if (Height <= 0)
- scale.y = newScaleX;
+ __genSliceUV(topleft);
+ __genSliceUV(top);
+ __genSliceUV(topright);
+ __genSliceUV(middleleft);
+ __genSliceUV(middle);
+ __genSliceUV(middleright);
+ __genSliceUV(bottomleft);
+ __genSliceUV(bottom);
+ __genSliceUV(bottomright);
- updateHitbox();
+ __framesDirty = false;
+ }
+
+ private inline function __genSliceTri(x:Float, y:Float, width:Float, height:Float) {
+ var indicesOffset:Int = Std.int(vertices.length / 2);
+
+ indices.push(indicesOffset);
+ indices.push(indicesOffset + 1);
+ indices.push(indicesOffset + 2);
+ indices.push(indicesOffset);
+ indices.push(indicesOffset + 2);
+ indices.push(indicesOffset + 3);
+
+ vertices.push(x);
+ vertices.push(y);
+ vertices.push(x + width);
+ vertices.push(y);
+ vertices.push(x + width);
+ vertices.push(y + height);
+ vertices.push(x);
+ vertices.push(y + height);
+ }
+
+ private inline function __genSliceUV(frame:FlxFrame) {
+ uvtData.push(frame.uv.x);
+ uvtData.push(frame.uv.y);
+ uvtData.push(frame.uv.width);
+ uvtData.push(frame.uv.y);
+ uvtData.push(frame.uv.width);
+ uvtData.push(frame.uv.height);
+ uvtData.push(frame.uv.x);
+ uvtData.push(frame.uv.height);
+ }
+
+ @:access(flixel.FlxCamera)
+ override function getBoundingBox(camera:FlxCamera):FlxRect {
+ getScreenPosition(_point, camera);
+
+ _rect.set(_point.x, _point.y, bWidth, bHeight);
+ _rect = camera.transformRect(_rect);
+
+ // if (isPixelPerfectRender(camera))
+ // _rect.floor();
+
+ return _rect;
+ }
+
+ override public function destroy():Void
+ {
+ vertices = null;
+ indices = null;
+ uvtData = null;
+ colors = null;
+
+ super.destroy();
}
}
\ No newline at end of file