From 641604c4de61fcb32b985c7a880cb0113199850a Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 14 Apr 2024 17:47:47 -0700 Subject: [PATCH] properties UI!! --- source/funkin/backend/utils/CoolUtil.hx | 26 +++++++ .../editors/character/CharacterEditor.hx | 21 +++--- .../editors/character/CharacterIconDisplay.hx | 48 +++++++++++++ .../character/CharacterPropertiesWindow.hx | 72 ++++++++++++++----- source/funkin/editors/ui/UIButtonList.hx | 4 +- 5 files changed, 143 insertions(+), 28 deletions(-) create mode 100644 source/funkin/editors/character/CharacterIconDisplay.hx diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx index 36f817e8..b5e4c307 100644 --- a/source/funkin/backend/utils/CoolUtil.hx +++ b/source/funkin/backend/utils/CoolUtil.hx @@ -1,5 +1,8 @@ package funkin.backend.utils; +import openfl.geom.Point; +import openfl.geom.Rectangle; +import openfl.display.BitmapData; import flixel.animation.FlxAnimation; import flixel.input.keyboard.FlxKey; import flixel.sound.FlxSound; @@ -733,6 +736,29 @@ class CoolUtil return array.indexOf(element) != -1; } #end + + /** + * Returns a new bitmap without any empty transperent space on the edges + * @param bitmap The bitmap to be cropped + */ + public static function cropBitmap(bitmap:BitmapData) { + var minX:Int = bitmap.width; + var minY:Int = bitmap.height; + var maxX:Int = 0; var maxY:Int = 0; + + for (y in 0...bitmap.height) + for (x in 0...bitmap.width) + if (bitmap.getPixel32(x, y) != 0x00000000) { + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + } + + var croppedBitmap:BitmapData = new BitmapData(maxX-minX+1, maxY-minY+1, true, 0x00000000); + croppedBitmap.copyPixels(bitmap, new Rectangle(minX, minY, croppedBitmap.width, croppedBitmap.height), new Point(0,0)); + return croppedBitmap; + } } /** diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx index 9538db34..fd8519a6 100644 --- a/source/funkin/editors/character/CharacterEditor.hx +++ b/source/funkin/editors/character/CharacterEditor.hx @@ -1,5 +1,6 @@ package funkin.editors.character; +import openfl.display.BitmapData; import flixel.math.FlxPoint; import funkin.backend.system.framerate.Framerate; import funkin.backend.utils.XMLUtil.AnimData; @@ -221,6 +222,8 @@ class CharacterEditor extends UIState { characterBG.scrollFactor.set(); add(characterBG); + // characterBG.visible = false; + FlxG.cameras.add(uiCamera); FlxG.cameras.add(animsCamera); @@ -234,23 +237,23 @@ class CharacterEditor extends UIState { add(ghosts); add(character); + characterPropertiresWindow = new CharacterPropertiesWindow((FlxG.width-500)+16, 23+12+10, character); + uiGroup.add(characterPropertiresWindow); + topMenuSpr = new UITopMenu(topMenu); topMenuSpr.cameras = uiGroup.cameras = [uiCamera]; - characterPropertiresWindow = new CharacterPropertiesWindow(); - uiGroup.add(characterPropertiresWindow); - characterAnimsWindow = new UIButtonList(777, 209, 473, 488, "Character Animations", FlxPoint.get(429, 32)); characterAnimsWindow.addButton.callback = function() CharacterEditor.instance.createAnimWithUI(); var animOrder = character.getAnimOrder(); for (i=>anim in animOrder) characterAnimsWindow.add(new CharacterAnimButtons(0,0, anim, character.getAnimOffset(anim))); - uiGroup.add(characterAnimsWindow); + // uiGroup.add(characterAnimsWindow); playAnimation(animOrder[0]); var characterMidpoint:FlxPoint = character.getMidpoint(); - characterMidpoint.x += ((characterPropertiresWindow.bWidth+23)/2); + characterMidpoint.x += ((characterAnimsWindow.bWidth+23)/2); characterMidpoint.x -= (FlxG.width/2)-character.globalOffset.x; characterMidpoint.y -= (FlxG.height/2)-character.globalOffset.y+(23/4); charCamera.scroll = _nextScroll.set(characterMidpoint.x, characterMidpoint.y); @@ -263,8 +266,8 @@ class CharacterEditor extends UIState { _nextScroll.x -= ((FlxG.width/2)*FlxG.camera.zoom)-FlxG.width/2; _nextScroll.y += (((FlxG.height/2)*FlxG.camera.zoom)-FlxG.height/2)/2; - add(topMenuSpr); add(uiGroup); + add(topMenuSpr); if(Framerate.isLoaded) { Framerate.fpsCounter.alpha = 0.4; @@ -292,10 +295,10 @@ class CharacterEditor extends UIState { if(FlxG.keys.justPressed.ANY) UIUtil.processShortcuts(topMenu); - if (character != null) - characterPropertiresWindow.characterInfo.text = '${character.getNameList().length} Animations\nFlipped: ${character.flipX}\nSprite: ${character.sprite}\nAnim: ${character.getAnimName()}\nOffset: (${character.frameOffset.x}, ${character.frameOffset.y})'; + // if (character != null) + // characterPropertiresWindow.characterInfo.text = '${character.getNameList().length} Animations\nFlipped: ${character.flipX}\nSprite: ${character.sprite}\nAnim: ${character.getAnimName()}\nOffset: (${character.frameOffset.x}, ${character.frameOffset.y})'; - if (!(characterPropertiresWindow.hovered || characterAnimsWindow.hovered) && !characterAnimsWindow.dragging) { + if (/*!(characterPropertiresWindow.hovered || characterAnimsWindow.hovered) && !characterAnimsWindow.dragging*/true) { if (FlxG.mouse.wheel != 0) { zoom += 0.25 * FlxG.mouse.wheel; __camZoom = Math.pow(2, zoom); diff --git a/source/funkin/editors/character/CharacterIconDisplay.hx b/source/funkin/editors/character/CharacterIconDisplay.hx new file mode 100644 index 00000000..e81b88ba --- /dev/null +++ b/source/funkin/editors/character/CharacterIconDisplay.hx @@ -0,0 +1,48 @@ +package funkin.editors.character; + +import openfl.geom.Point; +import openfl.geom.Rectangle; +import openfl.display.BitmapData; +import flixel.util.FlxColor; + +// DONT DELETE I MIGHT USE LATER -lunar +class CharacterIconDisplay extends UISprite { + public var healthBarBG:FlxSprite; + public var healthBar:FlxSprite; + public var textProperties:UIText; + + public function new(x:Float, y:Float, name:String, icon:String, color:Null, barWidth:Int) { + super(x, y); + + var path:String = Paths.image('icons/${icon}'); + if (!Assets.exists(path)) path = Paths.image('icons/face'); + + var imageBitmap:BitmapData = Assets.getBitmapData(path, true, false); + var iconBitmap:BitmapData = new BitmapData(150, 150, true, 0x00000000); + + iconBitmap.copyPixels(imageBitmap, new Rectangle(0, 0, 150, 150), new Point(0,0)); + + loadGraphic(iconBitmap.cropBitmap()); + scale.x = scale.y = 40/pixels.height; + updateHitbox(); + + antialiasing = true; + + healthBarBG = new FlxSprite(x+(width/2), y+(height*(2.25/4))+2).makeSolid(barWidth-Std.int(width), 10, 0xFF000000); + healthBar = new FlxSprite(healthBarBG.x+2, healthBarBG.y+2).makeSolid( + Std.int(healthBarBG.width-4), Std.int(healthBarBG.height-4), + color != null ? color : 0xFFFFFFFF + ); + + textProperties = new UIText(x+width+2, healthBarBG.y-14, 0, 'Character Properties of ${name}...', 13); + + members.push(healthBarBG); + members.push(healthBar); + members.push(textProperties); + } + + public override function draw() { + drawMembers(); + drawSuper(); + } +} \ No newline at end of file diff --git a/source/funkin/editors/character/CharacterPropertiesWindow.hx b/source/funkin/editors/character/CharacterPropertiesWindow.hx index 4ffe5329..ec1cfd96 100644 --- a/source/funkin/editors/character/CharacterPropertiesWindow.hx +++ b/source/funkin/editors/character/CharacterPropertiesWindow.hx @@ -1,27 +1,65 @@ package funkin.editors.character; -import flixel.util.FlxColor; +import funkin.game.Character; -class CharacterPropertiesWindow extends UIWindow { - public var newButton:UIButton; - public var editButton:UIButton; +class CharacterPropertiesWindow extends UISliceSprite { + public var positionXStepper:UINumericStepper; + public var positionYStepper:UINumericStepper; + public var scaleStepper:UINumericStepper; + public var flipXCheckbox:UICheckbox; - public var characterInfo:UIText; + public var cameraXStepper:UINumericStepper; + public var cameraYStepper:UINumericStepper; + public var antialiasingCheckbox:UICheckbox; + public var testAsDropDown:UIDropDown; + public var designedAsDropDown:UIDropDown; + + public function new(x:Float, y:Float, character:Character) { + super(x, y, Std.int(500-32), 204+20, "editors/ui/inputbox"); - public function new() { - super(800-23,23 + 23, 450 + 23, 140, "Character Properties"); + function addLabelOn(ui:UISprite, text:String) + members.push(new UIText(ui.x, ui.y - 24, 0, text)); - newButton = new UIButton( x +(450 + 23)- 25 - 3 - 200, y + 12 + 31, "New Character", null, 200); - members.push(newButton); - newButton.color = FlxColor.GREEN; + positionXStepper = new UINumericStepper(x+16, y + 36, character.globalOffset.x, 0.001, 2, null, null, 100); + members.push(positionXStepper); + addLabelOn(positionXStepper, "Position (X,Y)"); - editButton = new UIButton(newButton.x, newButton.y + 12 + 30 + 4, "Edit Character Info", function () { - CharacterEditor.instance.editInfoWithUI(); - }, 200); - members.push(editButton); + members.push(new UIText(positionXStepper.x + 100 - 32 + 0, positionXStepper.y + 9, 0, ",", 22)); - characterInfo = new UIText(x + 450 + 20 - 42 - 400, y + 36 + 10, 400, "0 Animations:\nFlipped:\nSprite:\nAnim:\nOffset: (,)"); - characterInfo.alignment = LEFT; - members.push(characterInfo); + positionYStepper = new UINumericStepper(positionXStepper.x + 100 - 32 + 26, positionXStepper.y, character.globalOffset.y, 0.001, 2, null, null, 100); + members.push(positionYStepper); + + scaleStepper = new UINumericStepper(positionYStepper.x + 100 - 32 + 32, positionYStepper.y, character.scale.x, 0.001, 2, null, null, 100); + members.push(scaleStepper); + addLabelOn(scaleStepper, "Scale"); + + flipXCheckbox = new UICheckbox(scaleStepper.x + 100 - 32 + 24, scaleStepper.y, "Flipped?", character.flipX); + members.push(flipXCheckbox); + addLabelOn(flipXCheckbox, "Flipped X"); + + cameraXStepper = new UINumericStepper(positionXStepper.x, positionXStepper.y+32+32+4, character.cameraOffset.x, 0.001, 2, null, null, 100); + members.push(cameraXStepper); + addLabelOn(cameraXStepper, "Camera Position (X,Y)"); + + members.push(new UIText(cameraXStepper.x + 100 - 32 + 0, cameraXStepper.y + 9, 0, ",", 22)); + + cameraYStepper = new UINumericStepper(cameraXStepper.x + 100 - 32 + 26, cameraXStepper.y, character.cameraOffset.y, 0.001, 2, null, null, 100); + members.push(cameraYStepper); + + antialiasingCheckbox = new UICheckbox(cameraYStepper.x+100-32+32+32, cameraYStepper.y, "Antialiased?", character.antialiasing); + members.push(antialiasingCheckbox); + addLabelOn(antialiasingCheckbox, "Antialiasing"); + + testAsDropDown = new UIDropDown(cameraXStepper.x, cameraXStepper.y+32+32+4, 226+8, 32, ["PLAYER", "OPPONENT"], 0); + members.push(testAsDropDown); + addLabelOn(testAsDropDown, "Test Character As..."); + + designedAsDropDown = new UIDropDown(testAsDropDown.x+226+8, testAsDropDown.y, 226+8, 32, ["PLAYER", "OPPONENT"], 0); + members.push(designedAsDropDown); + addLabelOn(designedAsDropDown, "Char Desgined As..."); + + antialiasingCheckbox.x+=14; + for (checkbox in [flipXCheckbox, antialiasingCheckbox]) + {checkbox.y += 3; checkbox.x += 12;} } } \ No newline at end of file diff --git a/source/funkin/editors/ui/UIButtonList.hx b/source/funkin/editors/ui/UIButtonList.hx index ec8385e5..6d4161ad 100644 --- a/source/funkin/editors/ui/UIButtonList.hx +++ b/source/funkin/editors/ui/UIButtonList.hx @@ -104,14 +104,14 @@ class UIButtonList extends UIWindow { super.update(elapsed); - nextscrollY = FlxMath.bound(buttonCameras.scroll.y - (hovered ? FlxG.mouse.wheel : 0) * 12, -buttonSpacing, Math.max((addButton.y + 32 + (buttonSpacing*1.5)) - buttonCameras.height, -buttonSpacing)); + nextscrollY = FlxMath.bound(nextscrollY - (hovered ? FlxG.mouse.wheel : 0) * 12, -buttonSpacing, Math.max((addButton.y + 32 + (buttonSpacing*1.5)) - buttonCameras.height, -buttonSpacing)); if (curMoving != null && dragging) { nextscrollY -= Math.min((bHeight - 100) - FlxG.mouse.getWorldPosition(buttonCameras).y, 0) / 8; nextscrollY += Math.min(FlxG.mouse.getWorldPosition(buttonCameras).y - 100, 0) / 8; } - buttonCameras.scroll.y = nextscrollY; + buttonCameras.scroll.y = FlxMath.lerp(buttonCameras.scroll.y, nextscrollY, 1/3); for (i => button in buttons.members) { if (button == null) continue;