From 5d7a3a00723bb1e5c2725ac63e4b1177ad2f87ea Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 12 Aug 2018 13:28:04 -0400 Subject: [PATCH] runelite-client: add wasd camera plugin --- .../java/net/runelite/api/widgets/Widget.java | 2 + .../net/runelite/api/widgets/WidgetID.java | 2 + .../net/runelite/api/widgets/WidgetInfo.java | 2 + .../plugins/wasdcamera/WASDCameraConfig.java | 79 +++++++ .../wasdcamera/WASDCameraListener.java | 198 ++++++++++++++++++ .../plugins/wasdcamera/WASDCameraPlugin.java | 159 ++++++++++++++ .../scripts/ChatboxInputWidgetBuilder.hash | 1 + .../scripts/ChatboxInputWidgetBuilder.rs2asm | 168 +++++++++++++++ .../java/net/runelite/rs/api/RSWidget.java | 4 + 9 files changed, 615 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraPlugin.java create mode 100644 runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.hash create mode 100644 runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.rs2asm diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java b/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java index 15ead6cad1..20ecaefc73 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/Widget.java @@ -538,4 +538,6 @@ public interface Widget * Recomputes this widget's group's x/y/w/h including scroll */ void revalidateScroll(); + + Object[] getOnKeyListener(); } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 0408e5a960..0e9464eed7 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -342,10 +342,12 @@ public class WidgetID static class Chatbox { + static final int CHATBOX_PARENT = 0; static final int CHATBOX_BUTTONS = 1; static final int CHATBOX_REPORT_TEXT = 28; static final int CHATBOX_FRAME = 29; static final int CHATBOX_MESSAGES = 47; + static final int CHATBOX_INPUT = 49; } static class Prayer diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 3b2f26e2e0..c5bed947b5 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -287,10 +287,12 @@ public enum WidgetInfo SLAYER_REWARDS_TOPBAR(WidgetID.SLAYER_REWARDS_GROUP_ID, WidgetID.SlayerRewards.TOP_BAR), + CHATBOX_PARENT(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.CHATBOX_PARENT), CHATBOX(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.CHATBOX_FRAME), CHATBOX_MESSAGES(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.CHATBOX_MESSAGES), CHATBOX_BUTTONS(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.CHATBOX_BUTTONS), CHATBOX_REPORT_TEXT(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.CHATBOX_REPORT_TEXT), + CHATBOX_INPUT(WidgetID.CHATBOX_GROUP_ID, WidgetID.Chatbox.CHATBOX_INPUT), BA_HEAL_WAVE_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.CURRENT_WAVE), BA_HEAL_CALL_TEXT(WidgetID.BA_HEALER_GROUP_ID, WidgetID.BarbarianAssault.TO_CALL), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraConfig.java new file mode 100644 index 0000000000..16e7c2c25a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraConfig.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.wasdcamera; + +import java.awt.event.KeyEvent; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Keybind; + +@ConfigGroup("wasdcamera") +public interface WASDCameraConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "up", + name = "Up key", + description = "The key which will replace up." + ) + default Keybind up() + { + return new Keybind(KeyEvent.VK_W, 0); + } + + @ConfigItem( + position = 2, + keyName = "down", + name = "Down key", + description = "The key which will replace down." + ) + default Keybind down() + { + return new Keybind(KeyEvent.VK_S, 0); + } + + @ConfigItem( + position = 3, + keyName = "left", + name = "Left key", + description = "The key which will replace left." + ) + default Keybind left() + { + return new Keybind(KeyEvent.VK_A, 0); + } + + @ConfigItem( + position = 4, + keyName = "right", + name = "Right key", + description = "The key which will replace right." + ) + default Keybind right() + { + return new Keybind(KeyEvent.VK_D, 0); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java new file mode 100644 index 0000000000..87b2b96f96 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2018, Adam + * Copyright (c) 2018, Abexlry + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.wasdcamera; + +import java.awt.event.KeyEvent; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.VarClientStr; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.input.KeyListener; +import net.runelite.client.input.MouseListener; + +class WASDCameraListener extends MouseListener implements KeyListener +{ + @Inject + private WASDCameraPlugin plugin; + + @Inject + private WASDCameraConfig config; + + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Override + public void keyTyped(KeyEvent e) + { + handleKey(e); + } + + @Override + public void keyPressed(KeyEvent e) + { + if (!plugin.chatboxFocused()) + { + return; + } + + if (!plugin.isTyping()) + { + if (config.up().matches(e)) + { + e.setKeyCode(KeyEvent.VK_UP); + } + else if (config.down().matches(e)) + { + e.setKeyCode(KeyEvent.VK_DOWN); + } + else if (config.left().matches(e)) + { + e.setKeyCode(KeyEvent.VK_LEFT); + } + else if (config.right().matches(e)) + { + e.setKeyCode(KeyEvent.VK_RIGHT); + } + else + { + switch (e.getKeyCode()) + { + case KeyEvent.VK_ENTER: + case KeyEvent.VK_SLASH: + // refocus chatbox + clientThread.invoke(() -> + { + plugin.unlockChat(); + }); + break; + case KeyEvent.VK_F1: + case KeyEvent.VK_F2: + case KeyEvent.VK_F3: + case KeyEvent.VK_F4: + case KeyEvent.VK_F5: + case KeyEvent.VK_F6: + case KeyEvent.VK_F7: + case KeyEvent.VK_F8: + case KeyEvent.VK_F9: + case KeyEvent.VK_F10: + case KeyEvent.VK_F11: + case KeyEvent.VK_F12: + case KeyEvent.VK_UP: + case KeyEvent.VK_DOWN: + case KeyEvent.VK_LEFT: + case KeyEvent.VK_RIGHT: + break; + default: + e.consume(); + break; + + } + } + } + else + { + switch (e.getKeyCode()) + { + case KeyEvent.VK_ENTER: + clientThread.invoke(() -> + { + plugin.lockChat(); + }); + break; + case KeyEvent.VK_ESCAPE: + clientThread.invoke(() -> + { + client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, ""); + plugin.lockChat(); + }); + break; + } + } + } + + @Override + public void keyReleased(KeyEvent e) + { + handleKey(e); + } + + private void handleKey(KeyEvent e) + { + if (!plugin.chatboxFocused()) + { + return; + } + + if (!plugin.isTyping()) + { + if (config.up().matches(e)) + { + e.setKeyCode(KeyEvent.VK_UP); + } + else if (config.down().matches(e)) + { + e.setKeyCode(KeyEvent.VK_DOWN); + } + else if (config.left().matches(e)) + { + e.setKeyCode(KeyEvent.VK_LEFT); + } + else if (config.right().matches(e)) + { + e.setKeyCode(KeyEvent.VK_RIGHT); + } + else + { + switch (e.getKeyCode()) + { + case KeyEvent.VK_F1: + case KeyEvent.VK_F2: + case KeyEvent.VK_F3: + case KeyEvent.VK_F4: + case KeyEvent.VK_F5: + case KeyEvent.VK_F6: + case KeyEvent.VK_F7: + case KeyEvent.VK_F8: + case KeyEvent.VK_F9: + case KeyEvent.VK_F10: + case KeyEvent.VK_F11: + case KeyEvent.VK_F12: + case KeyEvent.VK_UP: + case KeyEvent.VK_DOWN: + case KeyEvent.VK_LEFT: + case KeyEvent.VK_RIGHT: + break; + default: + e.consume(); + break; + } + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraPlugin.java new file mode 100644 index 0000000000..d4d9bd39d4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraPlugin.java @@ -0,0 +1,159 @@ +/*' + * Copyright (c) 2018, Adam + * Copyright (c) 2018, Abexlry + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.wasdcamera; + +import com.google.common.eventbus.Subscribe; +import com.google.inject.Provides; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.events.ScriptCallbackEvent; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.input.KeyManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "WASD Camera", + description = "Allows use of WASD keys for camera movement with 'Press Enter to Chat'", + tags = {"enter", "chat"}, + enabledByDefault = false +) +public class WASDCameraPlugin extends Plugin +{ + private static final String PRESS_ENTER_TO_CHAT = "Press Enter to Chat..."; + private static final String SCRIPT_EVENT_SET_CHATBOX_INPUT = "setChatboxInput"; + + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private KeyManager keyManager; + + @Inject + private WASDCameraListener inputListener; + + @Getter(AccessLevel.PACKAGE) + private boolean typing; + + @Override + protected void startUp() throws Exception + { + typing = false; + keyManager.registerKeyListener(inputListener); + + clientThread.invoke(() -> + { + if (client.getGameState() == GameState.LOGGED_IN) + { + lockChat(); + } + }); + } + + @Override + protected void shutDown() throws Exception + { + clientThread.invoke(() -> + { + if (client.getGameState() == GameState.LOGGED_IN) + { + unlockChat(); + } + }); + + keyManager.unregisterKeyListener(inputListener); + } + + @Provides + WASDCameraConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(WASDCameraConfig.class); + } + + boolean chatboxFocused() + { + Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT); + return chatboxParent != null && chatboxParent.getOnKeyListener() != null; + } + + @Subscribe + public void onScriptEvent(ScriptCallbackEvent scriptCallbackEvent) + { + if (scriptCallbackEvent.getEventName().equals(SCRIPT_EVENT_SET_CHATBOX_INPUT)) + { + Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); + if (chatboxInput != null) + { + if (chatboxFocused() && !typing) + { + chatboxInput.setText(PRESS_ENTER_TO_CHAT); + } + } + } + } + + void lockChat() + { + Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT); + if (chatboxParent != null && chatboxParent.getOnKeyListener() != null) + { + typing = false; + + Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); + if (chatboxInput != null) + { + chatboxInput.setText(PRESS_ENTER_TO_CHAT); + } + } + } + + void unlockChat() + { + Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT); + if (chatboxParent != null) + { + typing = true; + + Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT); + if (chatboxInput != null) + { + if (client.getGameState() == GameState.LOGGED_IN) + { + chatboxInput.setText(client.getLocalPlayer().getName() + ": *"); + } + } + } + } +} diff --git a/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.hash b/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.hash new file mode 100644 index 0000000000..1829e27080 --- /dev/null +++ b/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.hash @@ -0,0 +1 @@ +964049D8E719D7886E52ECC7E784D6FC9E7C6E5B5B50E577B926F73B32B0C9AF \ No newline at end of file diff --git a/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.rs2asm b/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.rs2asm new file mode 100644 index 0000000000..17d31181e1 --- /dev/null +++ b/runelite-client/src/main/scripts/ChatboxInputWidgetBuilder.rs2asm @@ -0,0 +1,168 @@ +.id 223 +.int_stack_count 0 +.string_stack_count 0 +.int_var_count 4 +.string_var_count 3 + load_string "" + sstore 0 + load_int 0 + istore 0 + load_int 6250335 + istore 1 + invoke 921 + load_int 1 + if_icmpeq LABEL10 + jump LABEL20 +LABEL10: + load_string "" + load_int 16777215 + load_int 12566463 + istore 1 + istore 0 + sstore 0 + load_int 1 + load_int 10616881 + widget_put_text_shadowed_widget + jump LABEL23 +LABEL20: + load_int 0 + load_int 10616881 + widget_put_text_shadowed_widget +LABEL23: + iload 0 + load_int 10616881 + widget_put_textcolor_widget + get_varc_string 1 + string_length + istore 2 + get_varc_string 1 + appendtags + sstore 1 + load_string "" + sstore 2 + load_int 0 + istore 3 + get_varc 203 + load_int 1 + if_icmpeq LABEL40 + jump LABEL99 +LABEL40: + load_int 105 + load_int 115 + load_int 1894 + get_varbit 1777 + get_enum_value + get_localplayer_name + load_string ": " + sload 0 + sload 1 + load_string "" + string_append 6 + sstore 2 + iload 2 + load_int 80 + if_icmplt LABEL56 + jump LABEL63 +LABEL56: + sload 2 + sload 0 + load_string "*" + load_string "" + string_append 3 + concat_string + sstore 2 +LABEL63: + sload 2 + load_int 2147483647 + load_int 495 + get_max_line_width + istore 3 + iload 3 + load_int 10616881 + widget_get_width_widget + if_icmpgt LABEL73 + jump LABEL79 +LABEL73: + load_int 2 + load_int 2 + load_int 0 + load_int 10616881 + widget_put_text_alignment_widget + jump LABEL84 +LABEL79: + load_int 0 + load_int 2 + load_int 0 + load_int 10616881 + widget_put_text_alignment_widget +LABEL84: + load_int 10616881 + widget_put_actions_null_widget + load_int -1 + load_string "" + load_int 10616881 + widget_put_mouse_hover_listener_widget + load_int -1 + load_string "" + load_int 10616881 + widget_put_mouse_exit_listener_widget + load_int -1 + load_string "" + load_int 10616881 + widget_put_option_click_listener_widget + jump LABEL140 +LABEL99: + load_int 105 + load_int 115 + load_int 1894 + get_varbit 1777 + get_enum_value + load_string " You must set a name before you can chat." + string_append 2 + sstore 2 + load_int 1 + load_int 2 + load_int 0 + load_int 10616881 + widget_put_text_alignment_widget + load_int 10 + load_string "Configure" + load_int 10616881 + widget_put_action_widget + load_string "" + load_string "Display name" + load_string "" + string_append 3 + load_int 10616881 + widget_put_name_widget + load_int 45 + load_int -2147483645 + iload 1 + load_string "Ii" + load_int 10616881 + widget_put_mouse_hover_listener_widget + load_int 45 + load_int -2147483645 + iload 0 + load_string "Ii" + load_int 10616881 + widget_put_mouse_exit_listener_widget + load_int 489 + load_int -2147483644 + load_int 1024 + load_string "ii" + load_int 10616881 + widget_put_option_click_listener_widget +LABEL140: + sload 2 + load_int 10616881 + widget_put_text_widget + load_string "setChatboxInput" + runelite_callback + load_int 3 + load_int 16 + load_int 1 + load_int 0 + load_int 10616881 + widget_put_size_widget + return diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSWidget.java b/runescape-api/src/main/java/net/runelite/rs/api/RSWidget.java index 36d9ed69fe..0f39d97ce0 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSWidget.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSWidget.java @@ -301,4 +301,8 @@ public interface RSWidget extends Widget @Import("hasListener") @Override void setHasListener(boolean hasListener); + + @Import("onKeyListener") + @Override + Object[] getOnKeyListener(); }