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(); + } + } }