diff --git a/assets/default/keymap.xml b/assets/default/keymap.xml index ab032ebf2..950da7980 100644 --- a/assets/default/keymap.xml +++ b/assets/default/keymap.xml @@ -1,8 +1,8 @@ - - - - - + + + + + diff --git a/src/org/geometerplus/android/fbreader/preferences/PreferenceActivity.java b/src/org/geometerplus/android/fbreader/preferences/PreferenceActivity.java index c29c5a0d3..a0f10a0df 100644 --- a/src/org/geometerplus/android/fbreader/preferences/PreferenceActivity.java +++ b/src/org/geometerplus/android/fbreader/preferences/PreferenceActivity.java @@ -20,6 +20,7 @@ package org.geometerplus.android.fbreader.preferences; import android.content.Intent; +import android.view.KeyEvent; import org.geometerplus.zlibrary.core.application.ZLKeyBindings; import org.geometerplus.zlibrary.core.options.ZLIntegerOption; @@ -407,14 +408,14 @@ public class PreferenceActivity extends ZLPreferenceActivity { { ActionCode.EXIT, ActionCode.SHOW_CANCEL_MENU }; cancelMenuScreen.addPreference(new ZLStringChoicePreference( this, cancelMenuScreen.Resource, "backKeyAction", - bindings.getOption("", false), backKeyActions + bindings.getOption(KeyEvent.KEYCODE_BACK, false), backKeyActions )); final String[] backKeyLongPressActions = //{ ActionCode.EXIT, ActionCode.GO_BACK, ActionCode.SHOW_CANCEL_MENU, FBReaderApp.NoAction }; { ActionCode.EXIT, ActionCode.SHOW_CANCEL_MENU, FBReaderApp.NoAction }; cancelMenuScreen.addPreference(new ZLStringChoicePreference( this, cancelMenuScreen.Resource, "backKeyLongPressAction", - bindings.getOption("", true), backKeyLongPressActions + bindings.getOption(KeyEvent.KEYCODE_BACK, true), backKeyLongPressActions )); } } diff --git a/src/org/geometerplus/zlibrary/core/application/ZLApplication.java b/src/org/geometerplus/zlibrary/core/application/ZLApplication.java index 4799619fa..17ff0fcda 100644 --- a/src/org/geometerplus/zlibrary/core/application/ZLApplication.java +++ b/src/org/geometerplus/zlibrary/core/application/ZLApplication.java @@ -146,12 +146,12 @@ public abstract class ZLApplication { //may be protected abstract public ZLKeyBindings keyBindings(); - public final boolean hasActionForKey(String key, boolean longPress) { + public final boolean hasActionForKey(int key, boolean longPress) { final String actionId = keyBindings().getBinding(key, longPress); return actionId != null && !NoAction.equals(actionId); } - public final boolean doActionByKey(String key, boolean longPress) { + public final boolean doActionByKey(int key, boolean longPress) { final String actionId = keyBindings().getBinding(key, longPress); if (actionId != null) { final ZLAction action = myIdToActionMap.get(actionId); diff --git a/src/org/geometerplus/zlibrary/core/application/ZLKeyBindings.java b/src/org/geometerplus/zlibrary/core/application/ZLKeyBindings.java index 94c3db6db..516330a63 100644 --- a/src/org/geometerplus/zlibrary/core/application/ZLKeyBindings.java +++ b/src/org/geometerplus/zlibrary/core/application/ZLKeyBindings.java @@ -33,23 +33,35 @@ public final class ZLKeyBindings { private final String myName; private final ZLStringListOption myKeysOption; - private final TreeMap myActionMap = new TreeMap(); - private final TreeMap myLongPressActionMap = new TreeMap(); + private final TreeMap myActionMap = new TreeMap(); + private final TreeMap myLongPressActionMap = new TreeMap(); public ZLKeyBindings(String name) { myName = name; final List keys = new LinkedList(); new Reader(keys).readBindings(); + Collections.sort(keys); myKeysOption = new ZLStringListOption(name, "KeyList", keys); + // this code is here for migration from old versions; + // should be removed in FBReader 2.0 + ZLStringOption oldBackKeyOption = new ZLStringOption(name + ":" + ACTION, "", ""); + if (oldBackKeyOption.getValue() != null) { + new ZLStringOption(name + ":" + ACTION, "4", oldBackKeyOption.getValue()); + } + oldBackKeyOption = new ZLStringOption(name + ":" + LONG_PRESS_ACTION, "", ""); + if (oldBackKeyOption.getValue() != null) { + new ZLStringOption(name + ":" + LONG_PRESS_ACTION, "4", oldBackKeyOption.getValue()); + } + // end of migration code } - private ZLStringOption createOption(String key, boolean longPress, String defaultValue) { + private ZLStringOption createOption(int key, boolean longPress, String defaultValue) { final String group = myName + ":" + (longPress ? LONG_PRESS_ACTION : ACTION); - return new ZLStringOption(group, key, defaultValue); + return new ZLStringOption(group, String.valueOf(key), defaultValue); } - public ZLStringOption getOption(String key, boolean longPress) { - final TreeMap map = longPress ? myLongPressActionMap : myActionMap; + public ZLStringOption getOption(int key, boolean longPress) { + final TreeMap map = longPress ? myLongPressActionMap : myActionMap; ZLStringOption option = map.get(key); if (option == null) { option = createOption(key, longPress, ZLApplication.NoAction); @@ -58,17 +70,19 @@ public final class ZLKeyBindings { return option; } - public void bindKey(String key, boolean longPress, String actionId) { + public void bindKey(int key, boolean longPress, String actionId) { + final String stringKey = String.valueOf(key); List keys = myKeysOption.getValue(); - if (!keys.contains(key)) { + if (!keys.contains(stringKey)) { keys = new ArrayList(keys); - keys.add(key); + keys.add(stringKey); + Collections.sort(keys); myKeysOption.setValue(keys); } getOption(key, longPress).setValue(actionId); } - public String getBinding(String key, boolean longPress) { + public String getBinding(int key, boolean longPress) { return getOption(key, longPress).getValue(); } @@ -87,11 +101,15 @@ public final class ZLKeyBindings { @Override public boolean startElementHandler(String tag, ZLStringMap attributes) { if ("binding".equals(tag)) { - final String key = attributes.getValue("key"); + final String stringKey = attributes.getValue("key"); final String actionId = attributes.getValue("action"); - if (key != null && actionId != null) { - myKeyList.add(key); - myActionMap.put(key, createOption(key, false, actionId)); + if (stringKey != null && actionId != null) { + try { + final int key = Integer.parseInt(stringKey); + myKeyList.add(stringKey); + myActionMap.put(key, createOption(key, false, actionId)); + } catch (NumberFormatException e) { + } } } return false; diff --git a/src/org/geometerplus/zlibrary/ui/android/util/ZLAndroidKeyUtil.java b/src/org/geometerplus/zlibrary/ui/android/util/ZLAndroidKeyUtil.java deleted file mode 100644 index cf79cf707..000000000 --- a/src/org/geometerplus/zlibrary/ui/android/util/ZLAndroidKeyUtil.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2007-2011 Geometer Plus - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -package org.geometerplus.zlibrary.ui.android.util; - -import android.view.KeyEvent; - -public final class ZLAndroidKeyUtil { - public static String getKeyNameByCode(int code) { - switch (code) { - case KeyEvent.KEYCODE_0: - return "<0>"; - case KeyEvent.KEYCODE_1: - return "<1>"; - case KeyEvent.KEYCODE_2: - return "<2>"; - case KeyEvent.KEYCODE_3: - return "<3>"; - case KeyEvent.KEYCODE_4: - return "<4>"; - case KeyEvent.KEYCODE_5: - return "<5>"; - case KeyEvent.KEYCODE_6: - return "<6>"; - case KeyEvent.KEYCODE_7: - return "<7>"; - case KeyEvent.KEYCODE_8: - return "<8>"; - case KeyEvent.KEYCODE_9: - return "<9>"; - case KeyEvent.KEYCODE_A: - return ""; - case KeyEvent.KEYCODE_B: - return ""; - case KeyEvent.KEYCODE_C: - return ""; - case KeyEvent.KEYCODE_D: - return ""; - case KeyEvent.KEYCODE_E: - return ""; - case KeyEvent.KEYCODE_F: - return ""; - case KeyEvent.KEYCODE_G: - return ""; - case KeyEvent.KEYCODE_H: - return ""; - case KeyEvent.KEYCODE_I: - return ""; - case KeyEvent.KEYCODE_J: - return ""; - case KeyEvent.KEYCODE_K: - return ""; - case KeyEvent.KEYCODE_L: - return ""; - case KeyEvent.KEYCODE_M: - return ""; - case KeyEvent.KEYCODE_N: - return ""; - case KeyEvent.KEYCODE_O: - return ""; - case KeyEvent.KEYCODE_P: - return "

"; - case KeyEvent.KEYCODE_Q: - return ""; - case KeyEvent.KEYCODE_R: - return ""; - case KeyEvent.KEYCODE_S: - return ""; - case KeyEvent.KEYCODE_T: - return ""; - case KeyEvent.KEYCODE_U: - return ""; - case KeyEvent.KEYCODE_V: - return ""; - case KeyEvent.KEYCODE_W: - return ""; - case KeyEvent.KEYCODE_X: - return ""; - case KeyEvent.KEYCODE_Y: - return ""; - case KeyEvent.KEYCODE_Z: - return ""; - case KeyEvent.KEYCODE_APOSTROPHE: - return "<'>"; - case KeyEvent.KEYCODE_AT: - return "<@>"; - case KeyEvent.KEYCODE_BACK: - return ""; - case KeyEvent.KEYCODE_BACKSLASH: - return "<\\>"; - case KeyEvent.KEYCODE_CALL: - return ""; - case KeyEvent.KEYCODE_CAMERA: - return ""; - case KeyEvent.KEYCODE_CLEAR: - return ""; - case KeyEvent.KEYCODE_COMMA: - return "<,>"; - case KeyEvent.KEYCODE_DEL: - return ""; - case KeyEvent.KEYCODE_DPAD_CENTER: - return ""; - case KeyEvent.KEYCODE_DPAD_DOWN: - return ""; - case KeyEvent.KEYCODE_DPAD_LEFT: - return ""; - case KeyEvent.KEYCODE_DPAD_RIGHT: - return ""; - case KeyEvent.KEYCODE_DPAD_UP: - return ""; - case KeyEvent.KEYCODE_ENDCALL: - return ""; - case KeyEvent.KEYCODE_ENTER: - return ""; - case KeyEvent.KEYCODE_ENVELOPE: - return ""; - case KeyEvent.KEYCODE_EQUALS: - return "<=>"; - case KeyEvent.KEYCODE_EXPLORER: - return ""; - case KeyEvent.KEYCODE_FOCUS: - return ""; - case KeyEvent.KEYCODE_GRAVE: - return ""; - case KeyEvent.KEYCODE_HEADSETHOOK: - return ""; - case KeyEvent.KEYCODE_HOME: - return ""; - case KeyEvent.KEYCODE_LEFT_BRACKET: - return "<(>"; - case KeyEvent.KEYCODE_MENU: - return "

"; - case KeyEvent.KEYCODE_MINUS: - return "<->"; - case KeyEvent.KEYCODE_NOTIFICATION: - return ""; - case KeyEvent.KEYCODE_NUM: - return ""; - case KeyEvent.KEYCODE_PERIOD: - return ""; - case KeyEvent.KEYCODE_PLUS: - return "<+>"; - case KeyEvent.KEYCODE_POUND: - return ""; - case KeyEvent.KEYCODE_POWER: - return ""; - case KeyEvent.KEYCODE_RIGHT_BRACKET: - return "<)>"; - case KeyEvent.KEYCODE_SEMICOLON: - return "<;>"; - case KeyEvent.KEYCODE_SLASH: - return ""; - case KeyEvent.KEYCODE_SOFT_LEFT: - return ""; - case KeyEvent.KEYCODE_SOFT_RIGHT: - return ""; - case KeyEvent.KEYCODE_SPACE: - return ""; - case KeyEvent.KEYCODE_STAR: - return "<*>"; - case KeyEvent.KEYCODE_SYM: - return ""; - case KeyEvent.KEYCODE_TAB: - return ""; - case KeyEvent.KEYCODE_VOLUME_DOWN: - return ""; - case KeyEvent.KEYCODE_VOLUME_UP: - return ""; - case KeyEvent.KEYCODE_UNKNOWN: - default: - return ""; - } - } - - private ZLAndroidKeyUtil() { - } -} diff --git a/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java b/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java index 876991993..001d7cc63 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java @@ -29,7 +29,6 @@ import org.geometerplus.zlibrary.core.view.ZLViewWidget; import org.geometerplus.zlibrary.core.application.ZLApplication; import org.geometerplus.zlibrary.ui.android.library.ZLAndroidActivity; -import org.geometerplus.zlibrary.ui.android.util.ZLAndroidKeyUtil; public class ZLAndroidWidget extends View implements ZLViewWidget, View.OnLongClickListener { private final Paint myPaint = new Paint(); @@ -387,35 +386,33 @@ public class ZLAndroidWidget extends View implements ZLViewWidget, View.OnLongCl return view.onFingerLongPress(myPressedX, myPressedY); } - private String myKeyUnderTracking; + private int myKeyUnderTracking = -1; private long myTrackingStartTime; public boolean onKeyDown(int keyCode, KeyEvent event) { final ZLApplication application = ZLApplication.Instance(); switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_BACK: - case KeyEvent.KEYCODE_ENTER: - case KeyEvent.KEYCODE_DPAD_CENTER: - { - final String keyName = ZLAndroidKeyUtil.getKeyNameByCode(keyCode); - if (myKeyUnderTracking != null) { - if (myKeyUnderTracking.equals(keyName)) { + default: + if (application.hasActionForKey(keyCode, true) || + application.hasActionForKey(keyCode, false)) { + if (myKeyUnderTracking != -1) { + if (myKeyUnderTracking == keyCode) { + return true; + } else { + myKeyUnderTracking = -1; + } + } + if (application.hasActionForKey(keyCode, true)) { + myKeyUnderTracking = keyCode; + myTrackingStartTime = System.currentTimeMillis(); return true; } else { - myKeyUnderTracking = null; + return application.doActionByKey(keyCode, false); } - } - if (application.hasActionForKey(keyName, true)) { - myKeyUnderTracking = keyName; - myTrackingStartTime = System.currentTimeMillis(); - return true; } else { - return application.doActionByKey(keyName, false); + return false; } - } case KeyEvent.KEYCODE_DPAD_LEFT: application.getCurrentView().onTrackballRotated(-1, 0); return true; @@ -428,30 +425,20 @@ public class ZLAndroidWidget extends View implements ZLViewWidget, View.OnLongCl case KeyEvent.KEYCODE_DPAD_UP: application.getCurrentView().onTrackballRotated(0, -1); return true; - default: - return false; } } public boolean onKeyUp(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_BACK: - case KeyEvent.KEYCODE_ENTER: - case KeyEvent.KEYCODE_DPAD_CENTER: - if (myKeyUnderTracking != null) { - final String keyName = ZLAndroidKeyUtil.getKeyNameByCode(keyCode); - if (myKeyUnderTracking.equals(keyName)) { - final boolean longPress = System.currentTimeMillis() > - myTrackingStartTime + ViewConfiguration.getLongPressTimeout(); - ZLApplication.Instance().doActionByKey(keyName, longPress); - } - myKeyUnderTracking = null; - } - return true; - default: - return false; + if (myKeyUnderTracking != -1) { + if (myKeyUnderTracking == keyCode) { + final boolean longPress = System.currentTimeMillis() > + myTrackingStartTime + ViewConfiguration.getLongPressTimeout(); + ZLApplication.Instance().doActionByKey(keyCode, longPress); + } + myKeyUnderTracking = -1; + return true; + } else { + return false; } }