PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Src/ime/TabletKeymap.h

https://github.com/hwti/LunaSysMgr
C Header | 391 lines | 253 code | 68 blank | 70 comment | 45 complexity | cdf37b012343660280df427d3fc709e2 MD5 | raw file
  1. /* @@@LICENSE
  2. *
  3. * Copyright (c) 2010-2012 Hewlett-Packard Development Company, L.P.
  4. * 2012 Måns Andersson <mail@mansandersson.se>
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * LICENSE@@@ */
  19. /*
  20. * Tablet Keyboard - Keymaps - Layout Families and more...
  21. * --The guide--
  22. *
  23. * This is a somewhat complete guide into how to set up a new keyboard
  24. * layout for Luna Sys Manager. Please help out and fill out the guide if
  25. * something is missing.
  26. *
  27. * --Wordlist
  28. * Autocorrect Language - the language used by the autocorrection service. An
  29. * autocorrect language does not imply that the keyboard
  30. * language is the same.
  31. * autocorrect language != keyboard language
  32. * Layout Family - a specific keyboard language, e.g. English, French
  33. * Keymap - a keyboard layout for a layout family. One layout
  34. * family can have many keymaps but not the other way
  35. * around.
  36. * Keyboard Language - see layout family
  37. *
  38. * --Files and their responsibilities
  39. * TabletKeymap.cpp/.h holds the actual keyboard layouts and keyboard languages
  40. * TabletKeyboard.cpp/.h handles drawing the keyboard and interfacing with other components
  41. * VirtualKeyboard.cpp/.h parent class of TabletKeyboard, more or less just an interface
  42. * VirtualKeyboardPreferences.cpp/.h handles storage of keyboard preferences, reading them and knowing which layout to display when
  43. *
  44. * --Creating your own keyboard layout
  45. * 1. All layout files are stored in the tabletkeymaps folder
  46. * 2. If your layout is part of a new layout family, copy any of the current
  47. * keymap files.
  48. * 3. Open the file and edit the keymap (will not go into details about this
  49. * step since it's quite straight forward). Make sure you always keep 12
  50. * keys per row. Add and remove NOKEY-definitions as needed.
  51. * 4. Register your new layout family by including the file you've created
  52. * in TabletKeymap.cpp. Make sure to add the layouts in alphabetical
  53. * descending order, otherwise they won't appear in ascending order
  54. * in the regional settings app.
  55. * 5. If you are using some obscure character that is not recognize yet,
  56. * you may add it to the function UKeyIsCharacter in this file.
  57. * 5. Compile and happy typing! :-)
  58. */
  59. #ifndef TABLET_KEYMAP_H
  60. #define TABLET_KEYMAP_H
  61. #include <palmimedefines.h>
  62. #include <qlist.h>
  63. #include <qrect.h>
  64. #include <qstring.h>
  65. #include "PalmIMEHelpers.h"
  66. // Whether the keyboard should have resize handles in the top left & right corners
  67. #define RESIZE_HANDLES 0
  68. class QFile;
  69. namespace Tablet_Keyboard {
  70. // We're back to using Qt::Key definitions. This typedef allows us to change our mind...
  71. typedef Qt::Key UKey;
  72. // Constants defined to make keyboard definitions more readable (and more stable as we change the values they point to...)
  73. // Note that except for the Euro sign, they are only meant to represent a key and are never used as unicode characters for display purposes...
  74. const UKey cKey_None = UKey(0); // nothing...
  75. const UKey cKey_Euro = UKey(0x20ac); // unicode "EURO SIGN" €
  76. const UKey cKey_SymbolPicker = Qt::Key_Control; // not used in virtual keyboard: that's to trigger Webkit's symbol picker
  77. const UKey cKey_Symbol = Qt::Key_Alt; // "new" virtual keyboard symbol key
  78. // special keys not mapping to already existing Qt keys: use unique value used only internaly.
  79. const UKey cKey_ToggleSuggestions = UKey(0x01200200);
  80. const UKey cKey_ToggleLanguage = UKey(0x01200201);
  81. const UKey cKey_SwitchToQwerty = UKey(0x01200202);
  82. const UKey cKey_SwitchToAzerty = UKey(0x01200203);
  83. const UKey cKey_SwitchToQwertz = UKey(0x01200204);
  84. const UKey cKey_ShowXT9Regions = UKey(0x01200209);
  85. const UKey cKey_CreateDefaultKeyboards = UKey(0x0120020D);
  86. const UKey cKey_ClearDefaultKeyboards = UKey(0x0120020E);
  87. const UKey cKey_Hide = UKey(0x0120020F);
  88. const UKey cKey_ShowKeymapRegions = UKey(0x01200210);
  89. const UKey cKey_StartStopRecording = UKey(0x01200211);
  90. const UKey cKey_Resize_Tiny = UKey(0x01200212);
  91. const UKey cKey_Resize_Small = UKey(0x01200213);
  92. const UKey cKey_Resize_Default = UKey(0x01200214);
  93. const UKey cKey_Resize_Large = UKey(0x01200215);
  94. const UKey cKey_Resize_First = cKey_Resize_Tiny;
  95. const UKey cKey_Resize_Last = cKey_Resize_Large;
  96. const UKey cKey_ToggleSoundFeedback = UKey(0x01200216);
  97. const UKey cKey_ResizeHandle = UKey(0x01200217);
  98. const UKey cKey_Trackball = UKey(0x01200218);
  99. // Keys that correspond to some text entry (label & entered text are equal)
  100. const UKey cKey_DotCom = UKey(0x01200300);
  101. const UKey cKey_DotOrg = UKey(0x01200301);
  102. const UKey cKey_DotNet = UKey(0x01200302);
  103. const UKey cKey_DotEdu = UKey(0x01200303);
  104. const UKey cKey_DotGov = UKey(0x01200304);
  105. const UKey cKey_DotCoUK = UKey(0x01200305);
  106. const UKey cKey_DotDe = UKey(0x01200306);
  107. const UKey cKey_DotFr = UKey(0x01200307);
  108. const UKey cKey_DotUs = UKey(0x01200308);
  109. const UKey cKey_WWW = UKey(0x01200309);
  110. const UKey cKey_HTTPColonSlashSlash = UKey(0x0120030A);
  111. const UKey cKey_HTTPSColonSlashSlash = UKey(0x0120030B);
  112. const UKey cKey_Emoticon_Frown = UKey(0x0120030C);
  113. const UKey cKey_Emoticon_Cry = UKey(0x0120030D);
  114. const UKey cKey_Emoticon_Smile = UKey(0x0120030E);
  115. const UKey cKey_Emoticon_Wink = UKey(0x0120030F);
  116. const UKey cKey_Emoticon_Yuck = UKey(0x01200310);
  117. const UKey cKey_Emoticon_Gasp = UKey(0x01200311);
  118. const UKey cKey_Emoticon_Heart = UKey(0x01200312);
  119. const UKey cKey_DotSe = UKey(0x01200313);
  120. const UKey cKey_DotDk = UKey(0x01200314);
  121. const UKey cKey_DotNo = UKey(0x01200315);
  122. // Keys used for keyboard/language selections
  123. const UKey cKey_KeyboardComboChoice_First = UKey(0x01200400);
  124. const UKey cKey_KeyboardComboChoice_Last = UKey(0x012004ff);
  125. // helper: can a UKey code be used as a Qt::Key and/or as an acceptable unicode character?
  126. inline bool UKeyIsUnicodeQtKey(UKey ukey) { return ukey >= ' ' && ukey < Qt::Key_Escape; }
  127. inline bool UKeyIsFunctionKey(UKey ukey) { return ukey >= Qt::Key_Escape; }
  128. inline bool UKeyIsTextShortcutKey(UKey ukey) { return ukey >= 0x01200300 && ukey <= 0x012003FF; }
  129. inline bool UKeyIsKeyboardComboKey(UKey ukey) { return ukey >= cKey_KeyboardComboChoice_First && ukey <= cKey_KeyboardComboChoice_Last;}
  130. inline bool UKeyIsKeyboardSizeKey(UKey ukey) { return ukey >= cKey_Resize_First && ukey <= cKey_Resize_Last;}
  131. inline bool UKeyIsEmoticonKey(UKey ukey) { return ukey >= cKey_Emoticon_Frown && ukey <= cKey_Emoticon_Heart; }
  132. inline bool UKeyIsCharacter(UKey ukey) { return (ukey >= Qt::Key_A && ukey <= Qt::Key_Z) // A-Z
  133. || (ukey >= UKey(0x0410) && ukey <= UKey(0x42F)) || ukey == UKey(0x0401) // Russian keys
  134. || (ukey >= Qt::Key_Agrave && ukey <= Qt::Key_ydiaeresis && ukey != Qt::Key_multiply && ukey != Qt::Key_division && ukey != Qt::Key_ssharp); } // the rest ;-)
  135. inline bool UKeyIsNumber(UKey ukey) { return (ukey >= Qt::Key_0 && ukey <= Qt::Key_9); }
  136. const QPoint cOutside(-1, -1); // special value meaning representing "outside of keyboard", or "no key".
  137. class TabletKeymap : public Mapper_IF
  138. {
  139. public:
  140. enum {
  141. cKeymapRows = 5,
  142. cKeymapColumns = 14,
  143. };
  144. enum EShiftMode
  145. {
  146. eShiftMode_Undefined = -1,
  147. eShiftMode_Off = 0,
  148. eShiftMode_Once,
  149. eShiftMode_CapsLock
  150. };
  151. enum ESymbolMode
  152. {
  153. eSymbolMode_Undefined = -1,
  154. eSymbolMode_Off = 0,
  155. eSymbolMode_Lock
  156. };
  157. enum ELayoutPage {
  158. eLayoutPage_plain = 0,
  159. eLayoutPage_Alternate,
  160. eLayoutPageCount = 2
  161. };
  162. enum ETabAction {
  163. eTabAction_Tab = 0,
  164. eTabAction_Next,
  165. eTabAction_Previous
  166. };
  167. typedef const UKey constUKeyArray[];
  168. struct WKey {
  169. void set(UKey key, float weight = 1, const UKey * extended = NULL)
  170. {
  171. m_weight = weight, m_key = key, m_altkey = key, m_extended = extended;
  172. }
  173. void set(UKey key, UKey altkey, float weight = 1, const UKey * extended = NULL)
  174. {
  175. m_weight = weight, m_key = key, m_altkey = altkey, m_extended = extended;
  176. }
  177. void hide()
  178. {
  179. m_weight = 0, m_key = cKey_None, m_altkey = cKey_None, m_extended = NULL;
  180. }
  181. bool operator !=(const WKey & rhs)
  182. {
  183. return m_weight != rhs.m_weight || m_key != rhs.m_weight || m_altkey != rhs.m_altkey || m_extended != rhs.m_extended;
  184. }
  185. float m_weight;
  186. UKey m_key;
  187. UKey m_altkey;
  188. const UKey * m_extended;
  189. };
  190. typedef WKey LayoutRow[cKeymapColumns];
  191. typedef LayoutRow Layout[cKeymapRows];
  192. typedef float HLimits[cKeymapRows][cKeymapColumns];
  193. typedef float VLimits[cKeymapRows];
  194. struct Keymap;
  195. struct LayoutFamily {
  196. LayoutFamily(const char * name, const char * language);
  197. const char * m_name;
  198. const char * m_language;
  199. // registration of key layouts
  200. Keymap * m_currentKeymap;
  201. Keymap * m_firstKeymap;
  202. unsigned int m_numKeymaps;
  203. Keymap * findKeymap(const char * name, bool returnNullNotDefaultIfNotFound = true);
  204. bool setCurrentKeymap(const char * keymap) { Keymap* kmap = findKeymap(keymap); if (kmap != NULL) m_currentKeymap = kmap; else return false; return true; }
  205. // self registration of layout families. Start with first, iterate until nextFamily is null.
  206. const LayoutFamily * m_nextFamily;
  207. static const LayoutFamily * findLayoutFamily(const char * name, bool returnNullNotDefaultIfNotFound = true);
  208. static const LayoutFamily * s_firstFamily ;
  209. };
  210. struct Keymap {
  211. Keymap(LayoutFamily * layoutFamily, const char * name, uint16_t primaryID, uint16_t secondaryID,
  212. const char * symbolKeyLabel, const char * noLanguageKeyLabel,
  213. int tabX, int symbolX, int returnX, int returnY, bool needNumbLock, Layout & layout,
  214. LayoutRow & defaultBottomRow, LayoutRow & urlBottomRow, LayoutRow & emailBottomRow);
  215. Keymap * m_nextKeymap;
  216. const WKey & wkey(int x, int y) const { return m_layout[y][x]; }
  217. UKey key(int x, int y, ELayoutPage page) const { return (page == eLayoutPage_plain) ? wkey(x, y).m_key : wkey(x, y).m_altkey; }
  218. float weight(int x, int y) const { return wkey(x, y).m_weight; }
  219. const char * m_name;
  220. uint16_t m_primaryID;
  221. uint16_t m_secondaryID;
  222. const char * m_symbolKeyLabel;
  223. const char * m_noLanguageKeyLabel;
  224. int m_tab_x; // x of tab key on last row
  225. int m_symbol_x; // x of option key on last row
  226. int m_return_x; // x of return key
  227. int m_return_y; // y of return key
  228. bool m_needNumLock;
  229. int m_cachedGlyphsCount;
  230. Layout & m_layout;
  231. LayoutRow & m_defaultBottomRow;
  232. LayoutRow & m_urlBottomRow;
  233. LayoutRow & m_emailBottomRow;
  234. };
  235. TabletKeymap();
  236. void setRect(int x, int y, int w, int h) { m_rect.setRect(x, y, w, h); m_limitsDirty = true; }
  237. const QRect & rect() const { return m_rect; }
  238. void setRowHeight(int rowIndex, int height);
  239. QPoint pointToKeyboard(const QPoint & location, bool useDiamondOptimizations = true); // convert screen coordinate in keyboard coordinate
  240. int keyboardToKeyZone(QPoint keyboardCoordinate, QRect & outZone); // convert keyboard coordinate to rect of the key
  241. // The following functions that return a bool return true when the layout effectively changed (and you probably need to update your display)
  242. bool setLayoutFamily(const LayoutFamily * layoutFamily);
  243. bool setKeymap(const std::string & keymap);
  244. void setAutoCorrectLanguage(const std::string & language);
  245. const LayoutFamily* layoutFamily() const { return m_layoutFamily; }
  246. void keyboardCombosChanged(); // called when available keyboard combos change
  247. QList<const char *> getLayoutList();
  248. const char * getLayoutDefaultLanguage(const char * layoutName);
  249. void setHasMoreThanOneLayoutFamily(bool has);
  250. bool setShiftMode(EShiftMode shiftMode);
  251. EShiftMode shiftMode() const { return m_shiftMode; }
  252. bool setSymbolMode(ESymbolMode symbolMode);
  253. ESymbolMode symbolMode() const { return m_symbolMode; }
  254. bool setShiftKeyDown(bool shiftKeyDown);
  255. bool setSymbolKeyDown(bool symbolKeyDown);
  256. bool setEditorState(const PalmIME::EditorState & editorState);
  257. const PalmIME::EditorState & editorState() const { return m_editorState; }
  258. bool setAutoCap(bool autoCap);
  259. bool isSymbolActive() const { return ((m_symbolMode == eSymbolMode_Lock) ? 1 : 0) + (m_symbolDown ? 1 : 0) == 1; }
  260. bool isShiftActive() const { return ((m_shiftMode == eShiftMode_Once) ? 1 : 0) + (m_shiftDown ? 1 : 0) == 1; }
  261. bool isShiftDown() const { return m_shiftDown; }
  262. bool isSymbolDown() const { return m_symbolDown; }
  263. bool isCapsLocked() const { return m_shiftMode == eShiftMode_CapsLock; }
  264. bool isCapActive() const { return (m_shiftDown && m_shiftMode == eShiftMode_Off) || (!m_shiftDown && m_shiftMode != eShiftMode_Off); }
  265. bool isCapOrAutoCapActive() const { return m_autoCap || isCapActive(); }
  266. bool isAutoCapActive() const { return m_autoCap; }
  267. UKey map(QPoint p) { return map(p.x(), p.y()); }
  268. UKey map(int x, int y);
  269. UKey map(QPoint p, ELayoutPage page) { return map(p.x(), p.y(), page); }
  270. UKey map(int x, int y, ELayoutPage page) { return isValidLocation(x, y) ? m_layoutFamily->m_currentKeymap->key(x, y, page) : cKey_None; }
  271. quint32 getPage() const { return m_layoutPage; }
  272. ETabAction tabAction() const;
  273. const char * layoutName() { return m_layoutFamily->m_name; }
  274. QString autoCorrectLanguage() { return m_autoCorrectLanguage; }
  275. uint16_t primaryKeyboardID() { return m_layoutFamily->m_currentKeymap->m_primaryID; }
  276. uint16_t secondaryKeyboardID() { return m_layoutFamily->m_currentKeymap->m_secondaryID; }
  277. bool generateKeyboardLayout(const char * fullPath);
  278. std::string getKeyboardLayoutAsJson();
  279. int getCachedGlyphsCount() const { return m_layoutFamily->m_currentKeymap->m_cachedGlyphsCount; }
  280. void incCachedGlyphs() { const_cast<Keymap *>(m_layoutFamily->m_currentKeymap)->m_cachedGlyphsCount++; }
  281. void resetCachedGlyphsCount() { if (m_layoutFamily->m_currentKeymap->m_cachedGlyphsCount > 1) const_cast<Keymap *>(m_layoutFamily->m_currentKeymap)->m_cachedGlyphsCount = 1; }
  282. static inline bool isValidLocation(int x, int y) { return x >= 0 && x < cKeymapColumns && y >= 0 && y < cKeymapRows; }
  283. static inline bool isValidLocation(QPoint location) { return isValidLocation(location.x(), location.y()); }
  284. const UKey * getExtendedChars(QPoint keyboardCoordinate); // MAY RETURN NULL!
  285. QString getKeyDisplayString(UKey key, bool logging = false); // for display purposes. NOT ALL KEYS can be handled that way! "logging" gives you more...
  286. bool showEmoticonsAsGraphics() { return m_editorState.flags & PalmIME::FieldFlags_Emoticons; }
  287. int updateLimits();
  288. // Mapper_IF implementation
  289. std::string pointToKeys(const QPoint & point);
  290. private:
  291. EShiftMode m_shiftMode;
  292. ESymbolMode m_symbolMode;
  293. bool m_shiftDown;
  294. bool m_symbolDown;
  295. bool m_autoCap;
  296. bool m_numLock; // in number & phone fields, when numbers need shift.
  297. PalmIME::EditorState m_editorState;
  298. LayoutFamily * m_layoutFamily;
  299. ELayoutPage m_layoutPage;
  300. QRect m_rect;
  301. int m_rowHeight[cKeymapRows];
  302. HLimits m_hlimits;
  303. VLimits m_vlimits;
  304. bool m_limitsDirty;
  305. int m_limitsVersion;
  306. bool m_hasMoreThanOneLayoutFamily;
  307. QString m_languageName;
  308. QString m_autoCorrectLanguage;
  309. QString m_custom_Enter;
  310. QString m_localized__Enter;
  311. QString m_localized__Tab;
  312. QString m_localized__Next;
  313. QString m_localized__Previous;
  314. bool updateMapping(); // true if layout changed
  315. bool updateLanguageKey(LayoutRow * bottomRow = NULL);
  316. QString getLanguageDisplayName(const LayoutFamily * layoutFamily);
  317. int xCenterOfKey(int touchX, int x, int y, float weight);
  318. int yCenterOfRow(int y, UKey key);
  319. QString getXKeys(int locX, int k_x, int k_y);
  320. };
  321. const QPoint cResizeHandleCoord(TabletKeymap::cKeymapColumns, 0);
  322. }; // namespace TabletKeyboard
  323. #endif // TABLET_KEYMAP_H