diff --git a/assets/images/editors/ui/warning-popup.png b/assets/images/editors/ui/warning-popup.png
new file mode 100644
index 00000000..d7fc0ec6
Binary files /dev/null and b/assets/images/editors/ui/warning-popup.png differ
diff --git a/assets/images/editors/ui/warning-popup.xml b/assets/images/editors/ui/warning-popup.xml
new file mode 100644
index 00000000..021dd81a
--- /dev/null
+++ b/assets/images/editors/ui/warning-popup.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/shaders/editorBlur.frag b/assets/shaders/editorBlur.frag
new file mode 100644
index 00000000..929c65cf
--- /dev/null
+++ b/assets/shaders/editorBlur.frag
@@ -0,0 +1,25 @@
+#pragma header
+#define PI 3.14159265359
+
+int steps = 16;
+int stepsInside = 2;
+float strength = 0.0075;
+void main() {
+ vec4 color = flixel_texture2D(bitmap, openfl_TextureCoordv);
+ float fsteps = steps;
+ for(float inside = 1; inside < stepsInside+1; inside++) {
+ for(int i = 0; i < steps; i++) {
+ float fi = i;
+ color += flixel_texture2D(bitmap, openfl_TextureCoordv + vec2(strength * (inside / stepsInside) * cos(fi / fsteps * (PI * 2.0)), strength * (inside / stepsInside) * sin(fi / fsteps * (PI * 2.0))));
+ }
+ }
+ /*
+ for(int x = -steps; x < steps+1; x++) {
+ for(int y = -steps; y < steps+1; y++) {
+ color += flixel_texture2D(bitmap, openfl_TextureCoordv + vec2(strength / steps * x, strength / steps * y));
+ }
+ }
+ */
+ color /= steps * stepsInside * 1.25;
+ gl_FragColor = color;
+}
\ No newline at end of file
diff --git a/assets/sounds/menu/warningMenu.mp3 b/assets/sounds/menu/warningMenu.mp3
new file mode 100644
index 00000000..c82f0a1f
Binary files /dev/null and b/assets/sounds/menu/warningMenu.mp3 differ
diff --git a/assets/sounds/menu/warningMenu.ogg b/assets/sounds/menu/warningMenu.ogg
new file mode 100644
index 00000000..cccaa129
Binary files /dev/null and b/assets/sounds/menu/warningMenu.ogg differ
diff --git a/buildnumber.txt b/buildnumber.txt
index 64d4e291..d567531c 100644
--- a/buildnumber.txt
+++ b/buildnumber.txt
@@ -1 +1 @@
-2526
\ No newline at end of file
+2534
\ No newline at end of file
diff --git a/source/funkin/editors/UIDebugState.hx b/source/funkin/editors/UIDebugState.hx
index 0aa8fdea..cd2377e9 100644
--- a/source/funkin/editors/UIDebugState.hx
+++ b/source/funkin/editors/UIDebugState.hx
@@ -16,5 +16,21 @@ class UIDebugState extends UIState {
add(new UIButton(10, 70, "Test button", function() {
trace("Hello, World!");
}, 120, 32));
+ add(new UIButton(10, 110, "Warning test", function() {
+ openSubState(new UIWarningSubstate("Test", "This is a test message", [
+ {
+ label: "Alt. Choice",
+ onClick: function(t) {
+
+ }
+ },
+ {
+ label: "OK",
+ onClick: function(t) {
+
+ }
+ }
+ ]));
+ }, 120, 32));
}
}
\ No newline at end of file
diff --git a/source/funkin/editors/ui/UIButton.hx b/source/funkin/editors/ui/UIButton.hx
index 971b30e2..2bc140ef 100644
--- a/source/funkin/editors/ui/UIButton.hx
+++ b/source/funkin/editors/ui/UIButton.hx
@@ -2,36 +2,26 @@ package funkin.editors.ui;
import flixel.graphics.frames.FlxFrame;
-class UIButton extends UISprite {
- public var bWidth:Int = 120;
- public var bHeight:Int = 20;
+class UIButton extends UISpliceSprite {
public var callback:Void->Void = null;
public var field:UIText;
- public function resize(w:Int, h:Int) {
- bWidth = w;
- bHeight = h;
- field.fieldWidth = w;
- }
-
- public override function new(x:Float, y:Float, text:String, callback:Void->Void, w:Float = 120, h:Float = 32) {
- super(x, y);
- frames = CoolUtil.loadFrames(Paths.image('editors/ui/button'));
+ public override function new(x:Float, y:Float, text:String, callback:Void->Void, w:Int = 120, h:Int = 32) {
+ super(x, y, w, h, 'editors/ui/button');
this.callback = callback;
members.push(field = new UIText(x, y, w, text));
field.borderStyle = OUTLINE;
field.borderColor = 0x88000000;
field.borderSize = 1;
field.alignment = CENTER;
+ field.fieldWidth = w;
}
- public override function updateButton() {
- __rect.x = x;
- __rect.y = y;
- __rect.width = bWidth;
- __rect.height = bHeight;
- UIState.state.updateRectButtonHandler(this, __rect, onHovered);
+ public override function resize(w:Int, h:Int) {
+ super.resize(w, h);
+ if (field != null)
+ field.fieldWidth = w;
}
public override function onHovered() {
@@ -41,93 +31,8 @@ class UIButton extends UISprite {
}
public override function draw() {
- var x:Float = this.x;
- var y:Float = this.y;
- var offset:Int = hovered ? (pressed ? 18 : 9) : 0;
-
- var topleft:FlxFrame = frames.frames[offset];
- var top:FlxFrame = frames.frames[offset + 1];
- var topright:FlxFrame = frames.frames[offset + 2];
- var middleleft:FlxFrame = frames.frames[offset + 3];
- var middle:FlxFrame = frames.frames[offset + 4];
- var middleright:FlxFrame = frames.frames[offset + 5];
- var bottomleft:FlxFrame = frames.frames[offset + 6];
- var bottom:FlxFrame = frames.frames[offset + 7];
- var bottomright:FlxFrame = frames.frames[offset + 8];
-
- @:privateAccess {
- // TOP LEFT
- frame = topleft;
- setPosition(x, y);
- __setSize(topleft.frame.width, topleft.frame.height);
- super.drawSuper();
-
- // TOP
- frame = top;
- setPosition(x + topleft.frame.width, y);
- __setSize(bWidth - topleft.frame.width - topright.frame.width, top.frame.height);
- super.drawSuper();
-
- // TOP RIGHT
- frame = topright;
- setPosition(x + bWidth - topright.frame.width, y);
- __setSize(topright.frame.width, topright.frame.height);
- super.drawSuper();
-
- // MIDDLE LEFT
- frame = middleleft;
- setPosition(x, y + top.frame.height);
- __setSize(middleleft.frame.width, bHeight - topleft.frame.height - bottomleft.frame.height);
- super.drawSuper();
-
- // MIDDLE
- frame = middle;
- setPosition(x + topleft.frame.width, y + top.frame.height);
- __setSize(bWidth - middleleft.frame.width - middleright.frame.width, bHeight - topleft.frame.height - bottomleft.frame.height);
- super.drawSuper();
-
- // MIDDLE RIGHT
- frame = middleright;
- setPosition(x + bWidth - topright.frame.width, y + top.frame.height);
- __setSize(middleright.frame.width, bHeight - topleft.frame.height - bottomleft.frame.height);
- super.drawSuper();
-
- // BOTTOM LEFT
- frame = bottomleft;
- setPosition(x, y + bHeight - bottom.frame.height);
- __setSize(bottomleft.frame.width, bottomleft.frame.height);
- super.drawSuper();
-
- // BOTTOM
- frame = bottom;
- setPosition(x + bottomleft.frame.width, y + bHeight - bottom.frame.height);
- __setSize(bWidth - bottomleft.frame.width - bottomright.frame.width, bottom.frame.height);
- super.drawSuper();
-
- // BOTTOM RIGHT
- frame = bottomright;
- setPosition(x + bWidth - bottomright.frame.width, y + bHeight - bottom.frame.height);
- __setSize(bottomright.frame.width, bottomright.frame.height);
- super.drawSuper();
- }
-
- setPosition(x, y);
-
- field.follow(this, 0, ((bHeight - field.height) / 2));
-
- super.drawMembers();
- }
-
- private function __setSize(Width:Float, Height:Float) {
- var newScaleX:Float = Width / frameWidth;
- var newScaleY:Float = Height / frameHeight;
- scale.set(newScaleX, newScaleY);
-
- if (Width <= 0)
- scale.x = newScaleY;
- else if (Height <= 0)
- scale.y = newScaleX;
-
- updateHitbox();
+ framesOffset = hovered ? (pressed ? 18 : 9) : 0;
+ field.follow(this, x, (bHeight - field.height) / 2);
+ super.draw();
}
}
\ No newline at end of file
diff --git a/source/funkin/editors/ui/UISpliceSprite.hx b/source/funkin/editors/ui/UISpliceSprite.hx
new file mode 100644
index 00000000..9c31a8f1
--- /dev/null
+++ b/source/funkin/editors/ui/UISpliceSprite.hx
@@ -0,0 +1,117 @@
+package funkin.editors.ui;
+
+import flixel.graphics.frames.FlxFrame;
+
+class UISpliceSprite extends UISprite {
+ public var bWidth:Int = 120;
+ public var bHeight:Int = 20;
+ public var framesOffset:Int = 0;
+
+ public function new(x:Float, y:Float, w:Int, h:Int, path:String) {
+ super(x, y);
+
+ frames = CoolUtil.loadFrames(Paths.image(path));
+ resize(w, h);
+ }
+
+ public override function updateButton() {
+ __rect.x = x;
+ __rect.y = y;
+ __rect.width = bWidth;
+ __rect.height = bHeight;
+ UIState.state.updateRectButtonHandler(this, __rect, onHovered);
+ }
+
+ public function resize(w:Int, h:Int) {
+ bWidth = w;
+ bHeight = h;
+ }
+
+ public override function draw() {
+ var x:Float = this.x;
+ var y:Float = this.y;
+
+ var topleft:FlxFrame = frames.frames[framesOffset];
+ var top:FlxFrame = frames.frames[framesOffset + 1];
+ var topright:FlxFrame = frames.frames[framesOffset + 2];
+ var middleleft:FlxFrame = frames.frames[framesOffset + 3];
+ var middle:FlxFrame = frames.frames[framesOffset + 4];
+ var middleright:FlxFrame = frames.frames[framesOffset + 5];
+ var bottomleft:FlxFrame = frames.frames[framesOffset + 6];
+ var bottom:FlxFrame = frames.frames[framesOffset + 7];
+ var bottomright:FlxFrame = frames.frames[framesOffset + 8];
+
+ @:privateAccess {
+ // TOP LEFT
+ frame = topleft;
+ setPosition(x, y);
+ __setSize(topleft.frame.width, topleft.frame.height);
+ super.drawSuper();
+
+ // TOP
+ frame = top;
+ setPosition(x + topleft.frame.width, y);
+ __setSize(bWidth - topleft.frame.width - topright.frame.width, top.frame.height);
+ super.drawSuper();
+
+ // TOP RIGHT
+ frame = topright;
+ setPosition(x + bWidth - topright.frame.width, y);
+ __setSize(topright.frame.width, topright.frame.height);
+ super.drawSuper();
+
+ // MIDDLE LEFT
+ frame = middleleft;
+ setPosition(x, y + top.frame.height);
+ __setSize(middleleft.frame.width, bHeight - topleft.frame.height - bottomleft.frame.height);
+ super.drawSuper();
+
+ // MIDDLE
+ frame = middle;
+ setPosition(x + topleft.frame.width, y + top.frame.height);
+ __setSize(bWidth - middleleft.frame.width - middleright.frame.width, bHeight - topleft.frame.height - bottomleft.frame.height);
+ super.drawSuper();
+
+ // MIDDLE RIGHT
+ frame = middleright;
+ setPosition(x + bWidth - topright.frame.width, y + top.frame.height);
+ __setSize(middleright.frame.width, bHeight - topleft.frame.height - bottomleft.frame.height);
+ super.drawSuper();
+
+ // BOTTOM LEFT
+ frame = bottomleft;
+ setPosition(x, y + bHeight - bottom.frame.height);
+ __setSize(bottomleft.frame.width, bottomleft.frame.height);
+ super.drawSuper();
+
+ // BOTTOM
+ frame = bottom;
+ setPosition(x + bottomleft.frame.width, y + bHeight - bottom.frame.height);
+ __setSize(bWidth - bottomleft.frame.width - bottomright.frame.width, bottom.frame.height);
+ super.drawSuper();
+
+ // BOTTOM RIGHT
+ frame = bottomright;
+ setPosition(x + bWidth - bottomright.frame.width, y + bHeight - bottom.frame.height);
+ __setSize(bottomright.frame.width, bottomright.frame.height);
+ super.drawSuper();
+ }
+
+ setPosition(x, y);
+
+ super.drawMembers();
+ }
+
+ private function __setSize(Width:Float, Height:Float) {
+ var newScaleX:Float = Width / frameWidth;
+ var newScaleY:Float = Height / frameHeight;
+ scale.set(newScaleX, newScaleY);
+
+ if (Width <= 0)
+ scale.x = newScaleY;
+ else if (Height <= 0)
+ scale.y = newScaleX;
+
+ updateHitbox();
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/editors/ui/UIWarningSubstate.hx b/source/funkin/editors/ui/UIWarningSubstate.hx
new file mode 100644
index 00000000..60343367
--- /dev/null
+++ b/source/funkin/editors/ui/UIWarningSubstate.hx
@@ -0,0 +1,72 @@
+package funkin.editors.ui;
+
+import flixel.tweens.FlxTween;
+import flixel.tweens.FlxEase;
+import funkin.shaders.CustomShader;
+
+class UIWarningSubstate extends MusicBeatSubstate {
+ var camShaders:Array = [];
+ var blurShader:CustomShader = new CustomShader("editorBlur");
+
+ var title:String;
+ var message:String;
+ var buttons:Array;
+
+ var titleSpr:UIText;
+ var messageSpr:UIText;
+
+ public override function onSubstateOpen() {
+ super.onSubstateOpen();
+ parent.persistentUpdate = false;
+ parent.persistentDraw = true;
+ }
+
+ public override function create() {
+ for(c in FlxG.cameras.list) {
+ camShaders.push(c);
+ c.addShader(blurShader);
+ }
+
+ camera = new FlxCamera();
+ camera.bgColor = 0;
+ camera.alpha = 0;
+ camera.zoom = 0.1;
+ FlxG.cameras.add(camera, false);
+
+ var spr = new UISpliceSprite(0, 0, 560, 280, "editors/ui/warning-popup");
+ spr.x = (FlxG.width - spr.bWidth) / 2;
+ spr.y = (FlxG.height - spr.bHeight) / 2;
+ add(spr);
+
+
+ add(titleSpr = new UIText(spr.x + 25, spr.y, spr.bWidth - 50, title, 15, -1));
+ titleSpr.y = spr.y + ((30 - titleSpr.height) / 2);
+
+ add(messageSpr = new UIText(spr.x + 10, spr.y + 40, spr.bWidth - 20, message, 15, 0xFF000000));
+
+ FlxTween.tween(camera, {alpha: 1}, 0.25, {ease: FlxEase.cubeOut});
+ FlxTween.tween(camera, {zoom: 1}, 0.66, {ease: FlxEase.elasticOut});
+ }
+
+ public override function destroy() {
+ super.destroy();
+ for(e in camShaders)
+ e.removeShader(blurShader);
+
+ FlxG.cameras.remove(camera);
+ }
+
+ public function new(title:String, message:String, buttons:Array) {
+ super();
+ this.title = title;
+ this.message = message;
+ this.buttons = buttons;
+ }
+}
+typedef WarningCamShader = {
+ var cam:FlxCamera;
+}
+typedef WarningButton = {
+ var label:String;
+ var onClick:UIWarningSubstate->Void;
+}
\ No newline at end of file
diff --git a/source/funkin/system/MusicBeatState.hx b/source/funkin/system/MusicBeatState.hx
index fbc21c22..afcbf3d1 100644
--- a/source/funkin/system/MusicBeatState.hx
+++ b/source/funkin/system/MusicBeatState.hx
@@ -242,4 +242,12 @@ class MusicBeatState extends FlxUIState implements IBeatReceiver
super.onFocusLost();
call("onFocusLost");
}
+
+ public override function resetSubState() {
+ super.resetSubState();
+ if (subState != null && subState is MusicBeatSubstate) {
+ cast(subState, MusicBeatSubstate).parent = this;
+ cast(subState, MusicBeatSubstate).onSubstateOpen();
+ }
+ }
}
diff --git a/source/funkin/system/MusicBeatSubstate.hx b/source/funkin/system/MusicBeatSubstate.hx
index e51ea793..2299fd4f 100644
--- a/source/funkin/system/MusicBeatSubstate.hx
+++ b/source/funkin/system/MusicBeatSubstate.hx
@@ -243,4 +243,18 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
super.onFocusLost();
call("onFocusLost");
}
+
+ public var parent:FlxState;
+
+ public function onSubstateOpen() {
+
+ }
+
+ public override function resetSubState() {
+ super.resetSubState();
+ if (subState != null && subState is MusicBeatSubstate) {
+ cast(subState, MusicBeatSubstate).parent = this;
+ cast(subState, MusicBeatSubstate).onSubstateOpen();
+ }
+ }
}