diff --git a/assets/images/desktop/ui.xml b/assets/images/desktop/ui.xml
index 26c8d287..40df3f67 100644
--- a/assets/images/desktop/ui.xml
+++ b/assets/images/desktop/ui.xml
@@ -10,4 +10,7 @@
+
+
+
\ No newline at end of file
diff --git a/assets/images/desktop/ui/checkbox.png b/assets/images/desktop/ui/checkbox.png
index 44c22b6f..c50a9390 100644
Binary files a/assets/images/desktop/ui/checkbox.png and b/assets/images/desktop/ui/checkbox.png differ
diff --git a/buildnumber.txt b/buildnumber.txt
index f01f3762..62cab397 100644
--- a/buildnumber.txt
+++ b/buildnumber.txt
@@ -1 +1 @@
-1675
\ No newline at end of file
+1683
\ No newline at end of file
diff --git a/source/funkin/desktop/DesktopMain.hx b/source/funkin/desktop/DesktopMain.hx
index 7f8a2620..93a61891 100644
--- a/source/funkin/desktop/DesktopMain.hx
+++ b/source/funkin/desktop/DesktopMain.hx
@@ -1,5 +1,6 @@
package funkin.desktop;
+import flixel.math.FlxRect;
import openfl.geom.Rectangle;
import flixel.FlxObject;
import lime.app.Application;
@@ -140,11 +141,11 @@ class MouseInput {
}
public function overlaps(spr:FlxObject, ?camera:FlxCamera) {
- return overlapsRect(spr, new Rectangle(spr.x, spr.y, spr.width, spr.height), camera);
+ return overlapsRect(spr, new FlxRect(spr.x, spr.y, spr.width, spr.height), camera);
// return FlxG.mouse.overlaps(spr, camera);
}
- public function overlapsRect(spr:FlxBasic, rect:Rectangle, ?camera:FlxCamera) {
+ public function overlapsRect(spr:FlxBasic, rect:FlxRect, ?camera:FlxCamera) {
if (__cancelled) return false;
if (camera == null) camera = FlxG.camera;
if (spr is FlxObject) {
diff --git a/source/funkin/desktop/DesktopUtils.hx b/source/funkin/desktop/DesktopUtils.hx
new file mode 100644
index 00000000..760f267f
--- /dev/null
+++ b/source/funkin/desktop/DesktopUtils.hx
@@ -0,0 +1,11 @@
+package funkin.desktop;
+
+import flixel.FlxObject;
+
+class DesktopUtils {
+ public static function copyProperties(spr1:FlxObject, spr2:FlxObject) {
+ spr1.cameras = spr2.cameras;
+ spr1.setPosition(spr2.x, spr2.y);
+ spr1.scrollFactor.set(spr2.scrollFactor.x, spr2.scrollFactor.y);
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/desktop/editors/HelloWorld.hx b/source/funkin/desktop/editors/HelloWorld.hx
index 69105f6a..a93294b7 100644
--- a/source/funkin/desktop/editors/HelloWorld.hx
+++ b/source/funkin/desktop/editors/HelloWorld.hx
@@ -32,6 +32,10 @@ class HelloWorld extends WindowContent {
});
butt.scrollFactor.set();
add(butt);
+
+ var checkbox = new Checkbox(10, 40, 0, "Test Checkbox", CHECKED);
+ checkbox.scrollFactor.set();
+ add(checkbox);
}
public var time:Float = 0;
diff --git a/source/funkin/desktop/import.hx b/source/funkin/desktop/import.hx
new file mode 100644
index 00000000..764de2d5
--- /dev/null
+++ b/source/funkin/desktop/import.hx
@@ -0,0 +1 @@
+using funkin.desktop.DesktopUtils;
\ No newline at end of file
diff --git a/source/funkin/desktop/sprites/Button.hx b/source/funkin/desktop/sprites/Button.hx
index 897ba134..bee4f808 100644
--- a/source/funkin/desktop/sprites/Button.hx
+++ b/source/funkin/desktop/sprites/Button.hx
@@ -103,11 +103,8 @@ class Button extends FlxObject {
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);
- }
+ for(sprite in [spr, label])
+ sprite.copyProperties(this);
spr.draw();
label.y += (height - label.height) / 2;
label.draw();
diff --git a/source/funkin/desktop/sprites/Checkbox.hx b/source/funkin/desktop/sprites/Checkbox.hx
new file mode 100644
index 00000000..2672bc99
--- /dev/null
+++ b/source/funkin/desktop/sprites/Checkbox.hx
@@ -0,0 +1,65 @@
+package funkin.desktop.sprites;
+
+import flixel.FlxSprite;
+import flixel.text.FlxText;
+import flixel.FlxObject;
+
+class Checkbox extends WindowText {
+ public var checked:CheckState = UNCHECKED;
+ public var disabled:Bool = false;
+ public var checkboxSprite:FlxSprite;
+
+ public function new(x:Float, y:Float, w:Float, t:String, checked:CheckState = UNCHECKED) {
+ super(x, y, w, t);
+ this.checked = checked;
+ offset.x -= 20;
+
+ var t = DesktopMain.theme.checkbox;
+
+ checkboxSprite = new FlxSprite(0, (20 - t.height) / 2);
+ checkboxSprite.loadGraphic(Paths.image(t.sprite), true, Std.int(t.width), Std.int(t.height));
+ checkboxSprite.animation.add("checkbox", [for(i in 0...checkboxSprite.frames.frames.length) i], 0, true);
+ checkboxSprite.animation.play("checkbox");
+ }
+
+ public override function update(elapsed:Float) {
+ super.update(elapsed);
+ checkboxSprite.update(elapsed);
+
+ var overlaps = DesktopMain.mouseInput.overlaps(this, camera) || DesktopMain.mouseInput.overlaps(checkboxSprite, camera);
+ var pressed = DesktopMain.mouseInput.pressed;
+
+ if (overlaps) {
+ // cancel so that sprites in the bg dont get hovered as well
+ if (!disabled && DesktopMain.mouseInput.justPressed) {
+ checked = switch(checked) {
+ case CHECKED | BOTH:
+ UNCHECKED;
+ case UNCHECKED:
+ CHECKED;
+ }
+ }
+ DesktopMain.mouseInput.cancel();
+ }
+
+ checkboxSprite.animation.curAnim.curFrame = (switch(checked) {
+ case UNCHECKED: 0;
+ case CHECKED: 1;
+ case BOTH: 2;
+ }) + (disabled ? 9 : (overlaps ? (pressed ? 6 : 3) : 0));
+ }
+
+ public override function draw() {
+ checkboxSprite.copyProperties(this);
+ rotOffset.y = (this.height - checkboxSprite.height) / 2;
+ super.draw();
+ checkboxSprite.draw();
+ }
+}
+
+@:enum
+abstract CheckState(Null) {
+ var CHECKED:CheckState = true;
+ var UNCHECKED:CheckState = false;
+ var BOTH:CheckState = null;
+}
\ No newline at end of file
diff --git a/source/funkin/desktop/theme/Theme.hx b/source/funkin/desktop/theme/Theme.hx
index 20012316..98f6192d 100644
--- a/source/funkin/desktop/theme/Theme.hx
+++ b/source/funkin/desktop/theme/Theme.hx
@@ -39,6 +39,11 @@ class Theme {
public var pressedButton:ThemeData = new ThemeData();
public var disabledButton:ThemeData = new ThemeData();
+ /**
+ * CHECKBOX
+ */
+ public var checkbox:ThemeData = new ThemeData();
+
public function new(content:String) {
try {
var access = new Access(Xml.parse(content).firstElement());
@@ -60,6 +65,8 @@ class Theme {
if (element.has.right) data.right = Std.parseFloat(element.att.right).getDefault(0);
if (element.has.top) data.top = Std.parseFloat(element.att.top).getDefault(0);
if (element.has.bottom) data.bottom = Std.parseFloat(element.att.bottom).getDefault(0);
+ if (element.has.width) data.width = Std.parseFloat(element.att.width).getDefault(data.width);
+ if (element.has.height) data.height = Std.parseFloat(element.att.height).getDefault(data.height);
if (element.has.size) {
var split = element.att.size.split(",");
data.size.set(
@@ -100,6 +107,9 @@ class ThemeData implements IFlxDestroyable {
public var top:Float = 4;
public var right:Float = 4;
+ public var width:Float = 4;
+ public var height:Float = 4;
+
public var margin:FlxPoint = FlxPoint.get(0, 0);
public var size:FlxPoint = FlxPoint.get(20, 20);
public var offset:FlxPoint = FlxPoint.get(5, 5);
diff --git a/source/funkin/desktop/windows/Window.hx b/source/funkin/desktop/windows/Window.hx
index 86947d3d..7129bc9c 100644
--- a/source/funkin/desktop/windows/Window.hx
+++ b/source/funkin/desktop/windows/Window.hx
@@ -1,5 +1,6 @@
package funkin.desktop.windows;
+import flixel.math.FlxRect;
import flixel.addons.ui.FlxUIText;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.FlxBasic;
@@ -252,7 +253,7 @@ class Window extends FlxTypedGroup {
windowInactiveFrame.visible = !(windowFrame.visible = focused);
var i = members.length;
- var shouldCancel = DesktopMain.mouseInput.overlapsRect(this, new Rectangle(0, 0, windowCaptionCamera.width, windowCaptionCamera.height), windowCaptionCamera);
+ var shouldCancel = DesktopMain.mouseInput.overlapsRect(this, new FlxRect(0, 0, windowCaptionCamera.width, windowCaptionCamera.height), windowCaptionCamera);