removed desktop (new ui framework)

This commit is contained in:
Yoshman29
2023-03-14 19:26:08 +01:00
parent b12d91e172
commit 758a02c379
60 changed files with 220 additions and 2500 deletions
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

-36
View File
@@ -1,36 +0,0 @@
<theme folder="desktop/ui/">
<!-- WINDOW!! !-->
<captionActive path="caption" textColor="#FFFFFF" left="5" top="30" right="5" bottom="5" textSize="16" />
<captionInactive path="captionInactive" textColor="#AAFFFFFF" left="5" top="30" right="5" bottom="5" />
<captionButtons path="captionButtons" size="21,21" margin="2,0" offset="4,6" />
<window color="255,255,255" textColor="0,0,0" font="file://C:/Windows/fonts/tahoma.ttf" fontSize="11"/>
<!-- BUTTONS !-->
<normalButton path="button" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<hoverButton path="buttonHover" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<pressedButton path="buttonPressed" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<disabledButton path="buttonDisabled" textColor="128,128,128" left="4" top="4" right="4" bottom="4" />
<!-- CHECKBOX -->
<checkbox path="checkbox" width="16" height="16"/>
<!-- TABS -->
<tabBackground path="tabBody" textColor="0,0,0" left="4" top="0" right="4" bottom="4" />
<tabButtonSelected path="tab" textColor="255,255,255" left="4" top="4" right="4" bottom="0" />
<tabButtonUnselected path="tabNonSelected" textColor="0,0,0" left="4" top="6" right="4" bottom="4" />
<tabButtonHover path="tabHover" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<tabButtonPressed path="tabPressed" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<!-- CONTEXT MENU -->
<contextBackground path="context" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<contextOption path="contextOption" textColor="255,255,255" height="20" />
<!-- MENU BAR -->
<menuBar path="menuBar" height="20" />
<!-- TEXTBOX -->
<textbox path="textbox" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<textboxHover path="textboxHover" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<textboxPressed path="textboxPressed" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
<textboxFocused path="textboxFocus" textColor="0,0,0" left="4" top="4" right="4" bottom="4" />
</theme>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

