diff --git a/assets/images/desktop/ui.xml b/assets/images/desktop/ui.xml
index 4b2aac16..26b05830 100644
--- a/assets/images/desktop/ui.xml
+++ b/assets/images/desktop/ui.xml
@@ -1,8 +1,12 @@
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/desktop/ui/button.png b/assets/images/desktop/ui/button.png
new file mode 100644
index 00000000..c4826c6a
Binary files /dev/null and b/assets/images/desktop/ui/button.png differ
diff --git a/assets/images/desktop/ui/buttonDisabled.png b/assets/images/desktop/ui/buttonDisabled.png
new file mode 100644
index 00000000..22fc15b6
Binary files /dev/null and b/assets/images/desktop/ui/buttonDisabled.png differ
diff --git a/assets/images/desktop/ui/buttonHover.png b/assets/images/desktop/ui/buttonHover.png
new file mode 100644
index 00000000..81f3e05d
Binary files /dev/null and b/assets/images/desktop/ui/buttonHover.png differ
diff --git a/assets/images/desktop/ui/buttonPressed.png b/assets/images/desktop/ui/buttonPressed.png
new file mode 100644
index 00000000..ba4d4ba8
Binary files /dev/null and b/assets/images/desktop/ui/buttonPressed.png differ
diff --git a/buildnumber.txt b/buildnumber.txt
index 45b1ccee..cbb5735d 100644
--- a/buildnumber.txt
+++ b/buildnumber.txt
@@ -1 +1 @@
-741
\ No newline at end of file
+760
\ No newline at end of file
diff --git a/source/funkin/desktop/editors/HelloWorld.hx b/source/funkin/desktop/editors/HelloWorld.hx
index a9ce1b2f..a07eb6ea 100644
--- a/source/funkin/desktop/editors/HelloWorld.hx
+++ b/source/funkin/desktop/editors/HelloWorld.hx
@@ -3,6 +3,7 @@ package funkin.desktop.editors;
import flixel.util.FlxDestroyUtil.IFlxDestroyable;
import flixel.addons.ui.FlxUIText;
import flixel.FlxG;
+import funkin.desktop.sprites.*;
class HelloWorld extends WindowContent {
public override function new() {
@@ -29,6 +30,12 @@ class HelloWorld extends WindowContent {
t.setPosition(630 - t.width, 10);
t.scrollFactor.set(1, 0);
add(t);
+
+ var butt = new Button(10, 10, "Test", function() {
+ trace("help");
+ });
+ butt.scrollFactor.set();
+ add(butt);
}
public var time:Float = 0;
diff --git a/source/funkin/desktop/sprites/Button.hx b/source/funkin/desktop/sprites/Button.hx
new file mode 100644
index 00000000..2c8e06d7
--- /dev/null
+++ b/source/funkin/desktop/sprites/Button.hx
@@ -0,0 +1,96 @@
+package funkin.desktop.sprites;
+
+import flixel.FlxObject;
+import flixel.addons.ui.FlxUIText;
+import flixel.FlxSprite;
+import flixel.math.FlxPoint;
+import funkin.desktop.windows.WindowGroup;
+
+class Button extends FlxObject {
+ public var callback:Void->Void;
+
+ public var disabled:Bool = false;
+
+ public var frame:Int = 0;
+
+ public var normalSprite:SpliceSprite;
+ public var hoverSprite:SpliceSprite;
+ public var pressedSprite:SpliceSprite;
+ public var disabledSprite:SpliceSprite;
+
+ public var label:FlxUIText;
+
+ public function new(x:Float, y:Float, text:String = "", callback:Void->Void) {
+ super();
+ this.x = x;
+ this.y = y;
+ this.width = 75;
+ this.height = 24;
+ this.callback = callback;
+
+ var normalButton = DesktopMain.theme.normalButton;
+ var hoverButton = DesktopMain.theme.hoverButton;
+ var pressedButton = DesktopMain.theme.pressedButton;
+ var disabledButton = DesktopMain.theme.disabledButton;
+
+ normalSprite = new SpliceSprite(normalButton.sprite, x, y, 75, 24, normalButton.left, normalButton.top, normalButton.bottom, normalButton.right);
+ hoverSprite = new SpliceSprite(hoverButton.sprite, x, y, 75, 24, hoverButton.left, hoverButton.top, hoverButton.bottom, hoverButton.right);
+ pressedSprite = new SpliceSprite(pressedButton.sprite, x, y, 75, 24, pressedButton.left, pressedButton.top, pressedButton.bottom, pressedButton.right);
+ disabledSprite = new SpliceSprite(disabledButton.sprite, x, y, 75, 24, disabledButton.left, disabledButton.top, disabledButton.bottom, disabledButton.right);
+
+ label = new FlxUIText(0, 0, 75, text);
+ }
+
+ public override function update(elapsed:Float) {
+ super.update(elapsed);
+ var mouseInput = DesktopMain.instance.mouseInput;
+ if (mouseInput.overlaps(normalSprite, camera)) {
+ if (mouseInput.justReleased) {
+ callback();
+ return;
+ }
+
+ if (mouseInput.justPressed || mouseInput.pressed)
+ frame = 2;
+ else
+ frame = 1;
+ mouseInput.cancel();
+ } else
+ frame = 0;
+
+ if (disabled) frame = 3;
+
+ for(e in [normalSprite, hoverSprite, pressedSprite, disabledSprite])
+ e.update(elapsed);
+ }
+
+ public override function destroy() {
+ for(e in [normalSprite, hoverSprite, pressedSprite, disabledSprite])
+ e.destroy();
+ scrollFactor.put();
+ super.destroy();
+ }
+
+ public function resize(width:Float, height:Float) {
+ this.width = width;
+ this.height = height;
+ normalSprite.resize(width, height);
+ label.fieldWidth = width;
+ }
+ public override function draw() {
+ super.draw();
+ var spr = switch(frame) {
+ case 1: hoverSprite;
+ case 2: pressedSprite;
+ case 3: disabledSprite;
+ default: normalSprite;
+ };
+ spr.resize(width, height);
+ for(sprite in [spr, label]) {
+ sprite.cameras = cameras;
+ sprite.setPosition(x, y);
+ sprite.scrollFactor.set(scrollFactor.x, scrollFactor.y);
+ sprite.draw();
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/desktop/sprites/SpliceSprite.hx b/source/funkin/desktop/sprites/SpliceSprite.hx
new file mode 100644
index 00000000..401e721c
--- /dev/null
+++ b/source/funkin/desktop/sprites/SpliceSprite.hx
@@ -0,0 +1,126 @@
+package funkin.desktop.sprites;
+
+import openfl.display.BitmapData;
+import openfl.geom.Rectangle;
+import openfl.geom.Point;
+import flixel.FlxObject;
+import flixel.FlxSprite;
+import flixel.system.FlxAssets.FlxGraphicAsset;
+
+class SpliceSprite extends FlxObject {
+ public var topLeft:FlxSprite = new FlxSprite();
+ public var left:FlxSprite = new FlxSprite();
+ public var bottomLeft:FlxSprite = new FlxSprite();
+ public var bottom:FlxSprite = new FlxSprite();
+ public var bottomRight:FlxSprite = new FlxSprite();
+ public var right:FlxSprite = new FlxSprite();
+ public var topRight:FlxSprite = new FlxSprite();
+ public var top:FlxSprite = new FlxSprite();
+
+ public var __internalSprite:FlxSprite;
+ public var slice:Array = [0, 0, 0, 0];
+
+ public function new(spr:FlxGraphicAsset, x:Float, y:Float, width:Float, height:Float, left:Float = 5, top:Float = 5, bottom:Float = 5, right:Float = 5) {
+ super();
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+
+ __internalSprite = new FlxSprite(0, 0, spr);
+
+ slice = [Std.int(left), Std.int(bottom), Std.int(top), Std.int(right)];
+ // for(e in [topLeft, left, bottomLeft, bottom, bottomRight, right, topRight, top]) {
+ // e.loadGraphic(spr);
+ // }
+ updateRects();
+ }
+
+ public function updateRects() {
+ var parts = [topLeft, left, bottomLeft, bottom, bottomRight, right, topRight, top];
+ var _left:Int = slice[0];
+ var _down:Int = slice[1];
+ var _up:Int = slice[2];
+ var _right:Int = slice[3];
+ var _height:Int = __internalSprite.frameHeight;
+ var _width:Int = __internalSprite.frameWidth;
+
+ topLeft.pixels = new BitmapData(_left, _up, true, 0);
+ left.pixels = new BitmapData(_left, _height - _up - _down, true, 0);
+ bottomLeft.pixels = new BitmapData(_left, _down, true, 0);
+ bottom.pixels = new BitmapData(_width - _left - _right, _down, true, 0);
+ bottomRight.pixels = new BitmapData(_right, _down, true, 0);
+ right.pixels = new BitmapData(_right, _height - _up - _down, true, 0);
+ topRight.pixels = new BitmapData(_right, _up, true, 0);
+ top.pixels = new BitmapData(_width - _left - _right, _up, true, 0);
+
+
+ for(e in parts) e.pixels.lock();
+
+ var pos = new Point(0, 0);
+ topLeft.pixels.copyPixels(__internalSprite.pixels, new Rectangle(0, 0, _left, _up), pos);
+ left.pixels.copyPixels(__internalSprite.pixels, new Rectangle(0, _up, _left, _height - _up - _down), pos);
+ bottomLeft.pixels.copyPixels(__internalSprite.pixels, new Rectangle(0, _height - _down, _left, _down), pos);
+ bottom.pixels.copyPixels(__internalSprite.pixels, new Rectangle(_left, _height - _down, _width - _left - _right, _down), pos);
+ bottomRight.pixels.copyPixels(__internalSprite.pixels, new Rectangle(_width - _right, _height - _down, _right, _down), pos);
+ right.pixels.copyPixels(__internalSprite.pixels, new Rectangle(_width - _right, _up, _right, _height - _down - _up), pos);
+ topRight.pixels.copyPixels(__internalSprite.pixels, new Rectangle(_width - _right, 0, _right, _up), pos);
+ top.pixels.copyPixels(__internalSprite.pixels, new Rectangle(_left, 0, _width - _left - _right, _up), pos);
+
+ for(e in parts) e.pixels.unlock();
+ }
+
+ public override function destroy() {
+ for(e in [topLeft, left, bottomLeft, bottom, bottomRight, right, topRight, top, __internalSprite])
+ e.destroy();
+ super.destroy();
+ }
+
+ public function resize(width:Float, height:Float) {
+ this.width = width;
+ this.height = height;
+ }
+
+ public override function draw() {
+ if (!visible) return;
+ super.draw();
+ var parts = [topLeft, left, bottomLeft, bottom, bottomRight, right, topRight, top];
+
+ var _left:Int = slice[0];
+ var _down:Int = slice[1];
+ var _up:Int = slice[2];
+ var _right:Int = slice[3];
+
+ // left
+ topLeft.setPosition(x, y);
+ left.setPosition(x, y + _up);
+ left.setSpriteSize(_left, height - _up - _down);
+ bottomLeft.setPosition(x, y + height - _down);
+
+ // top
+ top.setPosition(x + _left, y);
+ top.setSpriteSize(width - _left - _right, _up);
+
+ // bottom
+ bottom.setPosition(x + _left, y + height - _down);
+ bottom.setSpriteSize(width - _left - _right, _down);
+
+ // right
+ topRight.setPosition(x + (width - _right), y);
+ right.setPosition(x + (width - _right), y + _up);
+ right.setSpriteSize(_right, height - _up - _down);
+ bottomRight.setPosition(x + (width - _right), y + height - _down);
+
+ for(e in parts) {
+ e.cameras = cameras;
+ e.scrollFactor.set(scrollFactor.x, scrollFactor.y);
+ e.draw();
+ }
+ }
+
+ public override function update(elapsed:Float) {
+ super.update(elapsed);
+ for(e in [topLeft, left, bottomLeft, bottom, bottomRight, right, topRight, top])
+ e.update(elapsed);
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/desktop/theme/Theme.hx b/source/funkin/desktop/theme/Theme.hx
index db41c401..da66dd2f 100644
--- a/source/funkin/desktop/theme/Theme.hx
+++ b/source/funkin/desktop/theme/Theme.hx
@@ -23,10 +23,21 @@ class Theme {
return new Theme(content);
}
+ /**
+ * CAPTION
+ */
public var captionActive:ThemeData = new ThemeData();
public var captionInactive:ThemeData = new ThemeData();
public var captionButtons:ThemeData = new ThemeData();
+ /**
+ * BUTTON
+ */
+ public var normalButton:ThemeData = new ThemeData();
+ public var hoverButton:ThemeData = new ThemeData();
+ public var pressedButton:ThemeData = new ThemeData();
+ public var disabledButton:ThemeData = new ThemeData();
+
public function new(content:String) {
try {
var access = new Access(Xml.parse(content).firstElement());
diff --git a/source/funkin/desktop/windows/Window.hx b/source/funkin/desktop/windows/Window.hx
index 9e301d4c..7c28363b 100644
--- a/source/funkin/desktop/windows/Window.hx
+++ b/source/funkin/desktop/windows/Window.hx
@@ -13,6 +13,7 @@ import flixel.FlxG;
import flixel.tweens.FlxTween;
import flixel.tweens.FlxEase;
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
+import funkin.desktop.sprites.*;
typedef WindowCam = {
@@ -22,8 +23,8 @@ typedef WindowCam = {
var height:Int;
}
class Window extends FlxTypedGroup {
- public var windowFrame:FlxUI9SliceSprite;
- public var windowInactiveFrame:FlxUI9SliceSprite;
+ public var windowFrame:SpliceSprite;
+ public var windowInactiveFrame:SpliceSprite;
public var captionButtons:FlxTypedSpriteGroup;
public var windowWidth:Int = 0;
@@ -56,22 +57,16 @@ class Window extends FlxTypedGroup {
}
public function new(content:WindowContent) {
super();
- windowFrame = new FlxUI9SliceSprite(0, 0,
- Paths.image(DesktopMain.theme.captionActive.sprite),
- new Rectangle(10, 10), [
- Std.int(DesktopMain.theme.captionActive.left),
- Std.int(DesktopMain.theme.captionActive.top),
- Std.int(DesktopMain.theme.captionActive.right),
- Std.int(DesktopMain.theme.captionActive.bottom)
- ]);
- windowInactiveFrame = new FlxUI9SliceSprite(0, 0,
- Paths.image(DesktopMain.theme.captionInactive.sprite),
- new Rectangle(10, 10), [
- Std.int(DesktopMain.theme.captionInactive.left),
- Std.int(DesktopMain.theme.captionInactive.top),
- Std.int(DesktopMain.theme.captionInactive.right),
- Std.int(DesktopMain.theme.captionInactive.bottom)
- ]);
+ windowFrame = new SpliceSprite(Paths.image(DesktopMain.theme.captionActive.sprite), 0, 0, 10, 10,
+ Std.int(DesktopMain.theme.captionActive.left),
+ Std.int(DesktopMain.theme.captionActive.top),
+ Std.int(DesktopMain.theme.captionActive.right),
+ Std.int(DesktopMain.theme.captionActive.bottom));
+ windowInactiveFrame = new SpliceSprite(Paths.image(DesktopMain.theme.captionInactive.sprite), 0, 0, 10, 10,
+ Std.int(DesktopMain.theme.captionInactive.left),
+ Std.int(DesktopMain.theme.captionInactive.top),
+ Std.int(DesktopMain.theme.captionInactive.right),
+ Std.int(DesktopMain.theme.captionInactive.bottom));
add(windowFrame);
add(windowInactiveFrame);
diff --git a/source/funkin/desktop/windows/WindowContent.hx b/source/funkin/desktop/windows/WindowContent.hx
index eb9bb041..fb448aab 100644
--- a/source/funkin/desktop/windows/WindowContent.hx
+++ b/source/funkin/desktop/windows/WindowContent.hx
@@ -5,7 +5,7 @@ import flixel.FlxSprite;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.FlxCamera;
-class WindowContent extends FlxTypedGroup {
+class WindowContent extends WindowGroup {
public var winX(default, set):Float = 0;
public var winY(default, set):Float = 0;
public var title(default, set):String = "Window";
diff --git a/source/funkin/desktop/windows/WindowGroup.hx b/source/funkin/desktop/windows/WindowGroup.hx
index d7f84cba..eea068c2 100644
--- a/source/funkin/desktop/windows/WindowGroup.hx
+++ b/source/funkin/desktop/windows/WindowGroup.hx
@@ -2,11 +2,16 @@ package funkin.desktop.windows;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.FlxBasic;
+import flixel.FlxCamera;
class WindowGroup extends FlxTypedGroup {
public override function update(elapsed:Float) {
// update them backwards, so that the top most window gets the priority
var i = length;
+
+ @:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras;
+ @:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras;
+
while(i > 0) {
i--;
var window = members[i];
@@ -14,5 +19,7 @@ class WindowGroup extends FlxTypedGroup {
continue;
window.update(elapsed);
}
+
+ @:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
}
}
\ No newline at end of file
diff --git a/source/funkin/system/CoolUtil.hx b/source/funkin/system/CoolUtil.hx
index 9d431a88..035b96ff 100644
--- a/source/funkin/system/CoolUtil.hx
+++ b/source/funkin/system/CoolUtil.hx
@@ -189,6 +189,11 @@ class CoolUtil
}
}
+ public static function setSpriteSize(sprite:FlxSprite, width:Float, height:Float) {
+ sprite.scale.set(width / sprite.frameWidth, height / sprite.frameHeight);
+ sprite.updateHitbox();
+ }
+
/**
* Returns last member of array
*/