summaryrefslogtreecommitdiff
path: root/asciifarm/client
diff options
context:
space:
mode:
authortroido <troido@hotmail.com>2018-04-18 23:27:34 +0200
committertroido <troido@hotmail.com>2018-04-18 23:27:34 +0200
commit757ad925b47d24b1d0714671b8f04147a5748480 (patch)
treebc67553d76ac3301db7d2c20881448afc411221d /asciifarm/client
parentc0eb8ed32d53030de5b75b49a8e0f64e7c4a05ff (diff)
improved input handling
renamed InputHandler to CommandHandler. made InputHandler for input code that used to be in gameclient also started my own getstr() replacement.
Diffstat (limited to 'asciifarm/client')
-rw-r--r--asciifarm/client/commandhandler.py84
-rw-r--r--asciifarm/client/gameclient.py12
-rw-r--r--asciifarm/client/inputhandler.py129
3 files changed, 139 insertions, 86 deletions
diff --git a/asciifarm/client/commandhandler.py b/asciifarm/client/commandhandler.py
new file mode 100644
index 0000000..7eefe5b
--- /dev/null
+++ b/asciifarm/client/commandhandler.py
@@ -0,0 +1,84 @@
+
+import shlex
+
+class InvalidCommandException(Exception):
+ pass
+
+
+class CommandHandler:
+
+ def __init__(self, client):
+ self.client = client
+
+ self.commands = {
+ "send": self.send,
+ "input": self.input,
+ "move": self.move,
+ "say": self.say,
+ "chat": self.chat,
+ "log": self.log,
+ "do": self.do,
+ "runinput": self.runInput,
+ "select": self.select,
+ "inputwithselected": self.actWithSelected,
+ "eval": self.eval,
+ "exec": self.exec,
+ "scrollchat": self.scrollChat
+ }
+
+ def execute(self, action):
+ if isinstance(action[0], str):
+ command = action[0]
+ if command in self.commands:
+ self.commands[command](*action[1:])
+ else:
+ raise InvalidCommandException("Invalid command '{}'".format(command))
+ else:
+ raise Exception("Command should be a string")
+
+
+ # Commands
+
+ def send(self, data):
+ self.client.send(data)
+
+ def input(self, action):
+ self.send(["input", action])
+
+ def move(self, direction):
+ self.input(["move", direction])
+
+ def say(self, text):
+ self.input(["say", text])
+
+ def chat(self, text):
+ self.send(["chat", text])
+
+ def log(self, text):
+ self.client.log(text)
+
+ def do(self, actions):
+ for action in actions:
+ self.execute(action)
+
+ def runInput(self):
+ self.client.inputHandler.typing = True
+
+ def select(self, widget, value, relative=False, modular=False):
+ self.client.display.getWidget(widget).select(value, relative, modular)
+
+ def actWithSelected(self, action, widget):
+ self.input([action, self.client.display.getWidget(widget).getSelected()])
+
+ def eval(self, *texts):
+ text = " ".join(texts)
+ self.log(eval(text, {"self": self, "client": self.client, "connection": self.client.connection, "display": self.client.display}))
+
+ def exec(self, *texts):
+ text = " ".join(texts)
+ exec(text, {"self": self, "client": self.client, "connection": self.client.connection, "display": self.client.display})
+
+ def scrollChat(self, lines):
+ self.client.display.scrollBack(lines)
+
+
diff --git a/asciifarm/client/gameclient.py b/asciifarm/client/gameclient.py
index ec90cc6..0a9b243 100644
--- a/asciifarm/client/gameclient.py
+++ b/asciifarm/client/gameclient.py
@@ -15,7 +15,6 @@ from .display.screen import Screen
from .display.display import Display
from .inputhandler import InputHandler
-from .keynames import nameFromKey
class Client:
@@ -28,8 +27,7 @@ class Client:
self.logFile = logFile
self.closeMessage = None
- self.inputHandler = InputHandler(self, self.display, self.connection)
- self.keybindings = keybindings["actions"]
+ self.inputHandler = InputHandler(self, keybindings["actions"])
self.controlsString = keybindings.get("help", "")
@@ -128,12 +126,6 @@ class Client:
with(open(self.logFile, 'a')) as f:
f.write(text+'\n')
- def onInput(self, key):
- keyName = nameFromKey(key)
- if keyName in self.keybindings:
- self.inputHandler.execute(self.keybindings[keyName])
-
-
def command_loop(self):
while self.keepalive:
@@ -141,7 +133,7 @@ class Client:
if action[0] == "message":
self.update(action[1])
elif action[0] == "input":
- self.onInput(action[1])
+ self.inputHandler.onInput(action[1])
elif action[0] == "error":
raise action[1]
else:
diff --git a/asciifarm/client/inputhandler.py b/asciifarm/client/inputhandler.py
index 7fb18ad..1d907e9 100644
--- a/asciifarm/client/inputhandler.py
+++ b/asciifarm/client/inputhandler.py
@@ -1,96 +1,73 @@
-import shlex
-
-class InvalidCommandException(Exception):
- pass
-
+from commandhandler import CommandHandler
+from .keynames import nameFromKey
+import curses
+import curses.ascii
class InputHandler:
- def __init__(self, client, display, connection):
+ def __init__(self, client, keybindings):
self.client = client
- self.display = display
- self.connection = connection
+ self.keybindings = keybindings
+ self.commandHandler = CommandHandler(self.client)
- self.commands = {
- "send": self.send,
- "input": self.input,
- "move": self.move,
- "say": self.say,
- "chat": self.chat,
- "log": self.log,
- "do": self.do,
- "runinput": self.runInput,
- "select": self.select,
- "inputwithselected": self.actWithSelected,
- "eval": self.eval,
- "exec": self.exec,
- "scrollchat": self.scrollChat
- }
-
- def execute(self, action):
- if isinstance(action[0], str):
- command = action[0]
- if command in self.commands:
- self.commands[command](*action[1:])
- else:
- raise InvalidCommandException("Invalid command '{}'".format(command))
- else:
- raise Exception("Command should be a string")
-
-
-
- def send(self, data):
- self.client.send(data)
-
- def input(self, action):
- self.send(["input", action])
-
- def move(self, direction):
- self.input(["move", direction])
+ self.typing = False
+ self.string = ""
+ self.cursor = 0
- def say(self, text):
- self.input(["say", text])
- def chat(self, text):
- self.send(["chat", text])
-
- def log(self, text):
- self.client.log(text)
+ def onInput(self, key):
+ if not self.typing:
+ keyName = nameFromKey(key)
+ if keyName in self.keybindings:
+ self.commandHandler.execute(self.keybindings[keyName])
+ else:
+ self.addKey(key)
- def do(self, actions):
- for action in actions:
- self.execute(action)
- def runInput(self):
- message = self.display.getString()
+ def processString(self, message):
if message:
if message[0] == '/':
if message[1] == '/':
- self.chat(message[1:])
+ self.commandHandler.chat(message[1:])
else:
try:
- self.execute(shlex.split(message[1:]))
+ self.commandHandler.execute(shlex.split(message[1:]))
except InvalidCommandException as e:
- self.log(", ".join(e.args))
+ self.client.log(", ".join(e.args))
else:
- self.chat(message)
-
- def select(self, widget, value, relative=False, modular=False):
- self.display.getWidget(widget).select(value, relative, modular)
-
- def actWithSelected(self, action, widget):
- self.input([action, self.display.getWidget(widget).getSelected()])
-
- def eval(self, *texts):
- text = " ".join(texts)
- self.log(eval(text, {"self": self, "client": self.client, "connection": self.connection, "display": self.display}))
-
- def exec(self, *texts):
- text = " ".join(texts)
- exec(text, {"self": self, "client": self.client, "connection": self.connection, "display": self.display})
+ self.commandHandler.chat(message)
+
+
+ def addKey(self, key):
+ if curses.ascii.isprint(key):
+ self.string = self.string[:self.cursor] + chr(key) + self.string[self.cursor:]
+ self.cursor += 1
+ elif key == curses.KEY_BACKSPACE or key == curses.ascii.BS or key == curses.ascii.DEL:
+ self.string = self.string[:self.cursor-1] + self.string[self.cursor:]
+ self.cursor = max(self.cursor - 1, 0)
+ elif key == curses.KEY_RIGHT:
+ self.cursor = max(self.cursor + 1, len(self.string))
+ elif key == curses.KEY_LEFT:
+ self.cursor = max(self.cursor - 1, 0)
+ elif key == curses.KEY_DC:
+ self.string = self.string[:self.cursor] + self.string[self.cursor+1:]
+ elif key == curses.KEY_HOME:
+ self.cursor = 0
+ elif key == curses.KEY_END:
+ self.cursor = len(self.string)
+
+ elif key == curses.ascii.ESC or key == curses.KEY_DL:
+ self.typing = False
+ self.string = ""
+ self.cursor = 0
+ elif key == curses.ascii.LF or key == curses.ascii.CR:
+ message = self.string
+ self.string = ""
+ self.cursor = 0
+ self.typing = False
+ self.processString(message)
+
- def scrollChat(self, lines):
- self.display.scrollBack(lines)