Keyboard/gamepad control selection in SimpleWindow

This commit is contained in:
2023-07-06 12:11:14 -06:00
parent a235ab6fdf
commit 33975bfb88
3 changed files with 77 additions and 25 deletions

View File

@@ -20,7 +20,7 @@
(never otherwise)))) (never otherwise))))
(method subMenu [] (method subMenu []
(let [window (new SimpleWindow "SubMenu")] (let [window (new SimpleWindow "SubMenu" null null null null "escape" "left" "right" "up" "down" "enter")]
(doFor letter ["A" "B" "C"] (doFor letter ["A" "B" "C"]
(window.makeText letter null (window.makeText letter null
->_ (print "$letter clicked") ->_ (print "$letter clicked")

View File

@@ -15,6 +15,7 @@ import flixel.input.actions.FlxAction;
import flixel.input.actions.FlxActionInput; import flixel.input.actions.FlxActionInput;
import flixel.input.FlxInput; import flixel.input.FlxInput;
import flixel.input.gamepad.FlxGamepadInputID; import flixel.input.gamepad.FlxGamepadInputID;
import flixel.input.mouse.FlxMouseEvent;
typedef ShortcutAction = Void->Void; typedef ShortcutAction = Void->Void;
typedef Action = FlxSprite->Void; typedef Action = FlxSprite->Void;

View File

@@ -42,6 +42,26 @@
(otherwise)) (otherwise))
value)) value))
(method selectDown []
(let [columnControls (getColumnControls)
&mut nextIndex _selectedIndex]
(loop
(set nextIndex (% (+ 1 nextIndex) columnControls.length))
(when (or (dictGet _actions (nth columnControls nextIndex)) (Std.isOfType (nth columnControls nextIndex) KissInputText))
(set selectedIndex nextIndex)
(return)))))
(method selectUp []
(let [columnControls (getColumnControls)
&mut nextIndex _selectedIndex]
(loop
(-= nextIndex 1)
(when (< nextIndex 0)
(set nextIndex (- columnControls.length 1)))
(when (or (dictGet _actions (nth columnControls nextIndex)) (Std.isOfType (nth columnControls nextIndex) KissInputText))
(set selectedIndex nextIndex)
(return)))))
(defNew [&opt :String _title (defNew [&opt :String _title
:FlxColor bgColor :FlxColor bgColor
:FlxColor _textColor :FlxColor _textColor
@@ -109,15 +129,33 @@
(a) (a)
(keyHandler.start) (keyHandler.start)
}) })
(FlxMouseEvent.globalManager.add this)
(FlxMouseEvent.globalManager.setMouseMoveCallback this ->_
(set mouseMode true))
(prop &mut :Bool justPressedUIButton false)
(set xHandler.cancelKey null) (set xHandler.cancelKey null)
(set xHandler.onBadKey ->:Void [key context] 0) (set xHandler.onBadKey ->:Void [key context] 0)
(set xHandler.onSelectItem (set xHandler.onSelectItem
->:Void [:ShortcutAction a] { ->:Void [:ShortcutAction a] {
(set justPressedUIButton true)
(a) (a)
(xHandler.start) (xHandler.start)
}) })
(when upKey
(xHandler.registerItem "{${upKey}}" selectUp true))
(when downKey
(xHandler.registerItem "{${downKey}}" selectDown true))
(when enterKey
(xHandler.registerItem "{${enterKey}}"
->:Void
(unless (= -1 _selectedIndex)
(let [selectedControl (nth (getColumnControls) _selectedIndex)]
((dictGet _actions selectedControl) selectedControl))) true))
(defAndCall method makeXControls (defAndCall method makeXControls
(let [closeAction ->:Void {(hide)(when onClose (onClose))}] (let [closeAction ->:Void {(hide)(when onClose (onClose))}]
(when xButton (when xButton
@@ -177,7 +215,7 @@
control) control)
(prop &mut :Bool _useScrolling false) (prop &mut :Bool _useScrolling false)
(method enableVerticalScrolling [&opt :String upKey :String downKey] (method enableVerticalScrolling []
(set _useScrolling true) (set _useScrolling true)
// add scroll up/scroll down buttons // add scroll up/scroll down buttons
(assert xText) (assert xText)
@@ -400,10 +438,14 @@
(true (true
(color.getLightened amount)))) (color.getLightened amount))))
(prop &mut :Bool mouseMode true)
(prop &mut otherIsSelected false) (prop &mut otherIsSelected false)
(method &override update [:Float elapsed] (method &override update [:Float elapsed]
(super.update elapsed) (super.update elapsed)
(set justPressedUIButton false)
(set otherIsSelected false) (set otherIsSelected false)
(localVar columnControls (getColumnControls))
(when (= (last windowStack) this) (when (= (last windowStack) this)
(when keyboardEnabled (when keyboardEnabled
(unless (apply or (for textBox inputTexts.members textBox.hasFocus)) (unless (apply or (for textBox inputTexts.members textBox.hasFocus))
@@ -415,29 +457,34 @@
// TODO move all controls other than xButton and scrollbar. Clamp movement by top and bottom of all controls // TODO move all controls other than xButton and scrollbar. Clamp movement by top and bottom of all controls
null) null)
// Figure out whether to use mouse input or key/gamepad input for ui navigation
(when justPressedUIButton
(set mouseMode false))
// Handle mouse input // Handle mouse input
(let [mousePos (FlxG.mouse.getScreenPosition controlCamera)] (when mouseMode
// Click and hover on clickable text entries (let [mousePos (FlxG.mouse.getScreenPosition controlCamera)]
(controls.forEach ->text // Click and hover on clickable text entries
(whenLet [onClick (dictGet _actions text)] (controls.forEach ->text
(let [color (dictGet _colors text)] (whenLet [onClick (dictGet _actions text)]
(when (and !otherIsSelected (.containsPoint (text.getScreenBounds controlCamera) mousePos)) (let [color (dictGet _colors text)]
(when FlxG.mouse.justPressed (when (and !otherIsSelected (.containsPoint (text.getScreenBounds controlCamera) mousePos))
(onClick text)) (when FlxG.mouse.justPressed
(set otherIsSelected true) (onClick text))
(set selectedIndex (columnControls.indexOf text)))))) (set otherIsSelected true)
// Click on text boxes to focus them (set selectedIndex (columnControls.indexOf text))))))
(inputTexts.forEach ->text // Click on text boxes to focus them
(when FlxG.mouse.justPressed (inputTexts.forEach ->text
(when (.containsPoint (text.getScreenBounds controlCamera) mousePos) (when FlxG.mouse.justPressed
(set otherIsSelected true) (when (.containsPoint (text.getScreenBounds controlCamera) mousePos)
(set text.caretIndex (text.getCaretIndex controlCamera)) (set otherIsSelected true)
(set selectedIndex (columnControls.indexOf text))))) (set text.caretIndex (text.getCaretIndex controlCamera))
(unless otherIsSelected (set selectedIndex (columnControls.indexOf text)))))
(set selectedIndex -1) (unless otherIsSelected
// Click anywhere else to take focus away from text boxes (set selectedIndex -1)
(when FlxG.mouse.justPressed // Click anywhere else to take focus away from text boxes
(inputTexts.forEach ->text (set text.hasFocus false))))))) (when FlxG.mouse.justPressed
(inputTexts.forEach ->text (set text.hasFocus false))))))))
(function :SimpleWindow promptForChoice <>[T] [:String prompt (function :SimpleWindow promptForChoice <>[T] [:String prompt
:Array<T> choices :Array<T> choices
@@ -535,7 +582,11 @@
(method clearActions [] (method clearActions []
(_actions.clear)) (_actions.clear))
(prop &mut :Null<Int> gamepadId null)
(method enableGamepadInput [:Bool addDefaultUIInputs &opt :Map<FlxGamepadInputID,String> uiKeyMappings :Map<FlxGamepadInputID,String> otherKeyMappings :Int gamepadId] (method enableGamepadInput [:Bool addDefaultUIInputs &opt :Map<FlxGamepadInputID,String> uiKeyMappings :Map<FlxGamepadInputID,String> otherKeyMappings :Int gamepadId]
(unless gamepadId (set gamepadId FlxInputDeviceID.ALL))
(set this.gamepadId gamepadId)
(unless uiKeyMappings (set uiKeyMappings (new Map))) (unless uiKeyMappings (set uiKeyMappings (new Map)))
(localVar DEFAULT_UI_INPUTS [ (localVar DEFAULT_UI_INPUTS [
=>xKey [B] =>xKey [B]