diff --git a/assets/images/desktop/ui.xml b/assets/images/desktop/ui.xml index 66b00bf6..4b2aac16 100644 --- a/assets/images/desktop/ui.xml +++ b/assets/images/desktop/ui.xml @@ -1,5 +1,8 @@ - - - - - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/assets/images/desktop/ui/caption.png b/assets/images/desktop/ui/caption.png index c981a604..01cff8f6 100644 Binary files a/assets/images/desktop/ui/caption.png and b/assets/images/desktop/ui/caption.png differ diff --git a/assets/images/desktop/ui/captionButtons.png b/assets/images/desktop/ui/captionButtons.png index faadfa29..c0e1caef 100644 Binary files a/assets/images/desktop/ui/captionButtons.png and b/assets/images/desktop/ui/captionButtons.png differ diff --git a/assets/images/desktop/ui/captionInactive.png b/assets/images/desktop/ui/captionInactive.png index 6e562221..14f9d1d7 100644 Binary files a/assets/images/desktop/ui/captionInactive.png and b/assets/images/desktop/ui/captionInactive.png differ diff --git a/buildnumber.txt b/buildnumber.txt index 50ae8807..c7105757 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -714 \ No newline at end of file +732 \ No newline at end of file diff --git a/source/funkin/desktop/DesktopMain.hx b/source/funkin/desktop/DesktopMain.hx index 1b1fbac0..32b5342b 100644 --- a/source/funkin/desktop/DesktopMain.hx +++ b/source/funkin/desktop/DesktopMain.hx @@ -13,6 +13,7 @@ import flixel.FlxCamera; import flixel.math.FlxPoint; import funkin.desktop.editors.HelloWorld; import funkin.desktop.windows.*; +import funkin.desktop.theme.Theme; class DesktopMain extends MusicBeatState { public var oldScaleMode:BaseScaleMode; @@ -25,8 +26,12 @@ class DesktopMain extends MusicBeatState { public var mouseInput:MouseInput = new MouseInput(); + public static var theme:Theme = null; + public override function create() { super.create(); + + theme = Theme.loadFromAssets(Paths.getPath('images/desktop/ui.xml', TEXT, null)); instance = this; FlxG.mouse.useSystemCursor = FlxG.mouse.visible = true; diff --git a/source/funkin/desktop/theme/Theme.hx b/source/funkin/desktop/theme/Theme.hx new file mode 100644 index 00000000..db41c401 --- /dev/null +++ b/source/funkin/desktop/theme/Theme.hx @@ -0,0 +1,107 @@ +package funkin.desktop.theme; + +import flixel.util.FlxDestroyUtil.IFlxDestroyable; +import flixel.util.FlxColor; +import flixel.math.FlxPoint; +import haxe.xml.Access; +import openfl.Assets; + +class Theme { + public static function loadFromAssets(path:String) { + return load(Assets.getText(path)); + } + + public static function loadFromPath(path:String) { + #if sys + return load(sys.io.File.getContent(path)); + #else + return null; + #end + } + + public static function load(content:String):Theme { + return new Theme(content); + } + + public var captionActive:ThemeData = new ThemeData(); + public var captionInactive:ThemeData = new ThemeData(); + public var captionButtons:ThemeData = new ThemeData(); + + public function new(content:String) { + try { + var access = new Access(Xml.parse(content).firstElement()); + var prefix = ''; + if (access.has.folder) prefix = access.att.folder.trim(); + for(element in access.elements) { + var name:String = element.name.trim(); + trace(name); + if (!Type.getInstanceFields(Theme).contains(name)) continue; + var field = Reflect.field(this, name); + if (!(field is ThemeData)) continue; + var data = cast(field, ThemeData); + + if (element.has.path) data.sprite = '$prefix${element.att.path.trim()}'; + if (element.has.textColor) data.textColor = element.att.textColor.getColorFromDynamic(); + if (element.has.left) data.left = Std.parseFloat(element.att.left).getDefault(0); + 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.size) { + var split = element.att.size.split(","); + data.size.set( + Std.parseFloat(split[0]).getDefault(data.size.x), + Std.parseFloat(split[1]).getDefault(data.size.y)); + } + if (element.has.margin) { + var split = element.att.margin.split(","); + data.margin.set( + Std.parseFloat(split[0]).getDefault(data.margin.x), + Std.parseFloat(split[1]).getDefault(data.margin.y)); + } + if (element.has.offset) { + var split = element.att.offset.split(","); + data.offset.set( + Std.parseFloat(split[0]).getDefault(data.offset.x), + Std.parseFloat(split[1]).getDefault(data.offset.y)); + } + + } + } catch(e) { + // TODO: logs system + trace(e.details()); + } + } +} + +class ThemeData implements IFlxDestroyable { + public var sprite:String = ""; + + public var textColor:FlxColor = FlxColor.WHITE; + + public var left:Float = 4; + public var bottom:Float = 4; + public var top:Float = 4; + public var right: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); + + + public function new() {} + + public function destroy() { + if (margin != null) { + margin.put(); + margin = null; + } + if (size != null) { + size.put(); + size = null; + } + if (offset != null) { + offset.put(); + offset = null; + } + } +} \ No newline at end of file diff --git a/source/funkin/desktop/windows/Window.hx b/source/funkin/desktop/windows/Window.hx index 4db01ca0..78860997 100644 --- a/source/funkin/desktop/windows/Window.hx +++ b/source/funkin/desktop/windows/Window.hx @@ -55,19 +55,26 @@ class Window extends FlxTypedGroup { } public function new(content:WindowContent) { super(); - windowFrame = new FlxUI9SliceSprite(0, 0, Paths.image('desktop/windowFrame'), new Rectangle(10, 10), [3, 3, 6, 6]); + 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) + ]); add(windowFrame); caption = new FlxUIText(24, 4, 0, content.title); captionButtons = new FlxTypedSpriteGroup(); for(i in 0...3) { var btn = new WindowCaptionButton(this, i); - btn.x = (i+1) * -18; + btn.x = (i+1) * -(DesktopMain.theme.captionButtons.size.x + DesktopMain.theme.captionButtons.margin.x); captionButtons.add(btn); } add(caption); - dragHitbox = new WindowDragHitbox(4, 4, 4, 18); + dragHitbox = new WindowDragHitbox(DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.top); dragHitbox.parent = this; add(dragHitbox); @@ -158,12 +165,17 @@ class Window extends FlxTypedGroup { content.winY = windowCaptionCamera.y = y; @:privateAccess content.__noParentUpdate = false; for(e in windowCameras) { - e.camera.x = x + 4; - e.camera.y = y + 23; + e.camera.x = x + Std.int(DesktopMain.theme.captionActive.left); + e.camera.y = y + Std.int(DesktopMain.theme.captionActive.top); } } public override function update(elapsed:Float) { + if (__closing) { + DesktopMain.instance.windows.remove(this, true); + destroy(); + return; + } var i = members.length; var shouldCancel = DesktopMain.instance.mouseInput.overlapsRect(this, new Rectangle(0, 0, windowCaptionCamera.width, windowCaptionCamera.height), windowCaptionCamera); @@ -184,14 +196,12 @@ class Window extends FlxTypedGroup { public function close() { __closing = true; - DesktopMain.instance.windows.remove(this, true); - destroy(); } public function updateWindowFrame() { - windowFrame.resize(windowWidth + 4 + 4, windowHeight + 23 + 4); - windowCaptionCamera.setSize(windowWidth + 4 + 4, windowHeight + 23 + 4); - captionButtons.setPosition(windowWidth + 4, 4); + windowFrame.resize(windowWidth + Std.int(DesktopMain.theme.captionActive.left * 2), windowHeight + Std.int(DesktopMain.theme.captionActive.top) + Std.int(DesktopMain.theme.captionActive.left)); + windowCaptionCamera.setSize(windowWidth + Std.int(DesktopMain.theme.captionActive.left * 2), windowHeight + Std.int(DesktopMain.theme.captionActive.top) + Std.int(DesktopMain.theme.captionActive.left)); + captionButtons.setPosition(windowWidth + Std.int((DesktopMain.theme.captionActive.left * 2) - DesktopMain.theme.captionButtons.offset.x), Std.int(DesktopMain.theme.captionButtons.offset.y)); for(e in windowCameras) { e.camera.setSize(windowWidth, windowHeight); if (e.resizeScroll) { diff --git a/source/funkin/desktop/windows/WindowCaptionButton.hx b/source/funkin/desktop/windows/WindowCaptionButton.hx index af78f15f..1ac3627a 100644 --- a/source/funkin/desktop/windows/WindowCaptionButton.hx +++ b/source/funkin/desktop/windows/WindowCaptionButton.hx @@ -1,38 +1,59 @@ package funkin.desktop.windows; -import flixel.addons.ui.FlxUIButton; import flixel.FlxSprite; -class WindowCaptionButton extends FlxUIButton { +class WindowCaptionButton extends FlxSprite { public var icon:FlxSprite; + public var window:Window; public function new(window:Window, i:Int) { - super(0, 0, "", function() { - switch(i) { - case 0: - window.close(); - } - }); + // super(0, 0, "", function() { + // switch(i) { + // case 0: + // window.close(); + // } + // }); + super(0, 0); + this.window = window; ID = i; - resize(18, 18); - color = (i > 0) ? 0xFF8888FF : 0xFFFF0000; - icon = new FlxSprite(0, 0).loadGraphic(Paths.image('desktop/captionButtons'), true, 18, 18); - icon.animation.add("button", [switch(i) { - case 0: 2; - case 1: 1; - case 2: 0; - default: i; - }]); - icon.animation.play("button"); + loadGraphic(Paths.image(DesktopMain.theme.captionButtons.sprite), true, Std.int(DesktopMain.theme.captionButtons.size.x), Std.int(DesktopMain.theme.captionButtons.size.y)); + animation.add("button", [for(l in 0...6) i+(l*3)], 0, true); + animation.play("button"); + + // resize(18, 18); + // color = (i > 0) ? 0xFF8888FF : 0xFFFF0000; } public override function draw() { super.draw(); + } - icon.setPosition(x, y); - icon.cameras = this.cameras; - icon.draw(); - icon.scrollFactor.set(scrollFactor.x, scrollFactor.y); + public override function update(elapsed:Float) { + if (animation.curAnim == null) { + super.update(elapsed); + return; + } + var mouseInput = DesktopMain.instance.mouseInput; + if (DesktopMain.instance.mouseInput.overlaps(this, camera)) { + if (mouseInput.justReleased) { + switch(ID) { + case 0: + window.close(); + } + mouseInput.cancel(); + return; + } + if (mouseInput.pressed || mouseInput.justPressed) { + animation.curAnim.curFrame = 2; + } else { + animation.curAnim.curFrame = 1; + } + mouseInput.cancel(); // prevents controls behind this one from updating input + } else + animation.curAnim.curFrame = 0; + if (!window.focused) animation.curAnim.curFrame += 3; + + super.update(elapsed); } } \ No newline at end of file