+1 -1
View File
@@ -1 +1 @@
2492
2495
-222
View File
@@ -1,222 +0,0 @@
package funkin.desktop;
import flixel.math.FlxRect;
import openfl.geom.Rectangle;
import lime.app.Application;
import openfl.display.BitmapData;
import flixel.system.scaleModes.BaseScaleMode;
import flixel.system.scaleModes.FixedScaleAdjustSizeScaleMode;
import flixel.math.FlxPoint;
import flixel.util.FlxDestroyUtil;
import funkin.desktop.editors.*;
import funkin.desktop.windows.*;
import funkin.desktop.theme.Theme;
class DesktopMain extends MusicBeatState {
public var oldScaleMode:BaseScaleMode;
public var wallpaper:FlxSprite;
public var screenSize:FlxPoint;
public var windows:WindowGroup<Window>;
public static var instance:DesktopMain;
public static var currentFocus:IDesktopFocusableObject;
public static var mouseInput:MouseInput;
public static var theme:Theme = null;
public static var contextMenu:ContextMenu = null;
public static function init() {
theme = Theme.loadFromAssets(Paths.getPath('images/desktop/ui.xml', TEXT, null));
mouseInput = new MouseInput();
FlxG.signals.preUpdate.add(function() {
updateMouseInput();
});
}
public override function create() {
super.create();
instance = this;
FlxG.mouse.useSystemCursor = FlxG.mouse.visible = true;
oldScaleMode = FlxG.scaleMode;
FlxG.scaleMode = new FixedScaleAdjustSizeScaleMode(false, false);
wallpaper = new FlxSprite();
#if windows
try {
wallpaper.loadGraphic(BitmapData.fromFile('${Sys.getEnv("AppData")}\\Microsoft\\Windows\\Themes\\TranscodedWallpaper'));
} catch(e) #end wallpaper.loadGraphic(Paths.image("menus/menuBG"));
wallpaper.scrollFactor.set(0, 0); // anchor at top left
wallpaper.antialiasing = true;
add(wallpaper);
screenSize = new FlxPoint(-1, -1);
windows = new WindowGroup<Window>();
add(windows);
}
private static function updateMouseInput() {
mouseInput.set(FlxG.mouse.pressed, FlxG.mouse.justPressed, FlxG.mouse.justReleased, FlxG.mouse.pressedRight, FlxG.mouse.justPressedRight, FlxG.mouse.justReleasedRight);
}
public override function update(elapsed:Float) {
updateMouseInput();
if (contextMenu != null)
contextMenu.update(elapsed);
super.update(elapsed);
if (screenSize.x != FlxG.width || screenSize.y != FlxG.height) {
screenSize.set(FlxG.width, FlxG.height);
updateScreenRes();
}
// debug window
if (FlxG.keys.justPressed.SPACE)
windows.add(new Window(new HelloWorld()));
if (FlxG.keys.justPressed.F1)
windows.add(new Window(new CharacterEditor('dad')));
if (FlxG.keys.justPressed.F2)
windows.add(new Window(new EditorPlayState()));
FlxG.sound.enableVolumeChanges = !(currentFocus is IDesktopInputObject);
// TEMPORARY ESCAPE KEY UNTIL TASKBAR IS ADDED
if (FlxG.keys.justPressed.ESCAPE) FlxG.switchState(new funkin.menus.MainMenuState());
}
public function openWindow(content:WindowContent) {
return windows.add(new Window(content));
}
public override function draw() {
super.draw();
if (contextMenu != null)
contextMenu.draw();
}
public function updateScreenRes() {
// update wallpaper
wallpaper.setUnstretchedGraphicSize(FlxG.width, FlxG.height);
for(e in windows) {
e.onDesktopSizeChange(FlxG.width, FlxG.height);
}
}
public override function destroy() {
super.destroy();
FlxG.sound.enableVolumeChanges = true;
contextMenu = FlxDestroyUtil.destroy(contextMenu);
FlxG.scaleMode = oldScaleMode;
FlxG.mouse.useSystemCursor = FlxG.mouse.visible = false;
// TODO: switch back while using config
FlxG.resizeGame(1280, 720);
if (screenSize != null)
screenSize.put();
}
public function focusWindow(window:Window) {
windows.remove(window, true);
windows.add(window);
layerCameras();
}
public function layerCameras() {
for(win in windows.members) {
FlxG.cameras.remove(win.windowCaptionCamera, false);
for(e in win.windowCameras) FlxG.cameras.remove(e.camera, false);
}
for(win in windows.members) {
FlxG.cameras.add(win.windowCaptionCamera, false);
for(e in win.windowCameras) FlxG.cameras.add(e.camera, false);
}
}
public static function loseFocus(obj:IDesktopFocusableObject) {
if (currentFocus == obj) {
currentFocus.onFocusLost();
currentFocus = null;
}
}
public static function setFocus(obj:IDesktopFocusableObject) {
if (currentFocus == obj) return;
if (currentFocus != null)
currentFocus.onFocusLost();
(currentFocus = obj).onFocus();
}
public static function hasFocus(obj:IDesktopFocusableObject) {
return currentFocus == obj;
}
}
class MouseInput {
public var pressed:Bool = false;
public var justPressed:Bool = false;
public var justReleased:Bool = false;
public var pressedRight:Bool = false;
public var justPressedRight:Bool = false;
public var justReleasedRight:Bool = false;
public var screenPos:FlxPoint = null;
private var __cancelled:Bool = false;
public function cancel() {
pressed = justPressed = justReleased = pressedRight = justPressedRight = justReleasedRight = false;
__cancelled = true;
}
public function new() {}
public function set(pressed:Bool, justPressed:Bool, justReleased:Bool, pressedRight:Bool, justPressedRight:Bool, justReleasedRight:Bool) {
this.pressed = pressed;
this.justPressed = justPressed;
this.justReleased = justReleased;
this.pressedRight = pressedRight;
this.justPressedRight = justPressedRight;
this.justReleasedRight = justReleasedRight;
this.screenPos = FlxG.mouse.getScreenPosition(FlxG.camera);
this.__cancelled = false;
}
public function overlaps(spr:FlxObject, ?camera:FlxCamera) {
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:FlxRect, ?camera:FlxCamera) {
if (__cancelled) return false;
if (camera == null) camera = FlxG.camera;
if (spr is FlxObject && camera != null) {
var obj = cast(spr, FlxObject);
rect.x -= camera.scroll.x * obj.scrollFactor.x;
rect.y -= camera.scroll.y * obj.scrollFactor.y;
}
var pos = FlxG.mouse.getScreenPosition(camera);
return ((pos.x > rect.x) && (pos.x < rect.x + rect.width)) && ((pos.y > rect.y) && (pos.y < rect.y + rect.height));
}
}
interface IDesktopFocusableObject {
public function onFocus():Void;
public function onFocusLost():Void;
}
// useless, only here for
interface IDesktopInputObject {
}
-53
View File
@@ -1,53 +0,0 @@
package funkin.desktop;
import flixel.util.FlxDestroyUtil.IFlxDestroyable;
import openfl.events.Event;
import lime.app.Application;
import lime.ui.Window;
class DesktopScreen implements IFlxDestroyable {
public var cameras:Array<FlxCamera> = [];
public var window:Window;
public function new() {
window = Application.current.createWindow({
x: 0,
y: 0,
width: FlxG.width,
height: FlxG.height
});
@:privateAccess
Application.current.__addWindow(window);
window.stage.addEventListener(Event.ENTER_FRAME, onFrameEnter);
FlxG.signals.preDraw.add(__onPreDraw);
FlxG.signals.postDraw.add(__onPostDraw);
window.onClose.add(destroy);
}
public function addCamera(cam:FlxCamera) {
cameras.push(cam);
window.stage.addChild(cam.flashSprite);
}
private inline function __onPreDraw() {}
private inline function __onPostDraw() {}
private function onFrameEnter(event:Event) {
try {
@:privateAccess
for(c in cameras)
c.render();
} catch(e) {
trace(e.toString());
}
}
public function destroy() {
for(c in cameras)
c.destroy();
window.close();
}
}
-10
View File
@@ -1,10 +0,0 @@
package funkin.desktop;
class DesktopUtils {
public static inline 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);
}
}
@@ -1,341 +0,0 @@
package funkin.desktop.editors;
import funkin.game.Character;
using funkin.utils.XMLUtil;
class CharacterEditor extends WindowContent {
public function new(curCharacter:String) {
super('Character Editor - Loading...', 0, 0, 1200, 600);
}
public var camHUD:FlxCamera;
public var char:Character;
public var curCharacter:String;
public var camFollow:FlxObject;
public var tabView:TabView;
public var animList:Array<AnimData> = [];
public var animListNames:Array<String> = [];
public var curAnim:AnimData;
public var menuBar:MenuBar;
/**
* SILHOUETTES
*/
public var silhouetteDad:Character;
public var silhouetteGf:Character;
public var silhouetteBf:Character;
/**
* ANIMATION TAB
*/
public var animsDropDown:DropDown;
public var animNameInput:InputBox;
public var animPrefixInput:InputBox;
public var animLoopCheckbox:Checkbox;
public var animFpsStepper:NumericStepper;
public var animOffsetX:NumericStepper;
public var animOffsetY:NumericStepper;
/**
* CHARACTER SETTINGS TAB
*/
public var charSpriteInput:InputBox;
public var charIconInput:InputBox;
public var charIsPlayerCheckbox:Checkbox;
public var charIsGFCheckbox:Checkbox;
public var charOffsetXStepper:NumericStepper;
public var charOffsetYStepper:NumericStepper;
public var charHoldTimeStepper:NumericStepper;
public var charFlipXCheckbox:Checkbox;
public var charScaleStepper:NumericStepper;
public var charAntialiasingCheckbox:Checkbox;
public override function create() {
super.create();
// camera stuff
parent.windowCameras[0].resizeScroll = false;
camHUD = new FlxCamera(0, 0, 1200, 600, 1);
camHUD.pixelPerfectRender = true;
camHUD.bgColor = 0;
parent.addCamera(camHUD);
// stage
var bg = new FlxSprite(-600, -200).loadAnimatedGraphic(Paths.image('stages/default/stageback'));
bg.scrollFactor.set(0.9, 0.9);
var stageFront = new FlxSprite(-600, 600).loadAnimatedGraphic(Paths.image('stages/default/stagefront'));
silhouetteDad = new Character(100, 100, "dad", false);
silhouetteGf = new Character(400, 130, "gf", false);
silhouetteGf.scrollFactor.set(0.95, 0.95);
silhouetteBf = new Character(770, 100, "bf", true);
for (e in [silhouetteDad, silhouetteGf, silhouetteBf]) {
e.color = 0xFF000000;
e.visible = false;
e.alpha = 0.25;
}
for (e in [bg, stageFront, silhouetteDad, silhouetteGf, silhouetteBf]) {
e.antialiasing = true;
add(e);
}
char = new Character(100, 100, curCharacter, false, false);
add(char);
title = 'Character Editor - ${char.curCharacter}.xml';
// character setup & following
var charMidpoint = char.getGraphicMidpoint();
camFollow = new FlxObject(0, 0, 2, 2);
camFollow.setPosition(charMidpoint.x, charMidpoint.y);
add(camFollow);
charMidpoint.put();
windowCamera.follow(camFollow, LOCKON, 999);
// loading animations from character
animList = [];
if (char.xml != null)
for(anim in char.xml.nodes.anim)
animList.push(anim.extractAnimFromXML());
// interface setup
setupTabView();
// todo: menu bar handlers
menuBar = new MenuBar([
{
name: "File",
options: [
{
name: "New"
},
{
name: "Open"
},
{
name: "Save"
},
{
name: "Save As..."
},
{
name: "Exit"
}
]
},
{
name: "Edit",
options: [
{
name: "Add Animation..."
},
{
name: "Delete Animation"
}
]
},
{
name: "View",
options: [
{
name: "Lock Camera on Character"
},
{
name: "Reset Camera Position",
callback: resetCamPos
},
{
name: "Reset Camera Zoom",
callback: resetCamZoom
},
{
name: "Toggle Boyfriend Silhouette",
callback: toggleSilBF
},
{
name: "Toggle Dad Silhouette",
callback: toggleSilDad
},
{
name: "Toggle Girlfriend Silhouette",
callback: toggleSilGF
}
]
},
{
name: "Help",
options: [
{
name: "Open Editor Documentation"
},
{
name: "Open Engine Documentation"
}
]
}
]);
menuBar.cameras = [camHUD];
add(menuBar);
}
public function setupTabView() {
tabView = new TabView(800, 20, 400, 580, ["Animation Settings", "Character Settings"]);
tabView.updateAnchor(1, 0, [camHUD]);
add(tabView);
addAnimTab();
addCharTab();
refreshAnims();
changeAnim(0);
}
public function addAnimTab() {
var content:Array<FlxBasic> = [];
var label:WindowText = null;
content.push(label = new WindowText(10, 10, 0, "Animations"));
content.push(animsDropDown = new DropDown(10, label.y + label.height, 380, [], function(id) {
changeAnim(id);
}));
content.push(label = new WindowText(10, animsDropDown.y + animsDropDown.height + 10, 0, "Animation Name"));
content.push(animNameInput = new InputBox(10, label.y + label.height, 380, ""));
content.push(label = new WindowText(10, animNameInput.y + animNameInput.height + 10, 0, "Animation Prefix"));
content.push(animPrefixInput = new InputBox(10, label.y + label.height, 380, ""));
content.push(animLoopCheckbox = new Checkbox(10, animPrefixInput.y + animPrefixInput.height + 10, 380, "Loop"));
content.push(label = new WindowText(10, animLoopCheckbox.y + animLoopCheckbox.height + 10, 0, "Animation FPS (Frames per second)"));
content.push(animFpsStepper = new NumericStepper(10, label.y + label.height, 380, 0));
content.push(label = new WindowText(10, animFpsStepper.y + animFpsStepper.height + 10, 0, "Animation Offset (Relative to scale)"));
content.push(animOffsetX = new NumericStepper(10, label.y + label.height, 180, 0));
content.push(animOffsetY = new NumericStepper(200, label.y + label.height, 180, 0));
for(e in [animOffsetX, animOffsetY])
e.increment = 10;
for(spr in content)
tabView.tabs[0].add(spr);
}
public function addCharTab() {
var content:Array<FlxObject> = [];
var label:WindowText = null;
content.push(label = new WindowText(10, 10, 0, "Sprite Name (images/characters/)"));
content.push(charSpriteInput = new InputBox(10, label.y + label.height, 380, char.xml.has.sprite ? char.xml.att.sprite : ""));
content.push(label = new WindowText(10, content.last().y + content.last().height, 0, "Icon Name (images/icons/)"));
content.push(charIconInput = new InputBox(10, label.y + label.height, 380, char.icon.getDefault("")));
content.push(charIsPlayerCheckbox = new Checkbox(10, content.last().y + content.last().height + 10, 380, "Playable character"));
content.push(label = new WindowText(10, content.last().y + content.last().height, 380, "(Offsets are automatically fixed when playing as a non-playable character and vice versa)"));
charIsPlayerCheckbox.checked = char.xml.getAtt("isPlayer") == "true";
content.push(charIsGFCheckbox = new Checkbox(10, content.last().y + content.last().height + 10, 380, "Is Girlfriend"));
content.push(label = new WindowText(10, content.last().y + content.last().height, 380, "(Characters marked as Girlfriend will replace GF when used as opponent)"));
charIsGFCheckbox.checked = char.isGF;
content.push(charFlipXCheckbox = new Checkbox(10, content.last().y + content.last().height + 10, 380, "Flip Horizontally"));
charFlipXCheckbox.checked = char.__baseFlipped != char.isPlayer;
for(spr in content)
tabView.tabs[1].add(spr);
}
public function changeAnim(id:Int) {
curAnim = animList[id];
if (curAnim == null) return;
char.playAnim(curAnim.name, true);
animNameInput.text = curAnim.name;
animPrefixInput.text = curAnim.anim;
animLoopCheckbox.setChecked(curAnim.loop);
animFpsStepper.value = curAnim.fps;
animOffsetX.value = curAnim.x;
animOffsetY.value = curAnim.y;
}
public function refreshAnims() {
animListNames = [for(e in animList) e.name];
animsDropDown.options = animListNames;
animsDropDown.onSelectionChange(0);
}
public override function update(elapsed:Float) {
super.update(elapsed);
if (parent.focused) {
if (FlxG.keys.pressed.RIGHT) camFollow.x += elapsed * 500;
if (FlxG.keys.pressed.LEFT) camFollow.x -= elapsed * 500;
if (FlxG.keys.pressed.DOWN) camFollow.y += elapsed * 500;
if (FlxG.keys.pressed.UP) camFollow.y -= elapsed * 500;
}
if (curAnim != null) {
// animation updating
var shouldUpdate = false;
var oldName:String = curAnim.name;
var updateListAsWell = shouldUpdate = (curAnim.name != (curAnim.name = animNameInput.text));
shouldUpdate = (curAnim.anim != (curAnim.anim = animPrefixInput.text)) || shouldUpdate;
shouldUpdate = (curAnim.fps != (curAnim.fps = Std.int(animFpsStepper.value))) || shouldUpdate;
shouldUpdate = (curAnim.loop != (curAnim.loop = animLoopCheckbox.checked)) || shouldUpdate;
shouldUpdate = (curAnim.x != (curAnim.x = animOffsetX.value)) || shouldUpdate;
shouldUpdate = (curAnim.y != (curAnim.y = animOffsetY.value)) || shouldUpdate;
if (shouldUpdate)
updateCurAnim(oldName, updateListAsWell);
}
char.isPlayer = char.playerOffsets = charIsPlayerCheckbox.checked;
char.isGF = charIsPlayerCheckbox.checked;
char.flipX = char.__baseFlipped = (charFlipXCheckbox.checked != char.isPlayer);
char.x = charIsPlayerCheckbox.checked ? 770 : 100;
}
public function updateCurAnim(?oldName:String, updateListAsWell:Bool = false) {
if (oldName == null)
oldName = char.animation.curAnim != null ? char.animation.curAnim.name : curAnim.name;
char.animation.remove(oldName);
char.animation.curAnim = null;
XMLUtil.addAnimToSprite(char, curAnim);
char.playAnim(curAnim.name, true);
}
public override function onWindowResize(width:Int, height:Int) {
tabView.resize(400, height - 20);
}
/**
* =========== CONTEXT MENU OPTIONS ===========
*/
/**
* View
*/
public function resetCamPos() {
var pos = char.getCameraPosition();
camFollow.setPosition(pos.x, pos.y);
}
public function resetCamZoom() {
windowCamera.zoom = 1;
}
/**
* Silhouettes
*/
public function toggleSilBF() silhouetteBf.visible = !silhouetteBf.visible;
public function toggleSilDad() silhouetteDad.visible = !silhouetteDad.visible;
public function toggleSilGF() silhouetteGf.visible = !silhouetteGf.visible;
}
@@ -1,12 +0,0 @@
package funkin.desktop.editors;
class CommandPrompt extends WindowContent {
public function new() {
super("Command Prompt", 100, 100, 960, 480);
}
public override function create() {
super.create();
windowCamera.bgColor = 0xFF000000;
}
}
@@ -1,94 +0,0 @@
package funkin.desktop.editors;
import flixel.math.FlxPoint;
class EditorPlayState extends WindowContent {
var state:PlayState;
public function new() {
super("PlayState", 120, 120, 1280, 720);
state = new PlayState();
}
public override function create() {
super.create();
beforeStateShit();
state.camera = parent.windowCameras[0].camera;
state.create();
afterStateShit();
parent.windowCameras[0].resizeScroll = false;
parent.windowCameras.push(
{
camera: state.camHUD,
width: 1280,
height: 720,
resizeScroll: true
}
);
parent.move(winX, winY);
parent.resize(1280, 720);
beforeStateShit();
state.createPost();
afterStateShit();
}
var oldSize = FlxPoint.get(FlxG.width, FlxG.height);
var oldCamList:Array<FlxCamera>;
var oldCam:FlxCamera;
public function beforeStateShit() {
oldSize.set(FlxG.width, FlxG.height);
@:privateAccess
FlxG.width = 1280;
@:privateAccess
FlxG.height = 720;
oldCamList = FlxG.cameras.list;
oldCam = FlxG.camera;
@:privateAccess
FlxG.cameras.list = [for(e in parent.windowCameras) e.camera];
FlxG.camera = parent.windowCameras[0].camera;
}
public function afterStateShit() {
@:privateAccess
FlxG.width = Std.int(oldSize.x);
@:privateAccess
FlxG.height = Std.int(oldSize.y);
parent.windowCameras = [for(e in FlxG.cameras.list) {
camera: e,
width: 1280,
height: 720,
resizeScroll: false
}];
@:privateAccess
FlxG.cameras.list = oldCamList;
FlxG.camera = oldCam;
oldCamList = null;
oldCam = null;
}
public override function update(elapsed:Float) {
beforeStateShit();
super.update(elapsed);
@:privateAccess
FlxG.cameras.update(elapsed);
state.tryUpdate(elapsed);
afterStateShit();
}
public override function destroy() {
beforeStateShit();
super.destroy();
state.destroy();
afterStateShit();
}
public override function draw() {
beforeStateShit();
super.draw();
state.draw();
afterStateShit();
}
}
@@ -1,58 +0,0 @@
package funkin.desktop.editors;
import flixel.util.FlxDestroyUtil.IFlxDestroyable;
import flixel.addons.ui.FlxUIText;
class HelloWorld extends WindowContent {
public override function new() {
super("Test Window", 100, 100, 640, 480);
}
public override function create() {
super.create();
var helloWorldText = new WindowText(0, 0, 0, "Hello, World!");
helloWorldText.scrollFactor.set(0.5, 0.5);
helloWorldText.cameraCenter(camera);
add(helloWorldText);
var t = new WindowText(0, 0, 0, "Bottom right text!");
t.setPosition(630 - t.width, 470 - t.height);
t.scrollFactor.set(1, 1);
add(t);
var tabs = new TabView(330, 10, 300, 500, ["Tab 1", "Tab 2", "Tab 3"]);
tabs.updateAnchor(1, 0);
add(tabs);
var checkbox = new Checkbox(10, 40, 0, "Test Checkbox", CHECKED);
var text = new WindowText(10, 10, 180, "Stuff in page 1");
tabs.tabs[0].add(text);
tabs.tabs[0].add(checkbox);
var text2 = new WindowText(10, 10, 180, "Stuff in page 2");
tabs.tabs[1].add(text2);
var butt = new Button(10, 10, "Test", function() {
parent.showMessage("Test", "Test", ERROR);
});
butt.scrollFactor.set();
add(butt);
}
public var time:Float = 0;
public var coolAssMode:Bool = false;
public override function update(elapsed:Float) {
super.update(elapsed);
time += elapsed;
if (FlxG.keys.justPressed.M) coolAssMode = !coolAssMode;
if (coolAssMode) {
width = 500 + Std.int(Math.cos(time * Math.PI) * 250);
height = 500 + Std.int(Math.sin(time * Math.PI) * 250);
}
parent.updateWindowFrame();
}
}
@@ -1,72 +0,0 @@
package funkin.desktop.editors;
import flixel.util.typeLimit.OneOfTwo;
import flixel.util.FlxDestroyUtil.IFlxDestroyable;
import flixel.addons.ui.FlxUIText;
class MessageBox extends WindowContent {
public var caption:String;
public var message:String;
public var msgIcon:MessageBoxIcon;
public var callback:Int->Void = null;
private var __buttons:Array<OneOfTwo<String, Butt>> = null;
public override function new(caption:String, message:String, icon:MessageBoxIcon, ?buttons:Array<OneOfTwo<String, Butt>>, ?callback:Int->Void) {
super(caption, 100, 100, 500, 500);
this.caption = caption;
this.message = message;
this.msgIcon = icon;
this.callback = callback;
this.__buttons = buttons;
}
public override function create() {
super.create();
parent.canMinimize = parent.resizeable = false;
var text = new WindowText(10, 10, 0, message);
if (text.width > 500)
text.fieldWidth = 500;
add(text);
setSize(Std.int(Math.max(text.width + 20, 240)), Std.int(text.height + 20));
if (__buttons == null || __buttons.length <= 0) __buttons = ["OK"];
var firstButt:Button = null;
for(k=>b in __buttons) {
var label:String = null;
var callback:Void->Void = null;
if (b is String) {
label = cast(b, String);
} else if (b is Dynamic) {
label = Reflect.field(b, "label");
callback = Reflect.field(b, "callback");
}
var button = new Button(490, 490, label, function() {
parent.close();
if (callback != null) callback();
if (this.callback != null) this.callback(k);
});
button.x -= button.width;
button.y -= button.height;
button.scrollFactor.set(1, 1);
add(button);
if (firstButt == null) firstButt = button;
}
setSize(Std.int(width), Std.int(height + firstButt.height + 10));
}
}
@:enum
abstract MessageBoxIcon(Int) {
var ERROR = 0;
var ALERT = 1;
var INFORMATION = 2;
var QUESTION = 3;
}
// HAHA BUTT!! *minion laugh*
typedef Butt = {
var label:String;
@:optional var callback:Void->Void;
}
-4
View File
@@ -1,4 +0,0 @@
package funkin.desktop.editors;
import funkin.desktop.windows.*;
import funkin.desktop.sprites.*;
-3
View File
@@ -1,3 +0,0 @@
using funkin.desktop.DesktopUtils;
using funkin.desktop.windows.ContextMenu;
using funkin.desktop.DesktopMain;
-126
View File
@@ -1,126 +0,0 @@
package funkin.desktop.sprites;
import funkin.desktop.DesktopMain.IDesktopFocusableObject;
import funkin.desktop.theme.Theme;
import flixel.addons.ui.FlxUIText;
import flixel.math.FlxPoint;
import funkin.desktop.windows.WindowGroup;
using funkin.desktop.DesktopMain;
class Button extends FlxObject implements IDesktopFocusableObject {
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:WindowText;
private override function get_width() {
return normalSprite.width;
}
private override function get_height() {
return normalSprite.height;
}
public function new(x:Float, y:Float, text:String = "", callback:Void->Void, ?normalButton:ThemeData, ?hoverButton:ThemeData, ?pressedButton:ThemeData, ?disabledButton:ThemeData) {
super();
this.x = x;
this.y = y;
this.width = 75;
this.height = 24;
this.callback = callback;
scrollFactor.set();
if (normalButton == null) normalButton = DesktopMain.theme.normalButton;
if (hoverButton == null) hoverButton = DesktopMain.theme.hoverButton;
if (pressedButton == null) pressedButton = DesktopMain.theme.pressedButton;
if (disabledButton == null) disabledButton = DesktopMain.theme.disabledButton;
normalSprite = new SpliceSprite(Paths.image(normalButton.sprite), x, y, 75, 24, normalButton.left, normalButton.top, normalButton.bottom, normalButton.right);
hoverSprite = new SpliceSprite(Paths.image(hoverButton.sprite), x, y, 75, 24, hoverButton.left, hoverButton.top, hoverButton.bottom, hoverButton.right);
pressedSprite = new SpliceSprite(Paths.image(pressedButton.sprite), x, y, 75, 24, pressedButton.left, pressedButton.top, pressedButton.bottom, pressedButton.right);
disabledSprite = new SpliceSprite(Paths.image(disabledButton.sprite), x, y, 75, 24, disabledButton.left, disabledButton.top, disabledButton.bottom, disabledButton.right);
label = new WindowText(0, 0, 75, text);
label.alignment = CENTER;
}
public override function update(elapsed:Float) {
super.update(elapsed);
var mouseInput = DesktopMain.mouseInput;
if (mouseInput.overlaps(normalSprite, camera)) {
if (mouseInput.justReleased) {
callback();
return;
}
if (mouseInput.justPressed || mouseInput.pressed) {
this.setFocus();
frame = 2;
}
else
frame = 1;
mouseInput.cancel();
} else
frame = 0;
if (disabled) frame = 3;
for(e in [normalSprite, hoverSprite, pressedSprite, disabledSprite])
e.update(elapsed);
label.color = switch(frame) {
case 1: DesktopMain.theme.hoverButton.textColor;
case 2: DesktopMain.theme.pressedButton.textColor;
case 3: DesktopMain.theme.disabledButton.textColor;
default: DesktopMain.theme.normalButton.textColor;
}
}
public override function destroy() {
DesktopMain.loseFocus(this);
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.copyProperties(this);
spr.draw();
label.y += (height - label.height) / 2;
label.draw();
additionalDraw();
}
public function additionalDraw() {}
public function onFocus() {}
public function onFocusLost() {}
}
-70
View File
@@ -1,70 +0,0 @@
package funkin.desktop.sprites;
import flixel.math.FlxRect;
import flixel.text.FlxText;
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");
scrollFactor.set();
}
public function setChecked(checked:Bool) {
this.checked = cast checked;
}
public override function update(elapsed:Float) {
super.update(elapsed);
checkboxSprite.update(elapsed);
var overlaps = DesktopMain.mouseInput.overlapsRect(this, new FlxRect(x, y, width + 20, height), 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<Bool>) from Null<Bool> to Null<Bool> from Bool to Bool {
var CHECKED:CheckState = true;
var UNCHECKED:CheckState = false;
var BOTH:CheckState = null;
}
-40
View File
@@ -1,40 +0,0 @@
package funkin.desktop.sprites;
import funkin.desktop.theme.Theme.ThemeData;
import flixel.math.FlxPoint;
class DropDown extends Button {
public var selectedIndex:Int = -1;
public var onChange:Int->Void;
public var options:Array<String>;
public function new(x:Float, y:Float, w:Float, options:Array<String>, onChange:Int->Void, curId:Int = 0, ?normalButton:ThemeData, ?hoverButton:ThemeData, ?pressedButton:ThemeData, ?disabledButton:ThemeData) {
super(x, y, "", onClick, normalButton, hoverButton, pressedButton, disabledButton);
this.options = options;
onSelectionChange(curId);
this.onChange = onChange;
}
public function onClick() {
var pos:FlxPoint = getScreenPosition(null, camera);
pos.y += height;
var camPos = camera != null ? FlxPoint.get(camera.x, camera.y) : FlxPoint.get();
ContextMenu.open(pos.x + camPos.x, pos.y + camPos.y, [for(o in options) {
{
name: o
}
}], onSelectionChange);
pos.put();
camPos.put();
}
public function onSelectionChange(id:Int) {
selectedIndex = id;
label.text = options[id];
if (onChange != null)
onChange(id);
}
}
-105
View File
@@ -1,105 +0,0 @@
package funkin.desktop.sprites;
import openfl.ui.Keyboard;
import openfl.events.KeyboardEvent;
import lime.app.Application;
class InputBox extends Button implements IDesktopInputObject {
public var index:Int = 0;
public static var insertMode:Bool = false;
public var text(get, set):String;
private inline function set_text(t:String):String
return label.text = t;
private inline function get_text():String
return label.text;
public var onChange:Void->Void;
public var onConfirm:Void->Void;
public function new(x:Float, y:Float, w:Float, t:String, ?onChange:Void->Void) {
super(x, y, t, function() {
setIndex(label.text.length);
disabled = true;
}, DesktopMain.theme.textbox, DesktopMain.theme.textboxHover, DesktopMain.theme.textboxPressed, DesktopMain.theme.textboxFocused);
this.resize(w, height);
this.label.alignment = LEFT;
FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
Application.current.window.onTextInput.add(onTextInput);
}
private function onKeyDown(event:KeyboardEvent) {
if (!this.hasFocus()) return;
switch(event.keyCode) {
case Keyboard.ESCAPE:
this.loseFocus();
case Keyboard.INSERT:
insertMode = !insertMode;
case Keyboard.LEFT:
changeIndex(-1);
case Keyboard.RIGHT:
changeIndex(1);
case Keyboard.HOME:
setIndex(0);
case Keyboard.END:
setIndex(text.length);
case Keyboard.DELETE:
text = text.substr(0, index) + text.substring(index + 1, text.length);
onTextInput("");
case Keyboard.BACKSPACE:
text = text.substr(0, index <= 0 ? 0 : index - 1) + text.substring(index, text.length);
changeIndex(-1);
onTextInput("");
case Keyboard.ENTER | Keyboard.NUMPAD_ENTER:
if (onChange != null)
onChange();
if (onConfirm != null)
onConfirm();
default:
// nothing
}
}
private function onTextInput(input:String) {
if (!this.hasFocus()) return;
if (input.length > 0) {
text = text.substr(0, index) + input + text.substring(index, text.length);
if (!insertMode)
index += input.length;
}
if (onChange != null)
onChange();
}
public override function update(elapsed:Float) {
if (DesktopMain.mouseInput.justPressed && !DesktopMain.mouseInput.overlaps(this, camera))
this.loseFocus();
super.update(elapsed);
}
public override function onFocusLost() {
super.onFocusLost();
if (disabled != (disabled = false)) {
if (onChange != null)
onChange();
if (onConfirm != null)
onConfirm();
}
}
public inline function changeIndex(change:Int) {
setIndex(Std.int(FlxMath.bound(index + change, 0, label.text.length)));
}
public inline function setIndex(index:Int) {
this.index = index;
}
public override function destroy() {
super.destroy();
}
}
-52
View File
@@ -1,52 +0,0 @@
package funkin.desktop.sprites;
import flixel.math.FlxPoint;
import funkin.desktop.windows.WindowGroup;
class MenuBar extends WindowGroup<FlxBasic> {
public var spr:FlxSprite;
public var buttons:Array<Button> = [];
public function new(trees:Array<TopMenuTree>) {
super();
spr = new FlxSprite(0, 0);
spr.loadGraphic(Paths.image(DesktopMain.theme.menuBar.sprite));
add(spr);
var lastX:Float = 0;
for(t in trees) {
var b:Button = null;
b = new Button(lastX, 0, t.name, function() {
var pos:FlxPoint = b.getScreenPosition(null, camera);
pos.y += b.height;
var camPos = camera != null ? FlxPoint.get(camera.x, camera.y) : FlxPoint.get();
ContextMenu.open(pos.x + camPos.x, pos.y + camPos.y, t.options, function(i) {});
pos.put();
});
b.label.fieldWidth = 0;
@:privateAccess b.label._regen = true;
b.resize(b.label.width + 20, 20);
lastX = b.x + b.width;
b.normalSprite.visible = false;
buttons.push(b);
add(b);
}
}
public override function update(elapsed:Float) {
super.update(elapsed);
spr.setGraphicSize(FlxG.width, 20);
spr.updateHitbox();
}
}
typedef TopMenuTree = {
var name:String;
var options:Array<ContextOption>;
}
@@ -1,76 +0,0 @@
package funkin.desktop.sprites;
// TODO: FIX MEMORY GOING BRRRRRRRRRRRRRRRRRRRRR
class NumericStepper extends InputBox {
public var decimals:Int = 0;
public var increment:Float = 1;
@:isVar public var value(get, set):Float = 0;
public var onValueChange:Void->Void;
public var addButton:Button;
public var subButton:Button;
public function new(x:Float, y:Float, w:Float, v:Float, ?onValueChange:Void->Void) {
super(x, y, w, Std.string(v));
addButton = new Button(w - (height * 2), 0, "+", onAdd);
addButton.resize(height, height);
subButton = new Button(w - (height), 0, "-", onSub);
subButton.resize(height, height);
onConfirm = onManualChange;
}
public override function resize(width:Float, height:Float) {
super.resize(width - (height * 2), height);
}
public override function update(elapsed:Float) {
addButton.update(elapsed);
subButton.update(elapsed);
super.update(elapsed);
}
public override function additionalDraw() {
addButton.copyProperties(this);
subButton.copyProperties(this);
addButton.x += width;
subButton.x += width + height;
addButton.draw();
subButton.draw();
}
private inline function onSub()
value--;
private inline function onAdd()
value++;
private function onManualChange() {
var v = Std.parseFloat(text);
if (!v.isNaN()) {
value = round(v);
} else {
set_value(value);
}
}
private function set_value(nv:Float) {
if (this.value != (this.value = nv))
if (onValueChange != null)
onValueChange();
text = Std.string(round(this.value));
return this.value;
}
private inline function get_value()
return this.value;
private inline function round(value:Float) {
return decimals <= 0 ? Std.int(value) : FlxMath.roundDecimal(value, decimals);
}
}
@@ -1,133 +0,0 @@
package funkin.desktop.sprites;
import openfl.display.BitmapData;
import openfl.geom.Rectangle;
import openfl.geom.Point;
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 middle:FlxSprite = new FlxSprite();
public var __internalSprite:FlxSprite;
public var slice:Array<Int> = [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;
scrollFactor.set();
__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);
middle.pixels = new BitmapData(_width - _left - _right, _height - _up - _down, 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);
middle.pixels.copyPixels(__internalSprite.pixels, new Rectangle(_left, _up, _width - _left - _right, _height - _up - _down), 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, middle];
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);
// middle by dj snake
middle.setPosition(x + _left, y + _up);
middle.setSpriteSize(width - _left - _right, height - _up - _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);
}
}
-90
View File
@@ -1,90 +0,0 @@
package funkin.desktop.sprites;
import flixel.math.FlxRect;
import funkin.desktop.windows.WindowGroup;
class TabView extends WindowGroup<FlxBasic> {
public var tabBG:SpliceSprite;
public var tabButtons:Array<Button> = [];
public var tabs:Array<WindowGroup<FlxBasic>> = [];
public var bg:SpliceSprite;
public var selectedTab:Int = 0;
public var width:Float;
public var height:Float;
public function new(x:Float, y:Float, width:Float, height:Float, tabs:Array<String>) {
super();
this.x = x;
this.y = y;
var tabBG = DesktopMain.theme.tabBackground;
bg = new SpliceSprite(Paths.image(tabBG.sprite), x, y, 75, 24, tabBG.left, tabBG.top, tabBG.bottom, tabBG.right);
add(bg);
for(k=>t in tabs) {
// BUTTON
var b = new Button(0, 0, t, function() {
switchTab(k);
}, DesktopMain.theme.tabButtonUnselected, DesktopMain.theme.tabButtonHover, DesktopMain.theme.tabButtonPressed, DesktopMain.theme.tabButtonSelected);
tabButtons.push(b);
add(b);
// TAB
var tab = new WindowGroup<FlxBasic>();
tab.y += b.height;
this.tabs.push(tab);
add(tab);
}
resize(width, height);
switchTab(0);
}
public function resize(width:Float, height:Float) {
this.width = width;
this.height = height;
updateButtons();
updateBG();
}
public function updateButtons() {
var bWidth:Float = Math.floor(width / tabs.length);
for(k=>b in tabButtons) {
var w = (k >= tabs.length - 1) ? (width - (bWidth * (tabs.length - 1))) : bWidth;
b.resize(w, 24);
b.x = x + (k * bWidth);
}
}
public function updateBG() {
bg.x = x;
bg.y = y + 24;
bg.resize(width, height - 24);
}
public function switchTab(id:Int) {
selectedTab = id;
for(k=>b in tabButtons)
b.disabled = k == selectedTab;
}
public override function update(elapsed:Float) {
bg.update(elapsed);
for(e in tabButtons)
e.update(elapsed);
if (tabs[selectedTab] != null)
tabs[selectedTab].update(elapsed);
if (DesktopMain.mouseInput.overlapsRect(bg, new FlxRect(x, y, width, height), camera))
DesktopMain.mouseInput.cancel();
}
public override function draw() {
bg.draw();
for(e in tabButtons)
e.draw();
if (tabs[selectedTab] != null)
tabs[selectedTab].draw();
}
}
@@ -1,34 +0,0 @@
package funkin.desktop.sprites;
import flixel.text.FlxText;
import flixel.addons.ui.FlxUIText;
import funkin.desktop.theme.Theme.ThemeData;
class WindowText extends FlxText {
public function new(x:Float, y:Float, w:Float, t:String) {
super(x, y, w, t);
color = 0xFF000000;
scrollFactor.set();
size = 12;
applyFontSettings(DesktopMain.theme.window);
scrollFactor.set();
}
public function applyFontSettings(data:ThemeData) {
if (data.font != null) {
var fontPath:String;
if (data.font.startsWith("file://")) {
fontPath = data.font.substr(7);
while(fontPath.charAt(0) == "/") fontPath = fontPath.substr(1);
} else {
fontPath = Paths.font(data.font);
}
font = fontPath;
}
if (data.fontSize != null)
size = Std.int(data.fontSize);
if (data.textColor != null)
color = data.textColor;
}
}
-156
View File
@@ -1,156 +0,0 @@
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);
}
/**
* CAPTION & WINDOW
*/
public var window:ThemeData = new ThemeData();
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();
/**
* CHECKBOX
*/
public var checkbox:ThemeData = new ThemeData();
/**
* TABS
*/
public var tabBackground:ThemeData = new ThemeData();
public var tabButtonSelected:ThemeData = new ThemeData();
public var tabButtonUnselected:ThemeData = new ThemeData();
public var tabButtonHover:ThemeData = new ThemeData();
public var tabButtonPressed:ThemeData = new ThemeData();
/**
* CONTEXT MENU
*/
public var contextBackground:ThemeData = new ThemeData();
public var contextOption:ThemeData = new ThemeData();
/**
* MENU BAR
*/
public var menuBar:ThemeData = new ThemeData();
/**
* THEME
*/
public var textbox:ThemeData = new ThemeData();
public var textboxHover:ThemeData = new ThemeData();
public var textboxPressed:ThemeData = new ThemeData();
public var textboxFocused: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();
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.font) data.font = element.att.font;
if (element.has.color) data.color = element.att.color.getColorFromDynamic();
if (element.has.fontSize) data.fontSize = Std.parseFloat(element.att.fontSize).getDefault(0);
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.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(
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) {
Logs.trace('Failed to load Desktop Theme: $e', ERROR);
}
}
}
class ThemeData implements IFlxDestroyable {
public var sprite:String = "";
public var font:String = null;
public var fontSize:Null<Float> = null;
public var textColor:Null<FlxColor> = null;
public var color: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 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);
public function new() {}
public function destroy() {
if (margin != null)
margin.put();
if (size != null)
size.put();
if (offset != null)
offset.put();
}
}
@@ -1,102 +0,0 @@
package funkin.desktop.windows;
import flixel.util.FlxDestroyUtil;
import funkin.desktop.sprites.*;
class ContextMenu extends WindowGroup<FlxObject> {
public var bg:SpliceSprite;
public var texts:Array<WindowText> = [];
public var selectionBGs:Array<FlxSprite> = [];
public var callback:Int->Void;
public var contextOptions:Array<ContextOption> = [];
public var contextCamera:FlxCamera;
public override function new(x:Float, y:Float, options:Array<ContextOption>, callback:Int->Void) {
super();
this.callback = callback;
this.contextOptions = options;
var bgTheme = DesktopMain.theme.contextBackground;
var optionTheme = DesktopMain.theme.contextOption;
bg = new SpliceSprite(Paths.image(bgTheme.sprite), 0, 0, 75, 24, bgTheme.left, bgTheme.top, bgTheme.bottom, bgTheme.right);
add(bg);
var lastOption:FlxSprite = null;
var w:Float = 80;
for(k=>o in options) {
var selectSpr = new FlxSprite(bgTheme.left, bgTheme.top + (k * optionTheme.height));
selectSpr.loadGraphic(Paths.image(optionTheme.sprite));
selectSpr.setGraphicSize(10, Std.int(optionTheme.height));
selectSpr.visible = false;
selectionBGs.push(selectSpr);
add(selectSpr);
var text = new WindowText(4, 4, 0, o.name);
text.y = selectSpr.y + ((selectSpr.height - text.height) / 2);
text.applyFontSettings(bgTheme);
texts.push(text);
add(text);
if (w < text.width)
w = text.width;
lastOption = selectSpr;
}
var ow = Std.int(w) + 20;
for(o in selectionBGs) {
o.setGraphicSize(ow, Std.int(optionTheme.height));
o.updateHitbox();
}
bg.resize(bgTheme.left + ow + bgTheme.right, lastOption.y + lastOption.height + bgTheme.bottom);
contextCamera = camera = new FlxCamera(Std.int(x), Std.int(y), Std.int(bg.width), Std.int(bg.height));
contextCamera.pixelPerfectRender = true;
contextCamera.bgColor = 0;
FlxG.cameras.add(contextCamera, false);
}
public static function open(x:Float, y:Float, options:Array<ContextOption>, callback:Int->Void) {
DesktopMain.contextMenu = new ContextMenu(x, y, options, callback);
}
public override function update(elapsed:Float) {
super.update(elapsed);
if (DesktopMain.mouseInput.overlaps(bg, contextCamera)) {
for(i=>o in selectionBGs) {
var wasVisible = o.visible;
if (o.visible = DesktopMain.mouseInput.overlaps(o, contextCamera)) {
if (DesktopMain.mouseInput.justReleased) {
// select option
if (contextOptions[i].callback != null)
contextOptions[i].callback();
if (callback != null)
callback(i);
destroy();
return;
}
}
if (o.visible != wasVisible) {
texts[i].applyFontSettings(o.visible ? DesktopMain.theme.contextOption : DesktopMain.theme.contextBackground);
}
}
DesktopMain.mouseInput.cancel();
} else {
if (DesktopMain.mouseInput.justPressed) {
destroy();
return;
}
}
}
public override function destroy() {
FlxG.cameras.remove(contextCamera, true);
DesktopMain.contextMenu = null;
super.destroy();
}
}
typedef ContextOption = {
var name:String;
@:optional var callback:Void->Void;
@:optional var iconPath:String;
@:optional var iconId:Int;
}
-297
View File
@@ -1,297 +0,0 @@
package funkin.desktop.windows;
import flixel.math.FlxRect;
import flixel.addons.ui.FlxUIText;
import openfl.geom.Point;
import flixel.group.FlxSpriteGroup;
import openfl.geom.Rectangle;
import flixel.addons.ui.FlxUI9SliceSprite;
import flixel.tweens.FlxTween;
import funkin.desktop.sprites.*;
import funkin.desktop.editors.MessageBox.MessageBoxIcon;
import funkin.desktop.editors.MessageBox;
typedef WindowCam = {
var camera:FlxCamera;
var resizeScroll:Bool;
var width:Int;
var height:Int;
}
class Window extends FlxTypedGroup<FlxBasic> {
public var windowFrame:SpliceSprite;
public var windowInactiveFrame:SpliceSprite;
public var captionButtons:FlxTypedSpriteGroup<WindowCaptionButton>;
public var windowWidth:Int = 0;
public var windowHeight:Int = 0;
public var windowCaptionCamera:FlxCamera;
public var windowCameras:Array<WindowCam> = [];
private var __captionTweens:Array<FlxTween> = [];
private var __closing:Bool = false;
public var content:WindowContent;
public var caption:WindowText;
public var icon:FlxSprite;
public var dragHitbox:WindowDragHitbox;
public var moveable:Bool = true;
public var resizeable:Bool = true;
public var canClose:Bool = true;
public var canMinimize:Bool = true;
public var canHelp:Bool = false;
public var maximized:Bool = false;
public var focused(get, null):Bool;
public var curDialog:Window = null;
public function openDialog(window:Window) {
curDialog = window;
if (focused) DesktopMain.instance.focusWindow(curDialog);
}
private function get_focused() {
return DesktopMain.instance.windows.members.last() == this;
}
public function showMessage(caption:String, message:String, icon:MessageBoxIcon) {
var win = DesktopMain.instance.openWindow(new MessageBox(caption, message, icon));
curDialog = win;
win.move(
windowCaptionCamera.x + ((windowCaptionCamera.width - win.windowCaptionCamera.width) / 2),
windowCaptionCamera.y + ((windowCaptionCamera.height - win.windowCaptionCamera.height) / 2));
}
public function loadIcon(path:String) {
icon.loadGraphic(path);
icon.setUnstretchedGraphicSize(16, 16, false);
}
public function new(content:WindowContent) {
super();
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);
caption = new WindowText(24, 4, 0, content.title);
caption.applyFontSettings(DesktopMain.theme.captionActive);
caption.borderSize = 1.25;
caption.borderStyle = OUTLINE;
caption.borderColor = 0x63000000;
captionButtons = new FlxTypedSpriteGroup<WindowCaptionButton>();
for(i in 0...4) {
var btn = new WindowCaptionButton(this, i);
btn.x = (i+1) * -(DesktopMain.theme.captionButtons.size.x + DesktopMain.theme.captionButtons.margin.x);
captionButtons.add(btn);
}
caption.y = (DesktopMain.theme.captionActive.top - caption.height) / 2;
add(caption);
dragHitbox = new WindowDragHitbox(DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.left, DesktopMain.theme.captionActive.top);
dragHitbox.parent = this;
add(dragHitbox);
icon = new FlxSprite(4, (DesktopMain.theme.captionActive.top - 16) / 2);
add(icon);
loadIcon(content.icon);
add(captionButtons);
this.content = content;
// scrollFactor.set(0.5, 0.5);
windowCaptionCamera = new FlxCamera(0, 0, content.width, content.height, 1);
windowCaptionCamera.pixelPerfectRender = true;
windowCaptionCamera.bgColor = 0;
FlxG.cameras.add(windowCaptionCamera, false);
cameras = [windowCaptionCamera];
dragHitbox.cameras = [windowCaptionCamera];
for(btn in captionButtons.members)
btn.cameras = cameras; // so that buttons detects on the right camera
if (content.windowCamera == null) {
content.windowCamera = new FlxCamera(Std.int(content.winX + 4), Std.int(content.winY + 23), Std.int(content.width), Std.int(content.height), 1);
content.windowCamera.pixelPerfectRender = true;
content.windowCamera.bgColor = DesktopMain.theme.window.color;
}
content.cameras = [content.windowCamera];
content.parent = this;
addCamera(content.windowCamera);
content.create();
add(content);
windowWidth = content.width;
windowHeight = content.height;
popupCamera(windowCaptionCamera);
for(e in windowCameras) popupCamera(e.camera);
resize(content.width, content.height);
move(content.winX, content.winY);
}
public function addCamera(camera:FlxCamera, useResizeTechnique:Bool = true) {
FlxG.cameras.add(camera, false);
windowCameras.push({
camera: camera,
resizeScroll: useResizeTechnique,
width: camera.width,
height: camera.height
});
}
public function onDesktopSizeChange(width:Int, height:Int) {
if (maximized) {
resize(width, Std.int(height - DesktopMain.theme.captionActive.top + DesktopMain.theme.captionActive.left));
}
content.onDesktopSizeChange(width, height);
}
public function maximize() {
if (maximized != (maximized = true)) {
// maximizing!!
captionButtons.members[1].animation.play("restore", true);
move(-DesktopMain.theme.captionActive.left, -DesktopMain.theme.captionActive.left);
resize(FlxG.width, Std.int(FlxG.height - DesktopMain.theme.captionActive.top + DesktopMain.theme.captionActive.left)); // TODO: taskbar stuff
}
}
public function minimize() {
}
public function restore() {
if (maximized != (maximized = false)) {
// maximizing!!
captionButtons.members[1].animation.play("maximize", true);
move(100, 100);
var w:Int = 320;
var h:Int = 320;
if (windowCameras[0] != null) {
w = windowCameras[0].width;
h = windowCameras[0].height;
}
resize(w, h); // TODO: taskbar stuff
}
}
public function changeCaption(text:String) {
caption.text = text;
}
public function popupCamera(cam:FlxCamera, popout:Bool = false, ?onFinish:FlxTween->Void) {
if (popout) {
__captionTweens.push(FlxTween.tween(cam.flashSprite, {scaleX: 0.85, scaleY: 0.85}, 1/5, {ease: FlxEase.quintOut}));
__captionTweens.push(FlxTween.tween(cam, {alpha: 0}, 1/5, {ease: FlxEase.quintOut, onComplete: onFinish}));
} else {
cam.flashSprite.scaleX = 0.85;
cam.flashSprite.scaleY = 0.85;
cam.alpha = 0;
__captionTweens.push(FlxTween.tween(cam.flashSprite, {scaleX: 1, scaleY: 1}, 1/3, {ease: FlxEase.cubeOut}));
__captionTweens.push(FlxTween.tween(cam, {alpha: 1}, 1/3, {ease: FlxEase.cubeOut, onComplete: onFinish}));
}
}
public override function destroy() {
super.destroy();
for(e in __captionTweens) e.cancel();
FlxG.cameras.remove(windowCaptionCamera, true);
for(cam in windowCameras) {
FlxG.cameras.remove(cam.camera, true);
}
windowCameras = null;
windowCaptionCamera = null;
__captionTweens = null;
}
public function resize(width:Int, height:Int) {
windowWidth = width;
windowHeight = height;
updateWindowFrame();
}
public function move(x:Float, y:Float) {
@:privateAccess content.__noParentUpdate = true;
content.winX = windowCaptionCamera.x = x;
content.winY = windowCaptionCamera.y = y;
@:privateAccess content.__noParentUpdate = false;
for(e in windowCameras) {
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;
}
windowInactiveFrame.visible = !(windowFrame.visible = focused);
var i = members.length;
var shouldCancel = DesktopMain.mouseInput.overlapsRect(this, new FlxRect(0, 0, windowCaptionCamera.width, windowCaptionCamera.height), windowCaptionCamera);
if (curDialog != null && curDialog.exists) {
if (shouldCancel) {
if (DesktopMain.mouseInput.justPressed) {
// TODO: sounds
DesktopMain.instance.focusWindow(curDialog);
}
DesktopMain.mouseInput.cancel();
}
return;
} else if (shouldCancel && DesktopMain.mouseInput.justPressed)
DesktopMain.instance.focusWindow(this);
// updates them backwards!!
while(i > 0) {
i--;
var spr = members[i];
if (spr == null || !spr.exists) continue;
spr.update(elapsed);
}
if (shouldCancel) DesktopMain.mouseInput.cancel();
}
public function close() {
__closing = true;
popupCamera(windowCaptionCamera, true, function(t) {
DesktopMain.instance.windows.remove(this, true);
destroy();
});
for(e in windowCameras) popupCamera(e.camera, true);
}
public function updateWindowFrame() {
for(frame in [windowInactiveFrame, windowFrame])
frame.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) {
e.camera.scroll.set(-Std.int(e.camera.width - e.width), -Std.int(e.camera.height - e.height));
}
}
content.onWindowResize(windowWidth, windowHeight);
}
}
@@ -1,75 +0,0 @@
package funkin.desktop.windows;
class WindowCaptionButton extends FlxSprite {
public var icon:FlxSprite;
public var window:Window;
public static var anims:Array<String> = ["close", "maximize", "minimize", "help", "restore"];
public function new(window:Window, i:Int) {
super(0, 0);
this.window = window;
ID = i;
loadGraphic(Paths.image(DesktopMain.theme.captionButtons.sprite), true, Std.int(DesktopMain.theme.captionButtons.size.x), Std.int(DesktopMain.theme.captionButtons.size.y));
for(k=>e in anims) {
animation.add(e, [for(l in 0...8) k + (l * anims.length)], 0, true);
}
animation.play(anims[ID]);
}
public override function draw() {
super.draw();
}
public override function update(elapsed:Float) {
if (animation.curAnim == null) {
super.update(elapsed);
return;
}
var mouseInput = DesktopMain.mouseInput;
visible = switch(ID) {
case 1 | 2: window.resizeable || window.canMinimize;
case 3: window.canHelp;
default: true;
};
if(switch(ID) {
case 0: window.canClose;
case 1: window.resizeable;
case 2: window.canMinimize;
case 3: window.canHelp;
default: true;
}) {
if (DesktopMain.mouseInput.overlaps(this, camera)) {
if (mouseInput.justReleased) {
switch(ID) {
case 0:
if (window.canClose) window.close();
case 1:
if (window.resizeable) (window.maximized ? window.restore : window.maximize)();
case 2:
if (window.canMinimize) window.minimize();
}
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;
} else {
animation.curAnim.curFrame = 3;
}
if (!window.focused) animation.curAnim.curFrame += 4;
super.update(elapsed);
}
}
@@ -1,87 +0,0 @@
package funkin.desktop.windows;
class WindowContent extends WindowGroup<FlxBasic> {
public var winX(default, set):Float = 0;
public var winY(default, set):Float = 0;
public var title(default, set):String = "Window";
public var icon(default, set):String = 'flixel/images/logo/default.png';
public var windowCamera:FlxCamera = null;
public var parent:Window = null;
public var width(default, set):Int = 0;
public var height(default, set):Int = 0;
private var __noParentUpdate:Bool = false;
private function set_width(w:Int):Int {
width = w;
if (parent != null && !__noParentUpdate) {
parent.windowWidth = w;
if (!__noParentUpdate)
parent.updateWindowFrame();
}
return width;
}
private function set_height(h:Int):Int {
height = h;
if (parent != null && !__noParentUpdate) {
parent.windowHeight = h;
if (!__noParentUpdate)
parent.updateWindowFrame();
}
return height;
}
private function set_winX(v:Float):Float {
winX = v;
if (parent != null && !__noParentUpdate) parent.move(winX, winY);
return winX;
}
private function set_title(text:String):String {
title = text;
if (parent != null && !__noParentUpdate) parent.changeCaption(title);
return title;
}
private function set_icon(text:String):String {
icon = text;
if (parent != null && !__noParentUpdate) parent.loadIcon(icon);
return icon;
}
private function set_winY(v:Float):Float {
winY = v;
if (parent != null && !__noParentUpdate) parent.move(winX, winY);
return winY;
}
public function setSize(width:Int, height:Int) {
__noParentUpdate = true;
this.width = width;
this.height = height;
__noParentUpdate = false;
if (parent != null) parent.updateWindowFrame();
}
public function new(caption:String, x:Float, y:Float, width:Int, height:Int) {
super();
this.title = caption;
this.width = width;
this.height = height;
this.winX = x;
this.winY = y;
this.updateScrolls = false;
}
public function create() {
}
public function onWindowResize(width:Int, height:Int) {
}
public function onDesktopSizeChange(width:Int, height:Int) {
}
}
@@ -1,77 +0,0 @@
package funkin.desktop.windows;
import flixel.math.FlxPoint;
class WindowDragHitbox extends FlxObject {
public var parent:Window;
public var left:Float;
public var top:Float;
public var right:Float;
public var dragging:Bool = false;
public var offset:FlxPoint;
public function new(left:Float, top:Float, right:Float, height:Float) {
super();
x = left;
y = top;
this.left = left;
this.top = top;
this.right = right;
this.height = height;
}
public override function get_width() {
return parent.windowCaptionCamera.width - left - right;
}
public override function update(elapsed:Float) {
super.update(elapsed);
if (!parent.moveable || parent.maximized) {
dragging = false;
return;
}
if (dragging) {
var screenPos = FlxG.mouse.getScreenPosition(FlxG.camera);
screenPos.x = FlxMath.bound(screenPos.x, 0, FlxG.camera.width);
screenPos.y = FlxMath.bound(screenPos.y, 0, FlxG.camera.height);
if (DesktopMain.mouseInput.justReleased) {
dragging = false;
offset.put();
return;
}
parent.move(screenPos.x + offset.x, screenPos.y + offset.y);
DesktopMain.mouseInput.cancel();
} else {
if (DesktopMain.mouseInput.overlaps(this, camera)) {
if (DesktopMain.mouseInput.justPressed) {
var screenPos = FlxG.mouse.getScreenPosition(FlxG.camera);
offset = FlxPoint.get(parent.content.winX - screenPos.x, parent.content.winY - screenPos.y);
dragging = true;
} else if (DesktopMain.mouseInput.justPressedRight) {
var input = DesktopMain.mouseInput;
ContextMenu.open(input.screenPos.x, input.screenPos.y, [
{
name: "Close",
callback: function() {
parent.close();
}
}
], function(i) {
trace(i);
});
}
DesktopMain.mouseInput.cancel();
}
}
}
override function destroy() {
super.destroy();
if (offset != null)
offset.put();
}
}
@@ -1,72 +0,0 @@
package funkin.desktop.windows;
import flixel.math.FlxPoint;
class WindowGroup<T:FlxBasic> extends FlxTypedGroup<T> {
public var x:Float = 0;
public var y:Float = 0;
public var scrollFactor:FlxPoint = FlxPoint.get(0, 0);
public var updateScrolls:Bool = true;
public override function add(obj:T) {
super.add(obj);
if (!updateScrolls) return obj;
if (obj is FlxObject) {
var o = cast(obj, FlxObject);
o.x += x;
o.y += y;
} else if (obj is WindowGroup) {
var o:WindowGroup<FlxBasic> = cast obj;
o.x += x;
o.y += y;
}
__updateObjScrollFactor(obj);
return obj;
}
public function updateAnchor(x:Float, y:Float, ?cameras:Array<FlxCamera>) {
scrollFactor.set(x, y);
if (cameras != null) this.cameras = cameras;
if (!updateScrolls) return;
for(obj in members)
__updateObjScrollFactor(obj, cameras);
}
private function __updateObjScrollFactor(obj:FlxBasic, ?cameras:Array<FlxCamera>) {
if (obj is FlxObject) {
var o = cast(obj, FlxObject);
if (cameras != null) o.cameras = cameras;
o.scrollFactor.set(scrollFactor.x, scrollFactor.y);
} else if (obj is WindowGroup) {
var o:WindowGroup<FlxBasic> = cast obj;
o.updateAnchor(scrollFactor.x, scrollFactor.y, cameras);
}
}
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];
if (window == null || !window.exists)
continue;
window.update(elapsed);
}
@:privateAccess FlxCamera._defaultCameras = oldDefaultCameras;
}
public override function destroy() {
super.destroy();
scrollFactor.put();
}
}
+5
View File
@@ -24,6 +24,11 @@ class EditorPicker extends MusicBeatSubstate {
iconID: 2,
state: null
},
{
name: "UI Debug State",
iconID: 3,
state: UIDebugState
},
{
name: "Debug Options",
iconID: 4,
+11
View File
@@ -0,0 +1,11 @@
package funkin.editors;
import funkin.editors.ui.*;
class UIDebugState extends UIState {
public override function create() {
super.create();
add(new UICheckbox(10, 10, "Test unchecked", false));
add(new UICheckbox(10, 40, "Test checked", true));
}
}
+5
View File
@@ -0,0 +1,5 @@
package funkin.editors.charter;
class Charter extends MusicBeatState {
}
+74
View File
@@ -0,0 +1,74 @@
package funkin.editors.ui;
import funkin.ui.FunkinText;
class UICheckbox extends UISprite {
public var field:FunkinText;
public var check:FlxSprite;
public var checked:Bool = false;
var hovered:Bool = false;
var pressed:Bool = false;
public function new(x:Float, y:Float, text:String, checked:Bool = false, w:Int = 0) {
super(x, y);
loadGraphic(Paths.image('editors/ui/checkbox'), true, 20, 20);
for(frame=>name in ["normal", "hover", "pressed", "checkmark"])
animation.add(name, [frame], 0, false);
this.checked = checked;
field = new FunkinText(x, y, text, w);
check = new FlxSprite().loadGraphicFromSprite(this);
check.animation.play("checkmark");
members.push(check);
members.push(field);
}
public override function update(elapsed:Float) {
// ANIMATION HANDLING
animation.play(hovered ? (pressed ? "pressed" : "hover") : "normal");
hovered = false;
pressed = false;
// CHECKMARK HANDLING
check.visible = checked;
check.scale.x = CoolUtil.fpsLerp(check.scale.x, 1, 0.25);
check.scale.y = CoolUtil.fpsLerp(check.scale.y, 1, 0.25);
// POSITION HANDLING
updatePositions();
super.update(elapsed);
}
public inline function updatePositions() {
field.setPosition(x + 30, y);
check.setPosition(x, y);
}
public override function draw() {
updatePositions();
super.draw();
}
public override function onHovered() {
hovered = true;
if (FlxG.mouse.pressed)
pressed = true;
if (FlxG.mouse.justReleased) {
// clicked
checked = !checked;
check.scale.set(1.25, 1.25);
}
}
public override function updateButton() {
__rect.x = x;
__rect.y = y;
__rect.width = field.width + 30;
__rect.height = field.height > height ? field.height : height;
UIState.state.updateRectButtonHandler(this, __rect, onHovered);
}
}
+61
View File
@@ -0,0 +1,61 @@
package funkin.editors.ui;
import flixel.util.FlxDestroyUtil;
import flixel.math.FlxRect;
@:allow(funkin.editors.ui.UIState)
class UISprite extends FlxSprite {
public var members:Array<FlxBasic> = [];
private var __lastDrawCameras:Array<FlxCamera> = [];
private var __rect:FlxRect = new FlxRect();
private var __oldDefCams:Array<FlxCamera>;
public override function update(elapsed:Float) {
super.update(elapsed);
updateButton();
@:privateAccess {
__oldDefCams = FlxCamera._defaultCameras;
FlxCamera._defaultCameras = cameras;
for(m in members)
m.update(elapsed);
FlxCamera._defaultCameras = __oldDefCams;
}
}
public override function draw() {
super.draw();
@:privateAccess {
__oldDefCams = FlxCamera._defaultCameras;
FlxCamera._defaultCameras = cameras;
for(m in members)
m.draw();
FlxCamera._defaultCameras = __oldDefCams;
}
__lastDrawCameras = [for(c in cameras) c];
}
public override function destroy() {
super.destroy();
members = FlxDestroyUtil.destroyArray(members);
}
public function updateButton() {
UIState.state.updateButtonHandler(this, onHovered);
}
/**
* Called whenever the sprite is being hovered by the mouse.
*/
public function onHovered() {
}
}
+63
View File
@@ -0,0 +1,63 @@
package funkin.editors.ui;
import flixel.math.FlxPoint;
import flixel.math.FlxRect;
class UIState extends MusicBeatState {
public static var state(get, null):UIState;
public var buttonHandler:Void->Void = null;
private var __rect:FlxRect;
private var __mousePos:FlxPoint;
private inline static function get_state()
return FlxG.state is UIState ? cast FlxG.state : null;
public override function create() {
__rect = new FlxRect();
__mousePos = FlxPoint.get();
super.create();
}
public function updateButtonHandler(spr:UISprite, buttonHandler:Void->Void) {
spr.__rect.x = spr.x;
spr.__rect.y = spr.y;
spr.__rect.width = spr.width;
spr.__rect.height = spr.height;
updateRectButtonHandler(spr, spr.__rect, buttonHandler);
}
public function updateRectButtonHandler(spr:UISprite, rect:FlxRect, buttonHandler:Void->Void) {
var pos = FlxG.mouse.getScreenPosition(camera);
for(camera in spr.__lastDrawCameras) {
__rect.x = rect.x;
__rect.y = rect.y;
__rect.width = rect.width;
__rect.height = rect.height;
__rect.x -= camera.scroll.x * spr.scrollFactor.x;
__rect.y -= camera.scroll.y * spr.scrollFactor.y;
if (((pos.x > __rect.x) && (pos.x < __rect.x + rect.width)) && ((pos.y > __rect.y) && (pos.y < __rect.y + __rect.height))) {
this.buttonHandler = buttonHandler;
return;
}
}
}
public override function update(elapsed:Float) {
super.update(elapsed);
if (buttonHandler != null) {
buttonHandler();
buttonHandler = null;
}
}
public override function destroy() {
super.destroy();
__mousePos.put();
}
}
-2
View File
@@ -1,6 +1,5 @@
package funkin.system;
import funkin.desktop.DesktopMain;
import openfl.utils.AssetLibrary;
import openfl.utils.AssetCache;
import openfl.text.TextFormat;
@@ -156,7 +155,6 @@ class Main extends Sprite
Logs.init();
Paths.init();
ModsFolder.init();
DesktopMain.init();
DiscordUtil.init();
#if GLOBAL_SCRIPT
funkin.scripting.GlobalScript.init();