From 29930c6b44e4b1d5b60446c0b83059588a9e2d9e Mon Sep 17 00:00:00 2001 From: Christian Heller <c.heller@plomlompom.de> Date: Sat, 7 Nov 2020 21:28:35 +0100 Subject: [PATCH] Make keybindings configurable. --- new2/rogue_chat_curses.py | 79 +++++---- new2/rogue_chat_nocanvas_monochrome.html | 195 ++++++++++++++--------- 2 files changed, 175 insertions(+), 99 deletions(-) diff --git a/new2/rogue_chat_curses.py b/new2/rogue_chat_curses.py index 5b3a7a8..bb3dac2 100755 --- a/new2/rogue_chat_curses.py +++ b/new2/rogue_chat_curses.py @@ -48,19 +48,19 @@ def cmd_MAP(game, geometry, size, content): game.map_content = content if type(game.map_geometry) == MapGeometrySquare: game.tui.movement_keys = { - 'w': 'UP', - 'a': 'LEFT', - 's': 'DOWN', - 'd': 'RIGHT', + game.tui.keys['square_move_up']: 'UP', + game.tui.keys['square_move_left']: 'LEFT', + game.tui.keys['square_move_down']: 'DOWN', + game.tui.keys['square_move_right']: 'RIGHT', } elif type(game.map_geometry) == MapGeometryHex: game.tui.movement_keys = { - 'w': 'UPLEFT', - 'e': 'UPRIGHT', - 'd': 'RIGHT', - 'c': 'DOWNRIGHT', - 'x': 'DOWNLEFT', - 's': 'LEFT', + game.tui.keys['hex_move_upleft']: 'UPLEFT', + game.tui.keys['hex_move_upright']: 'UPRIGHT', + game.tui.keys['hex_move_right']: 'RIGHT', + game.tui.keys['hex_move_downright']: 'DOWNRIGHT', + game.tui.keys['hex_move_downleft']: 'DOWNLEFT', + game.tui.keys['hex_move_left']: 'LEFT', } cmd_MAP.argtypes = 'string:map_geometry yx_tuple:pos string' @@ -153,6 +153,8 @@ class TUI: self.is_intro = is_intro def __init__(self, host, port): + import os + import json self.host = host self.port = port self.mode_play = self.Mode('play') @@ -173,6 +175,30 @@ class TUI: self.queue = queue.Queue() self.login_name = None self.switch_mode('waiting_for_server') + self.keys = { + 'switch_to_chat': 'C', + 'switch_to_play': 'P', + 'switch_to_annotate': 'E', + 'switch_to_portal': 'p', + 'switch_to_study': '?', + 'switch_to_edit': 'E', + 'flatten': 'f', + 'hex_move_upleft': 'w', + 'hex_move_upright': 'e', + 'hex_move_right': 'd', + 'hex_move_downright': 'c', + 'hex_move_downleft': 'x', + 'hex_move_left': 's', + 'square_move_up': 'w', + 'square_move_left': 'a', + 'square_move_down': 's', + 'square_move_right': 'd', + } + if os.path.isfile('config.json'): + with open('config.json', 'r') as f: + keys_conf = json.loads(f.read()) + for k in keys_conf: + self.keys[k] = keys_conf[k] curses.wrapper(self.loop) def flash(self): @@ -225,18 +251,15 @@ class TUI: self.log_msg(" /P or /play - switch to play mode"); self.log_msg(" /? or /study - switch to study mode"); self.log_msg("commands common to study and play mode:"); - if type(self.game.map_geometry) == MapGeometrySquare: - self.log_msg(" w,a,s,d - move"); - elif type(self.game.map_geometry) == MapGeometryHex: - self.log_msg(" e,d,c,x,s,w - move"); - self.log_msg(" C - switch to chat mode"); + self.log_msg(" %s - move" % ','.join(self.movement_keys)); + self.log_msg(" %s - switch to chat mode" % self.keys['switch_to_chat']); self.log_msg("commands specific to play mode:"); - self.log_msg(" E - write following ASCII character"); - self.log_msg(" f - flatten surroundings"); - self.log_msg(" ? - switch to study mode"); + self.log_msg(" %s - write following ASCII character" % self.keys['switch_to_edit']); + self.log_msg(" %s - flatten surroundings" % self.keys['flatten']); + self.log_msg(" %s - switch to study mode" % self.keys['switch_to_study']); self.log_msg("commands specific to study mode:"); - self.log_msg(" E - annotate terrain"); - self.log_msg(" P - switch to play mode"); + self.log_msg(" %s - annotate terrain" % self.keys['switch_to_annotate']); + self.log_msg(" %s - switch to play mode" % self.keys['switch_to_play']); def loop(self, stdscr): @@ -504,24 +527,24 @@ class TUI: self.switch_mode('play') self.input_ = '' elif self.mode == self.mode_study: - if key == 'C': + if key == self.keys['switch_to_chat']: self.switch_mode('chat') - elif key == 'P': + elif key == self.keys['switch_to_play']: self.switch_mode('play') - elif key == 'A': + elif key == self.keys['switch_to_annotate']: self.switch_mode('annotate', keep_position=True) - elif key == 'p': + elif key == self.keys['switch_to_portal']: self.switch_mode('portal', keep_position=True) elif key in self.movement_keys: move_explorer(self.movement_keys[key]) elif self.mode == self.mode_play: - if key == 'C': + if key == self.keys['switch_to_chat']: self.switch_mode('chat') - elif key == '?': + elif key == self.keys['switch_to_study']: self.switch_mode('study') - if key == 'E': + if key == self.keys['switch_to_edit']: self.switch_mode('edit') - elif key == 'f': + elif key == self.keys['flatten']: self.send('TASK:FLATTEN_SURROUNDINGS') elif key in self.movement_keys: self.send('TASK:MOVE ' + self.movement_keys[key]) diff --git a/new2/rogue_chat_nocanvas_monochrome.html b/new2/rogue_chat_nocanvas_monochrome.html index b81dcb1..0f502ed 100644 --- a/new2/rogue_chat_nocanvas_monochrome.html +++ b/new2/rogue_chat_nocanvas_monochrome.html @@ -4,25 +4,54 @@ </style> </head><body> <div> -movement: <select id="movement_keys" name="movement_keys" > -<option value="alphabetic" selected>w/a/s/d (square grid) or e,d,c,x,s,w (hex grid)</option> -<option value="arrow_or_numpad">arrow keys (square grid) or numpad (hex grid)</option> -</select> rows: <input id="n_rows" type="number" step=4 min=8 value=24 /> cols: <input id="n_cols" type="number" step=4 min=20 value=80 /> -<option value=":" selected>:</option> -<option value="/">/</option> -</select> </div> <pre id="terminal" style="display: inline-block;"></pre> <textarea id="input" style="opacity: 0; width: 0px;"></textarea> +<div> +keys:<br /> +square_move_up: <input id="key_square_move_up" type="text" value="w" /> (hint: ArrowUp)<br /> +square_move_left: <input id="key_square_move_left" type="text" value="a" /> (hint: ArrowLeft)<br /> +square_move_down: <input id="key_square_move_down" type="text" value="s" /> (hint: ArrowDown)<br /> +square_move_right: <input id="key_square_move_right" type="text" value="d" /> (hint: ArrowRight)<br /> +hex_move_upleft: <input id="key_hex_move_upleft" type="text" value="w" /><br /> +hex_move_upright: <input id="key_hex_move_upright" type="text" value="e" /><br /> +hex_move_right: <input id="key_hex_move_right" type="text" value="d" /><br /> +hex_move_downright: <input id="key_hex_move_downright" type="text" value="c" /><br /> +hex_move_downleft: <input id="key_hex_move_downleft" type="text" value="x" /><br /> +hex_move_left: <input id="key_hex_move_left" type="text" value="s" /><br /> +flatten_: <input id="key_flatten" type="text" value="f" /><br /> +switch_to_chat: <input id="key_switch_to_chat" type="text" value="C" /><br /> +switch_to_play: <input id="key_switch_to_play" type="text" value="P" /><br /> +switch_to_annotate: <input id="key_switch_to_annotate" type="text" value="E" /><br /> +switch_to_portal: <input id="key_switch_to_portal" type="text" value="p" /><br /> +switch_to_study: <input id="key_switch_to_study" type="text" value="?" /><br /> +switch_to_edit: <input id="key_switch_to_edit" type="text" value="E" /><br /> +</div> <script> "use strict"; let websocket_location = "ws://localhost:8000"; -let movement_keys_selector = document.getElementById("movement_keys"); let rows_selector = document.getElementById("n_rows"); let cols_selector = document.getElementById("n_cols"); +let key_switch_to_chat_selector = document.getElementById("key_switch_to_chat"); +let key_switch_to_play_selector = document.getElementById("key_switch_to_play"); +let key_switch_to_annotate_selector = document.getElementById("key_switch_to_annotate"); +let key_switch_to_portal_selector = document.getElementById("key_switch_to_portal"); +let key_switch_to_study_selector = document.getElementById("key_switch_to_study"); +let key_switch_to_edit_selector = document.getElementById("key_switch_to_edit"); +let key_flatten_selector = document.getElementById("key_flatten"); +let key_hex_move_upleft_selector = document.getElementById("key_hex_move_upleft"); +let key_hex_move_upright_selector = document.getElementById("key_hex_move_upright"); +let key_hex_move_right_selector = document.getElementById("key_hex_move_right"); +let key_hex_move_downright_selector = document.getElementById("key_hex_move_downright"); +let key_hex_move_downleft_selector = document.getElementById("key_hex_move_downleft"); +let key_hex_move_left_selector = document.getElementById("key_hex_move_left"); +let key_square_move_up_selector = document.getElementById("key_square_move_up"); +let key_square_move_left_selector = document.getElementById("key_square_move_left"); +let key_square_move_down_selector = document.getElementById("key_square_move_down"); +let key_square_move_right_selector = document.getElementById("key_square_move_right"); let terminal = { foreground: 'white', @@ -180,7 +209,7 @@ let server = { game.get_thing(tokens[1], true).name_ = tokens[2]; } else if (tokens[0] === 'MAP') { game.map_geometry = tokens[1]; - tui.init_wasd(); + tui.init_keys(); game.map_size = parser.parse_yx(tokens[2]); game.map = tokens[3] } else if (tokens[0] === 'GAME_STATE_COMPLETE') { @@ -287,49 +316,43 @@ let tui = { this.recalc_input_lines(); this.height_header = this.height_turn_line + this.height_mode_line; this.log_msg("@ waiting for server connection ..."); - this.init_wasd(); + this.init_keys(); }, - init_wasd: function() { - - if (movement_keys_selector.value == 'alphabetic') { - if (game.map_geometry == 'Square') { - this.movement_keys = { - 'w': 'UP', - 'a': 'LEFT', - 's': 'DOWN', - 'd': 'RIGHT' - }; - tui.movement_keys_desc = 'w, a, s, d'; - } else if (game.map_geometry == 'Hex') { - this.movement_keys = { - 'w': 'UPLEFT', - 'e': 'UPRIGHT', - 'd': 'RIGHT', - 'c': 'DOWNRIGHT', - 'x': 'DOWNLEFT', - 's': 'LEFT' - }; - tui.movement_keys_desc = 'e, d, c, x, s, w'; + init_keys: function() { + this.keys = { + switch_to_chat: key_switch_to_chat_selector.value, + switch_to_play: key_switch_to_play_selector.value, + switch_to_annotate: key_switch_to_annotate_selector.value, + switch_to_portal: key_switch_to_portal_selector.value, + switch_to_study: key_switch_to_study_selector.value, + switch_to_edit: key_switch_to_edit_selector.value, + flatten: key_flatten_selector.value, + hex_move_upleft: key_hex_move_upleft_selector.value, + hex_move_upright: key_hex_move_upright_selector.value, + hex_move_right: key_hex_move_right_selector.value, + hex_move_downright: key_hex_move_downright_selector.value, + hex_move_downleft: key_hex_move_downleft_selector.value, + hex_move_left: key_hex_move_left_selector.value, + square_move_up: key_square_move_up_selector.value, + square_move_left: key_square_move_left_selector.value, + square_move_down: key_square_move_down_selector.value, + square_move_right: key_square_move_right_selector.value, + } + if (game.map_geometry == 'Square') { + this.movement_keys = { + [this.keys.square_move_up]: 'UP', + [this.keys.square_move_left]: 'LEFT', + [this.keys.square_move_down]: 'DOWN', + [this.keys.square_move_right]: 'RIGHT' }; - } else if (movement_keys_selector.value == 'arrow_or_numpad') { - if (game.map_geometry == 'Square') { - this.movement_keys = { - 'ArrowUp': 'UP', - 'ArrowLeft': 'LEFT', - 'ArrowDown': 'DOWN', - 'ArrowRight': 'RIGHT' - }; - tui.movement_keys_desc = 'arrow keys'; - } else if (game.map_geometry == 'Hex') { - this.movement_keys = { - '7': 'UPLEFT', - '9': 'UPRIGHT', - '6': 'RIGHT', - '3': 'DOWNRIGHT', - '1': 'DOWNLEFT', - '4': 'LEFT' - }; - tui.movement_keys_desc = 'numpad keys'; + } else if (game.map_geometry == 'Hex') { + this.movement_keys = { + [this.keys.hex_move_upleft]: 'UPLEFT', + [this.keys.hex_move_upright]: 'UPRIGHT', + [this.keys.hex_move_right]: 'RIGHT', + [this.keys.hex_move_downright]: 'DOWNRIGHT', + [this.keys.hex_move_downleft]: 'DOWNLEFT', + [this.keys.hex_move_left]: 'LEFT' }; }; }, @@ -398,6 +421,7 @@ let tui = { this.full_refresh(); }, log_help: function() { + let movement_keys_desc = Object.keys(this.movement_keys).join(','); this.log_msg("HELP:"); this.log_msg("chat mode commands:"); this.log_msg(" /nick NAME - re-name yourself to NAME"); @@ -406,15 +430,15 @@ let tui = { this.log_msg(" /P or /play - switch to play mode"); this.log_msg(" /? or /study - switch to study mode"); this.log_msg("commands common to study and play mode:"); - this.log_msg(" " + this.movement_keys_desc + " - move"); - this.log_msg(" C - switch to chat mode"); + this.log_msg(" " + movement_keys_desc + " - move"); + this.log_msg(" " + this.keys.switch_to_chat + " - switch to chat mode"); this.log_msg("commands specific to play mode:"); - this.log_msg(" E - write following ASCII character"); - this.log_msg(" f - flatten surroundings"); - this.log_msg(" ? - switch to study mode"); + this.log_msg(" " + this.keys.switch_to_edit + " - write following ASCII character"); + this.log_msg(" " + this.keys.flatten + " - flatten surroundings"); + this.log_msg(" " + this.keys.switch_to_study + " - switch to study mode"); this.log_msg("commands specific to study mode:"); - this.log_msg(" E - annotate terrain"); - this.log_msg(" P - switch to play mode"); + this.log_msg(" " + this.keys.switch_to_annotate + " - annotate terrain"); + this.log_msg(" " + this.keys.switch_to_play + " - switch to play mode"); }, draw_map: function() { let map_lines_split = []; @@ -740,42 +764,37 @@ tui.inputEl.addEventListener('keydown', (event) => { tui.empty_input(); tui.full_refresh(); } else if (tui.mode == mode_play) { - if (event.key === 'C') { + if (event.key === tui.keys.switch_to_chat) { event.preventDefault(); tui.switch_mode(mode_chat); - } else if (event.key === 'E') { + } else if (event.key === tui.keys.switch_to_edit) { event.preventDefault(); tui.switch_mode(mode_edit); - } else if (event.key === '?') { + } else if (event.key === tui.keys.switch_to_study) { tui.switch_mode(mode_study); - } else if (event.key === 'F1') { - tui.log_help(); - } else if (event.key === 'f') { + } else if (event.key === tui.keys.flatten) { server.send(["TASK:FLATTEN_SURROUNDINGS"]); } else if (event.key in tui.movement_keys) { server.send(['TASK:MOVE', tui.movement_keys[event.key]]); }; } else if (tui.mode == mode_study) { - if (event.key === 'C') { + if (event.key === tui.keys.switch_to_chat) { event.preventDefault(); tui.switch_mode(mode_chat); - } else if (event.key == 'P') { + } else if (event.key == tui.keys.switch_to_play) { tui.switch_mode(mode_play); - } else if (event.key === 'p') { + } else if (event.key === tui.keys.switch_to_portal) { event.preventDefault(); tui.switch_mode(mode_portal); } else if (event.key in tui.movement_keys) { explorer.move(tui.movement_keys[event.key]); - } else if (event.key === 'E') { + } else if (event.key === tui.keys.switch_to_annotate) { event.preventDefault(); tui.switch_mode(mode_annotate); }; } }, false); -movement_keys_selector.addEventListener('input', function() { - tui.init_wasd(); -}, false); rows_selector.addEventListener('input', function() { if (rows_selector.value % 4 != 0) { return; @@ -791,8 +810,42 @@ cols_selector.addEventListener('input', function() { tui.window_width = terminal.cols / 2, tui.full_refresh(); }, false); +key_switch_to_chat_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_switch_to_play_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_switch_to_annotate_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_switch_to_portal_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_switch_to_study_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_switch_to_edit_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_flatten_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_hex_move_upleft_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_hex_move_upright_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_hex_move_right_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_hex_move_downright_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_hex_move_downleft_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_hex_move_left_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_square_move_up_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_square_move_left_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_square_move_down_selector.addEventListener('input', function() { tui.init_keys(); }, false); +key_square_move_right_selector.addEventListener('input', function() { tui.init_keys(); }, false); window.setInterval(function() { - if (!(['input', 'n_cols', 'n_rows', 'movement_keys'].includes(document.activeElement.id))) { + if (!(['input', 'n_cols', 'n_rows', + 'key_switch_to_chat', + 'key_switch_to_play', + 'key_switch_to_annotate', + 'key_switch_to_portal', + 'key_switch_to_study', + 'key_switch_to_edit', + 'key_flatten', + 'key_hex_move_upleft', + 'key_hex_move_upright', + 'key_hex_move_right', + 'key_hex_move_downright', + 'key_hex_move_downleft', + 'key_hex_move_left', + 'key_square_move_up', + 'key_square_move_left', + 'key_square_move_down', + 'key_square_move_right',].includes(document.activeElement.id))) { tui.inputEl.focus(); } }, 100); -- 2.30.2