Bläddra i källkod

Console autocomplete (#701)

Aksel 5 år sedan
förälder
incheckning
a8174c69c8
2 ändrade filer med 62 tillägg och 0 borttagningar
  1. 55 0
      h2d/Console.hx
  2. 7 0
      hxd/Window.js.hx

+ 55 - 0
h2d/Console.hx

@@ -25,6 +25,7 @@ class Console #if !macro extends h2d.Object #end {
 	var height : Int;
 	var bg : h2d.Bitmap;
 	var tf : h2d.TextInput;
+	var hintTxt: h2d.Text;
 	var logTxt : h2d.HtmlText;
 	var lastLogTime : Float;
 	var commands : Map < String, { help : String, args : Array<ConsoleArgDesc>, callb : Dynamic } > ;
@@ -35,6 +36,7 @@ class Console #if !macro extends h2d.Object #end {
 	var curCmd:String;
 
 	public var shortKeyChar : Int = "/".code;
+	public var autoComplete : Bool = true;
 
 	public function new(font:h2d.Font,?parent) {
 		super(parent);
@@ -47,12 +49,21 @@ class Console #if !macro extends h2d.Object #end {
 		logIndex = -1;
 		bg = new h2d.Bitmap(h2d.Tile.fromColor(0,1,1,0.5), this);
 		bg.visible = false;
+
+		hintTxt = new h2d.Text(font, bg);
+		hintTxt.x = 2;
+		hintTxt.y = 1;
+		hintTxt.textColor = 0xFFFFFFFF;
+		hintTxt.alpha = 0.5;
+
 		tf = new h2d.TextInput(font, bg);
 		tf.onKeyDown = handleKey;
+		tf.onChange = handleCmdChange;
 		tf.onFocusLost = function(_) hide();
 		tf.x = 2;
 		tf.y = 1;
 		tf.textColor = 0xFFFFFFFF;
+
 		commands = new Map();
 		aliases = new Map();
 		addCommand("help", "Show help", [ { name : "command", t : AString, opt : true } ], showHelp);
@@ -175,6 +186,7 @@ class Console #if !macro extends h2d.Object #end {
 	public function hide() {
 		bg.visible = false;
 		tf.text = "";
+		hintTxt.text = "";
 		tf.cursorIndex = -1;
 	}
 
@@ -185,6 +197,24 @@ class Console #if !macro extends h2d.Object #end {
 		logIndex = -1;
 	}
 
+	function getCommandSuggestion(cmd : String) : String {
+		if (cmd == "") {
+			return "";
+		}
+
+		var closestCommand = "";
+		var commandNames = commands.keys();
+		for (command in commandNames) {
+			if (command.indexOf(cmd) == 0) {
+				if (closestCommand == "" || closestCommand.length > command.length) {
+					closestCommand = command;
+				}
+			}
+		}
+
+		return closestCommand;
+	}
+
 	function handleKey( e : hxd.Event ) {
 		if( !bg.visible )
 			return;
@@ -192,10 +222,26 @@ class Console #if !macro extends h2d.Object #end {
 		case Key.ENTER, Key.NUMPAD_ENTER:
 			var cmd = tf.text;
 			tf.text = "";
+
+			hintTxt.text = "";
+			if (autoComplete) {
+				var suggestion = getCommandSuggestion(cmd);
+				if (suggestion != "") {
+					cmd = suggestion;
+				}
+			}
+
 			handleCommand(cmd);
 			if( !logTxt.visible ) bg.visible = false;
 			e.cancel = true;
 			return;
+		case Key.TAB:
+			if (autoComplete) {
+				if (hintTxt.text != "") {
+					tf.text = hintTxt.text + " ";
+					tf.cursorIndex = tf.text.length;
+				}
+			}
 		case Key.ESCAPE:
 			hide();
 		case Key.UP:
@@ -221,6 +267,15 @@ class Console #if !macro extends h2d.Object #end {
 		}
 	}
 
+	function handleCmdChange() {
+		hintTxt.visible = autoComplete;
+		if (autoComplete) {
+			hintTxt.text = getCommandSuggestion(tf.text);
+		} else {
+			hintTxt.text = "";
+		}
+	}
+
 	function handleCommand( command : String ) {
 		command = StringTools.trim(command);
 		if( command.charCodeAt(0) == "/".code ) command = command.substr(1);

+ 7 - 0
hxd/Window.js.hx

@@ -47,6 +47,12 @@ class Window {
 
 		this.canvas = canvas;
 		this.propagateKeyEvents = globalEvents;
+
+		var propagate = canvas.getAttribute("propagateKeyEvents");
+		if (propagate != null) {
+			this.propagateKeyEvents = propagate != "0" && propagate != "false";
+		}
+
 		focused = globalEvents;
 		element = globalEvents ? js.Browser.window : canvas;
 		canvasPos = canvas.getBoundingClientRect();
@@ -301,6 +307,7 @@ class Window {
 					33, 34, // Page up/down
 					35, 36, // Home/end
 					8, // Backspace
+					9, // Tab
 					16, // Shift
 					17 : // Ctrl
 						e.preventDefault();