diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 0dd271cc..222409e9 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import flixel.input.keyboard.FlxKey; import flixel.system.FlxSound; import flixel.util.FlxSort; import flixel.math.FlxPoint; @@ -100,7 +101,7 @@ class Charter extends UIState { }, { label: "Redo", - keybind: [CONTROL, Y], + keybinds: [[CONTROL, Y], [CONTROL, SHIFT, Z]], onSelect: _edit_redo }, null, diff --git a/source/funkin/editors/ui/UIContextMenu.hx b/source/funkin/editors/ui/UIContextMenu.hx index 7fbd53e7..0ac09dc1 100644 --- a/source/funkin/editors/ui/UIContextMenu.hx +++ b/source/funkin/editors/ui/UIContextMenu.hx @@ -3,74 +3,74 @@ package funkin.editors.ui; import flixel.input.keyboard.FlxKey; class UIContextMenu extends MusicBeatSubstate { - public var options:Array; - var x:Float; - var y:Float; - var contextCam:FlxCamera; + public var options:Array; + var x:Float; + var y:Float; + var contextCam:FlxCamera; - var bg:UISliceSprite; - var callback:UIContextMenuCallback; + var bg:UISliceSprite; + var callback:UIContextMenuCallback; - public var contextMenuOptions:Array = []; - public var separators:Array = []; + public var contextMenuOptions:Array = []; + public var separators:Array = []; - private var __oobDeletion:Bool = true; + private var __oobDeletion:Bool = true; - public inline function preventOutOfBoxClickDeletion() { - __oobDeletion = false; - } + public inline function preventOutOfBoxClickDeletion() { + __oobDeletion = false; + } - public function new(options:Array, callback:UIContextMenuCallback, x:Float, y:Float) { - super(); - this.options = options.getDefault([]); - this.x = x; - this.y = y; - this.callback = callback; - } + public function new(options:Array, callback:UIContextMenuCallback, x:Float, y:Float) { + super(); + this.options = options.getDefault([]); + this.x = x; + this.y = y; + this.callback = callback; + } - public override function create() { - super.create(); - camera = contextCam = new FlxCamera(); - contextCam.bgColor = 0; - contextCam.alpha = 0; - contextCam.scroll.set(0, 7.5); - FlxG.cameras.add(contextCam, false); + public override function create() { + super.create(); + camera = contextCam = new FlxCamera(); + contextCam.bgColor = 0; + contextCam.alpha = 0; + contextCam.scroll.set(0, 7.5); + FlxG.cameras.add(contextCam, false); - bg = new UISliceSprite(x, y, 100, 100, 'editors/ui/context-bg'); + bg = new UISliceSprite(x, y, 100, 100, 'editors/ui/context-bg'); bg.cameras = [contextCam]; - add(bg); + add(bg); - var lastY:Float = bg.y + 4; - for(o in options) { - if (o == null) { - var spr = new FlxSprite(bg.x + 8, lastY + 2).makeGraphic(1, 1, -1); - spr.alpha = 0.3; - separators.push(spr); - add(spr); - lastY += 5; - continue; - } - var spr = new UIContextMenuOptionSpr(bg.x + 4, lastY, o, this); + var lastY:Float = bg.y + 4; + for(o in options) { + if (o == null) { + var spr = new FlxSprite(bg.x + 8, lastY + 2).makeGraphic(1, 1, -1); + spr.alpha = 0.3; + separators.push(spr); + add(spr); + lastY += 5; + continue; + } + var spr = new UIContextMenuOptionSpr(bg.x + 4, lastY, o, this); spr.cameras = [contextCam]; - lastY = spr.y + spr.bHeight; - contextMenuOptions.push(spr); - add(spr); - } + lastY = spr.y + spr.bHeight; + contextMenuOptions.push(spr); + add(spr); + } - var maxW = bg.bWidth - 8; - for(o in contextMenuOptions) - if (o.bWidth > maxW) - maxW = o.bWidth; + var maxW = bg.bWidth - 8; + for(o in contextMenuOptions) + if (o.bWidth > maxW) + maxW = o.bWidth; - - for(o in contextMenuOptions) - o.bWidth = maxW; - for(o in separators) { - o.scale.set(maxW - 8, 1); - o.updateHitbox(); - } - bg.bWidth = maxW + 8; - bg.bHeight = Std.int(lastY - bg.y + 4); + + for(o in contextMenuOptions) + o.bWidth = maxW; + for(o in separators) { + o.scale.set(maxW - 8, 1); + o.updateHitbox(); + } + bg.bWidth = maxW + 8; + bg.bHeight = Std.int(lastY - bg.y + 4); if (bg.y + bg.bHeight > FlxG.height) { bg.y -= bg.bHeight; @@ -79,58 +79,59 @@ class UIContextMenu extends MusicBeatSubstate { for(o in separators) o.y -= bg.bHeight; } - } + } - public function select(option:UIContextMenuOption) { - var index = options.indexOf(option); - if (option.onSelect != null) - option.onSelect(option); - if (callback != null) - callback(this, index, option); - close(); - } + public function select(option:UIContextMenuOption) { + var index = options.indexOf(option); + if (option.onSelect != null) + option.onSelect(option); + if (callback != null) + callback(this, index, option); + close(); + } - public override function update(elapsed:Float) { - if (__oobDeletion && FlxG.mouse.pressed && !bg.hoveredByChild) - close(); + public override function update(elapsed:Float) { + if (__oobDeletion && FlxG.mouse.pressed && !bg.hoveredByChild) + close(); - __oobDeletion = true; + __oobDeletion = true; - super.update(elapsed); + super.update(elapsed); - contextCam.scroll.y = CoolUtil.fpsLerp(contextCam.scroll.y, 0, 0.5); - contextCam.alpha = CoolUtil.fpsLerp(contextCam.alpha, 1, 0.25); - } + contextCam.scroll.y = CoolUtil.fpsLerp(contextCam.scroll.y, 0, 0.5); + contextCam.alpha = CoolUtil.fpsLerp(contextCam.alpha, 1, 0.25); + } - public override function destroy() { - super.destroy(); - FlxG.cameras.remove(contextCam); - if (UIState.state.curContextMenu == this) - UIState.state.curContextMenu = null; - } + public override function destroy() { + super.destroy(); + FlxG.cameras.remove(contextCam); + if (UIState.state.curContextMenu == this) + UIState.state.curContextMenu = null; + } } typedef UIContextMenuCallback = UIContextMenu->Int->UIContextMenuOption->Void; typedef UIContextMenuOption = { - var label:String; - var ?keybind:Array; - var ?icon:Int; - var ?onSelect:UIContextMenuOption->Void; - var ?childs:Array; + var label:String; + var ?keybind:Array; + var ?keybinds:Array>; + var ?icon:Int; + var ?onSelect:UIContextMenuOption->Void; + var ?childs:Array; } class UIContextMenuOptionSpr extends UISliceSprite { - public var label:UIText; - public var labelKeybind:UIText; + public var label:UIText; + public var labelKeybind:UIText; public var icon:FlxSprite; - public var option:UIContextMenuOption; + public var option:UIContextMenuOption; - var parent:UIContextMenu; + var parent:UIContextMenu; - public function new(x:Float, y:Float, option:UIContextMenuOption, parent:UIContextMenu) { - label = new UIText(20, 2, 0, option.label); - this.option = option; - this.parent = parent; + public function new(x:Float, y:Float, option:UIContextMenuOption, parent:UIContextMenu) { + label = new UIText(20, 2, 0, option.label); + this.option = option; + this.parent = parent; if (option.icon != null && option.icon > 0) { icon = new FlxSprite(0, 0).loadGraphic(Paths.image('editors/ui/context-icons'), true, 20, 20); @@ -138,34 +139,45 @@ class UIContextMenuOptionSpr extends UISliceSprite { icon.animation.play('icon'); } - if (option.keybind != null) { - var text = ""; - text += [for(o in option.keybind) o.toUIString()].join("+"); + if (option.keybinds == null) { + if (option.keybind != null) { + option.keybinds = [option.keybind]; + } + } + + if (option.keybinds != null) { + var textKeys:Array = []; + for (o in option.keybinds[0]) { + if (Std.int(o) > 0) { + textKeys.push(o.toUIString()); + } + } + var text = textKeys.join("+"); labelKeybind = new UIText(label.x + label.frameWidth + 10, 2, 0, text); labelKeybind.alpha = 0.75; } - super(x, y, labelKeybind != null ? Std.int(labelKeybind.x + labelKeybind.frameWidth + 10) : (label.frameWidth + 22), label.frameHeight, 'editors/ui/menu-item'); - members.push(label); - if (icon != null) + super(x, y, labelKeybind != null ? Std.int(labelKeybind.x + labelKeybind.frameWidth + 10) : (label.frameWidth + 22), label.frameHeight, 'editors/ui/menu-item'); + members.push(label); + if (icon != null) members.push(icon); - if (labelKeybind != null) + if (labelKeybind != null) members.push(labelKeybind); - } + } - public override function draw() { - alpha = hovered ? 1 : 0; - label.follow(this, 20, 2); + public override function draw() { + alpha = hovered ? 1 : 0; + label.follow(this, 20, 2); if (icon != null) icon.follow(this, 0, 0); if (labelKeybind != null) labelKeybind.follow(this, bWidth - 10 - labelKeybind.frameWidth, 2); - super.draw(); - } + super.draw(); + } - public override function onHovered() { - super.onHovered(); - if (FlxG.mouse.justReleased) - parent.select(option); - } + public override function onHovered() { + super.onHovered(); + if (FlxG.mouse.justReleased) + parent.select(option); + } } \ No newline at end of file diff --git a/source/funkin/editors/ui/UIUtil.hx b/source/funkin/editors/ui/UIUtil.hx index 346c0b2b..021830ef 100644 --- a/source/funkin/editors/ui/UIUtil.hx +++ b/source/funkin/editors/ui/UIUtil.hx @@ -16,37 +16,51 @@ class UIUtil { /** * Process all options with shortcuts present in a `Array`. Also checks childrens. - * @param topMenuOptions + * @param topMenuOptions */ public static function processShortcuts(topMenuOptions:Array) { for(o in topMenuOptions) { if (o == null) continue; - if (o.keybind != null) { - var pressed = true; - var justPressed = false; - for(keybind in o.keybind) { - var k = switch(keybind) { - #if mac - case CONTROL: - WINDOWS; - #end - default: - keybind; - } - if (FlxG.keys.checkStatus(k, JUST_PRESSED)) { - justPressed = true; - } else if (!FlxG.keys.checkStatus(k, PRESSED)) { - pressed = false; - break; - } + if (o.keybinds == null) { + if (o.keybind != null) { + o.keybinds = [o.keybind]; } - if (!pressed || !justPressed) continue; + } - if (o.onSelect != null) - o.onSelect(o); + if (o.keybinds != null) { + for (keybind in o.keybinds) { + var pressed = true; + var justPressed = false; + var needsShift = keybind.contains(SHIFT); - return true; + for (key in keybind) { + var shouldPress = Std.int(key) > 0; + if(!shouldPress) key = -key; + + var k = switch(key) { + #if mac + case CONTROL: + WINDOWS; + #end + default: + key; + } + if (FlxG.keys.checkStatus(k, shouldPress ? JUST_PRESSED : JUST_RELEASED)) { + justPressed = true; + } else if (!FlxG.keys.checkStatus(k, shouldPress ? PRESSED : RELEASED)) { + pressed = false; + break; + } + } + if (!needsShift && FlxG.keys.pressed.SHIFT) continue; + if (!pressed || !justPressed) continue; + + if (o.onSelect != null) + o.onSelect(o); + + return true; + } } if (o.childs != null && processShortcuts(o.childs))