Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New text input object #3191

Closed
wants to merge 14 commits into from
3 changes: 2 additions & 1 deletion checkstyle.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"STATIC",
"MACRO",
"INLINE",
"DYNAMIC"
"DYNAMIC",
"FINAL"
Starmapo marked this conversation as resolved.
Show resolved Hide resolved
]
}
},
Expand Down
13 changes: 8 additions & 5 deletions flixel/FlxG.hx
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package flixel;

import openfl.Lib;
import openfl.display.DisplayObject;
import openfl.display.Stage;
import openfl.display.StageDisplayState;
import openfl.net.URLRequest;
import flixel.effects.postprocess.PostProcess;
import flixel.math.FlxMath;
import flixel.math.FlxRandom;
Expand All @@ -17,6 +12,7 @@ import flixel.system.frontEnds.CameraFrontEnd;
import flixel.system.frontEnds.ConsoleFrontEnd;
import flixel.system.frontEnds.DebuggerFrontEnd;
import flixel.system.frontEnds.InputFrontEnd;
import flixel.system.frontEnds.InputTextFrontEnd;
import flixel.system.frontEnds.LogFrontEnd;
import flixel.system.frontEnds.PluginFrontEnd;
import flixel.system.frontEnds.SignalFrontEnd;
Expand All @@ -28,6 +24,11 @@ import flixel.system.scaleModes.RatioScaleMode;
import flixel.util.FlxCollision;
import flixel.util.FlxSave;
import flixel.util.typeLimit.NextState;
import openfl.Lib;
import openfl.display.DisplayObject;
import openfl.display.Stage;
import openfl.display.StageDisplayState;
import openfl.net.URLRequest;
#if FLX_TOUCH
import flixel.input.touch.FlxTouchManager;
#end
Expand Down Expand Up @@ -320,6 +321,8 @@ class FlxG
*/
public static var plugins(default, null):PluginFrontEnd;

public static var inputText(default, null):InputTextFrontEnd = new InputTextFrontEnd();

public static var initialWidth(default, null):Int = 0;
public static var initialHeight(default, null):Int = 0;

Expand Down
204 changes: 204 additions & 0 deletions flixel/system/frontEnds/InputTextFrontEnd.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package flixel.system.frontEnds;

import lime.ui.KeyCode;
import lime.ui.KeyModifier;

class InputTextFrontEnd
{
public var focus(default, set):Null<IFlxInputText>;

var _registeredInputTexts:Array<IFlxInputText> = [];

public function new() {}

public function registerInputText(input:IFlxInputText)
{
if (!_registeredInputTexts.contains(input))
{
_registeredInputTexts.push(input);

if (!FlxG.stage.window.onTextInput.has(onTextInput))
{
FlxG.stage.window.onTextInput.add(onTextInput);
// Higher priority is needed here because FlxKeyboard will cancel
// the event for key codes in `preventDefaultKeys`.
FlxG.stage.window.onKeyDown.add(onKeyDown, false, 1000);
}
}
}

public function unregisterInputText(input:IFlxInputText)
{
if (_registeredInputTexts.contains(input))
{
_registeredInputTexts.remove(input);

if (_registeredInputTexts.length == 0 && FlxG.stage.window.onTextInput.has(onTextInput))
{
FlxG.stage.window.onTextInput.remove(onTextInput);
FlxG.stage.window.onKeyDown.remove(onKeyDown);
}
}
}

function onTextInput(text:String)
{
if (focus != null)
{
focus.dispatchTypingAction(ADD_TEXT(text));
}
}

function onKeyDown(key:KeyCode, modifier:KeyModifier)
{
// Taken from OpenFL's `TextField`
var modifierPressed = #if mac modifier.metaKey #elseif js(modifier.metaKey || modifier.ctrlKey) #else (modifier.ctrlKey && !modifier.altKey) #end;

switch (key)
{
case RETURN, NUMPAD_ENTER:
focus.dispatchTypingAction(COMMAND(NEW_LINE));
case BACKSPACE:
focus.dispatchTypingAction(COMMAND(DELETE_LEFT));
case DELETE:
focus.dispatchTypingAction(COMMAND(DELETE_RIGHT));
case LEFT:
if (modifierPressed)
{
focus.dispatchTypingAction(MOVE_CURSOR(PREVIOUS_LINE, modifier.shiftKey));
}
else
{
focus.dispatchTypingAction(MOVE_CURSOR(LEFT, modifier.shiftKey));
}
case RIGHT:
if (modifierPressed)
{
focus.dispatchTypingAction(MOVE_CURSOR(NEXT_LINE, modifier.shiftKey));
}
else
{
focus.dispatchTypingAction(MOVE_CURSOR(RIGHT, modifier.shiftKey));
}
case UP:
if (modifierPressed)
{
focus.dispatchTypingAction(MOVE_CURSOR(HOME, modifier.shiftKey));
}
else
{
focus.dispatchTypingAction(MOVE_CURSOR(UP, modifier.shiftKey));
}
case DOWN:
if (modifierPressed)
{
focus.dispatchTypingAction(MOVE_CURSOR(END, modifier.shiftKey));
}
else
{
focus.dispatchTypingAction(MOVE_CURSOR(DOWN, modifier.shiftKey));
}
case HOME:
if (modifierPressed)
{
focus.dispatchTypingAction(MOVE_CURSOR(HOME, modifier.shiftKey));
}
else
{
focus.dispatchTypingAction(MOVE_CURSOR(LINE_BEGINNING, modifier.shiftKey));
}
case END:
if (modifierPressed)
{
focus.dispatchTypingAction(MOVE_CURSOR(END, modifier.shiftKey));
}
else
{
focus.dispatchTypingAction(MOVE_CURSOR(LINE_END, modifier.shiftKey));
}
case C:
if (modifierPressed)
{
focus.dispatchTypingAction(COMMAND(COPY));
}
case X:
if (modifierPressed)
{
focus.dispatchTypingAction(COMMAND(CUT));
}
#if !js
case V:
if (modifierPressed)
{
focus.dispatchTypingAction(COMMAND(PASTE));
}
#end
case A:
if (modifierPressed)
{
focus.dispatchTypingAction(COMMAND(SELECT_ALL));
}
default:
}
}

function set_focus(value:IFlxInputText)
{
if (focus != value)
{
if (focus != null)
{
focus.hasFocus = false;
}

focus = value;

if (focus != null)
{
focus.hasFocus = true;
}

FlxG.stage.window.textInputEnabled = (focus != null);
}

return value;
}
}

interface IFlxInputText
{
var hasFocus(default, set):Bool;
function dispatchTypingAction(action:TypingAction):Void;
}

enum TypingAction
{
ADD_TEXT(text:String);
MOVE_CURSOR(type:MoveCursorAction, shiftKey:Bool);
COMMAND(cmd:TypingCommand);
}

enum MoveCursorAction
{
LEFT;
RIGHT;
UP;
DOWN;
HOME;
END;
LINE_BEGINNING;
LINE_END;
PREVIOUS_LINE;
NEXT_LINE;
}

enum TypingCommand
{
NEW_LINE;
DELETE_LEFT;
DELETE_RIGHT;
COPY;
CUT;
PASTE;
SELECT_ALL;
}
Loading
Loading