1414#include " ui/keypad_icons.h"
1515#include " keypad.h"
1616
17- constexpr int ROW_LENGTHS [] = {7 , 10 , 9 , 9 , 9 };
18- constexpr int MAX_ROWS = 5 ;
19- constexpr int MAX_COLS = 10 ;
20- constexpr int QWERTY_ROW = 1 ;
21- constexpr int ASDF_ROW = 2 ;
22- constexpr int SPACE_COLS = 3 ;
17+ // the size of PNGs as defined in keypad/build.sh
2318constexpr int IMAGE_SIZE = 30 ;
19+
20+ // PI
2421constexpr double PI = 3.14159 ;
2522
2623// padding size based on character height
@@ -49,74 +46,111 @@ KeypadTheme MODERN_DARK_THEME = {
4946 ._funcKeyHighlight = 0x90a4ae , // Blue Grey 300 (matching accent highlight)
5047};
5148
52- constexpr RawKey KEYS [MAX_ROWS ][MAX_COLS ] = {
53- // Toolbar
54- {
55- {K_CUT , K_CUT , K_CUT , K_CUT },
56- {K_COPY , K_COPY , K_COPY , K_COPY },
57- {K_PASTE , K_PASTE , K_PASTE , K_PASTE },
58- {K_SEARCH , K_SEARCH , K_SEARCH , K_SEARCH },
59- {K_SAVE , K_SAVE , K_SAVE , K_SAVE },
60- {K_RUN , K_RUN , K_RUN , K_RUN },
61- {K_HELP , K_HELP , K_HELP , K_HELP },
62- {K_NULL },
63- {K_NULL },
64- {K_NULL }
65- },
66- // QWERTY
67- {
68- {K_q, K_1 , K_1 , K_Q },
69- {K_w, K_2 , K_2 , K_W },
70- {K_e, K_3 , K_3 , K_E },
71- {K_r, K_4 , K_4 , K_R },
72- {K_t, K_5 , K_5 , K_T },
73- {K_y, K_6 , K_6 , K_Y },
74- {K_u, K_7 , K_7 , K_U },
75- {K_i, K_8 , K_8 , K_I },
76- {K_o, K_9 , K_9 , K_O },
77- {K_p, K_0 , K_0 , K_P }
78- },
79- // ASDF
80- {
81- {K_a, K_COMMA , K_HASH , K_A },
82- {K_s, K_EQUALS , K_SEMICOLON , K_S },
83- {K_d, K_LPAREN , K_QUESTION , K_D },
84- {K_f, K_RPAREN , K_AMPERSAND , K_F },
85- {K_g, K_QUOTE , K_DOLLAR , K_G },
86- {K_h, K_APOSTROPHE , K_EXCLAIM , K_H },
87- {K_j, K_PERIOD , K_AT , K_J },
88- {K_k, K_MINUS , K_SLASH , K_K },
89- {K_l, K_ASTERISK , K_BACKSLASH , K_L },
90- {K_NULL }
91- },
92- // ZXC
93- {
94- {K_TOGGLE , K_TOGGLE , K_TOGGLE , K_TOGGLE },
95- {K_z, K_UNDERSCORE , K_CARET , K_Z },
96- {K_x, K_PLUS , K_LBRACE , K_X },
97- {K_c, K_COLON , K_RBRACE , K_C },
98- {K_v, K_LBRACKET , K_PIPE , K_V },
99- {K_b, K_RBRACKET , K_PERCENT , K_B },
100- {K_n, K_LESS , K_BACKTICK , K_N },
101- {K_m, K_GREATER , K_TILDE , K_M },
102- {K_BACKSPACE , K_BACKSPACE , K_BACKSPACE , K_BACKSPACE },
103- {K_NULL }
104- },
105- // FUNCs, SPACE
106- {
107- {K_LINE_UP , K_PAGE_UP , K_LINE_UP , K_PAGE_UP },
108- {K_LINE_DOWN , K_PAGE_DOWN , K_LINE_DOWN , K_PAGE_DOWN },
109- {K_LPAREN , K_SLASH , K_COMMA , K_LBRACKET },
110- {K_SPACE , K_SPACE , K_SPACE , K_SPACE },
111- {K_RPAREN , K_HASH , K_EQUALS , K_RBRACKET },
112- {K_TAG , K_TAG , K_TAG , K_TAG },
113- {K_ENTER , K_ENTER , K_ENTER , K_ENTER },
114- {K_NULL },
115- {K_NULL },
116- {K_NULL },
117- }
49+ // compact layout for mobile devices in portrait mode
50+ namespace MobileKeypadLayout {
51+ constexpr int ROW_LENGTHS [] = {7 , 10 , 9 , 9 , 9 };
52+ constexpr int MAX_ROWS = 5 ;
53+ constexpr int MAX_COLS = 10 ;
54+ constexpr int QWERTY_ROW = 1 ;
55+ constexpr int ASDF_ROW = 2 ;
56+ constexpr int SPACE_COLS = 3 ;
57+ constexpr RawKey KEYS [MAX_ROWS ][MAX_COLS ] = {
58+ // Toolbar
59+ {
60+ {K_CUT , K_CUT , K_CUT , K_CUT },
61+ {K_COPY , K_COPY , K_COPY , K_COPY },
62+ {K_PASTE , K_PASTE , K_PASTE , K_PASTE },
63+ {K_SEARCH , K_SEARCH , K_SEARCH , K_SEARCH },
64+ {K_SAVE , K_SAVE , K_SAVE , K_SAVE },
65+ {K_RUN , K_RUN , K_RUN , K_RUN },
66+ {K_HELP , K_HELP , K_HELP , K_HELP },
67+ {K_NULL },
68+ {K_NULL },
69+ {K_NULL }
70+ },
71+ // QWERTY
72+ {
73+ {K_q, K_1 , K_1 , K_Q },
74+ {K_w, K_2 , K_2 , K_W },
75+ {K_e, K_3 , K_3 , K_E },
76+ {K_r, K_4 , K_4 , K_R },
77+ {K_t, K_5 , K_5 , K_T },
78+ {K_y, K_6 , K_6 , K_Y },
79+ {K_u, K_7 , K_7 , K_U },
80+ {K_i, K_8 , K_8 , K_I },
81+ {K_o, K_9 , K_9 , K_O },
82+ {K_p, K_0 , K_0 , K_P }
83+ },
84+ // ASDF
85+ {
86+ {K_a, K_COMMA , K_HASH , K_A },
87+ {K_s, K_EQUALS , K_SEMICOLON , K_S },
88+ {K_d, K_LPAREN , K_QUESTION , K_D },
89+ {K_f, K_RPAREN , K_AMPERSAND , K_F },
90+ {K_g, K_QUOTE , K_DOLLAR , K_G },
91+ {K_h, K_APOSTROPHE , K_EXCLAIM , K_H },
92+ {K_j, K_PERIOD , K_AT , K_J },
93+ {K_k, K_MINUS , K_SLASH , K_K },
94+ {K_l, K_ASTERISK , K_BACKSLASH , K_L },
95+ {K_NULL }
96+ },
97+ // ZXC
98+ {
99+ {K_TOGGLE , K_TOGGLE , K_TOGGLE , K_TOGGLE },
100+ {K_z, K_UNDERSCORE , K_CARET , K_Z },
101+ {K_x, K_PLUS , K_LBRACE , K_X },
102+ {K_c, K_COLON , K_RBRACE , K_C },
103+ {K_v, K_LBRACKET , K_PIPE , K_V },
104+ {K_b, K_RBRACKET , K_PERCENT , K_B },
105+ {K_n, K_LESS , K_BACKTICK , K_N },
106+ {K_m, K_GREATER , K_TILDE , K_M },
107+ {K_BACKSPACE , K_BACKSPACE , K_BACKSPACE , K_BACKSPACE },
108+ {K_NULL }
109+ },
110+ // FUNCs, SPACE
111+ {
112+ {K_LINE_UP , K_PAGE_UP , K_LINE_UP , K_PAGE_UP },
113+ {K_LINE_DOWN , K_PAGE_DOWN , K_LINE_DOWN , K_PAGE_DOWN },
114+ {K_LPAREN , K_SLASH , K_COMMA , K_LBRACKET },
115+ {K_SPACE , K_SPACE , K_SPACE , K_SPACE },
116+ {K_RPAREN , K_HASH , K_EQUALS , K_RBRACKET },
117+ {K_TAG , K_TAG , K_TAG , K_TAG },
118+ {K_ENTER , K_ENTER , K_ENTER , K_ENTER },
119+ {K_NULL },
120+ {K_NULL },
121+ {K_NULL },
122+ }
123+ };
124+
125+ struct Impl : public KeypadLayout {
126+ RawKey getRawKey (int row, int col) const override {
127+ return KEYS [row][col];
128+ }
129+
130+ int getMaxRowLength () const override {
131+ return ROW_LENGTHS [QWERTY_ROW ];
132+ }
133+
134+ int getMaxRows () const override {
135+ return MAX_ROWS ;
136+ }
137+
138+ int getRowLength (int row) const override {
139+ return ROW_LENGTHS [row];
140+ };
141+
142+ int getSpaceCols () const override {
143+ return SPACE_COLS ;
144+ }
145+
146+ bool isWideRow (int row) const override {
147+ return row == QWERTY_ROW || row == ASDF_ROW ;
148+ }
149+ };
118150};
119151
152+ KeypadLayout::~KeypadLayout () = default ;
153+
120154//
121155// KeypadImage
122156//
@@ -202,6 +236,7 @@ KeyCode KeypadDrawContext::getKey(RawKey key) const {
202236 case kNumber : keyCode = key._number ; break ;
203237 case kSymbol : keyCode = key._symbol ; break ;
204238 case kSize : keyCode = K_NULL ; break ;
239+ default : keyCode = K_NULL ; break ;
205240 }
206241 return keyCode;
207242}
@@ -414,46 +449,51 @@ Keypad::Keypad(int charWidth, int charHeight, bool toolbar)
414449 _width(0 ),
415450 _height(0 ),
416451 _padding(static_cast <int >(charHeight * PADDING_FACTOR )),
417- _theme(&MODERN_DARK_THEME ),
418- _context(charWidth, charHeight),
419452 _toolbar(toolbar),
420- _pressed(nullptr ) {
453+ _pressed(nullptr ),
454+ _theme(&MODERN_DARK_THEME ),
455+ _context(charWidth, charHeight) {
456+ selectLayout ();
421457 generateKeys ();
422458}
423459
424460void Keypad::generateKeys () {
425461 _keys.clear ();
426462
427- const int rows = _toolbar ? 1 : MAX_ROWS ;
463+ const int rows = _toolbar ? 1 : _layout-> getMaxRows () ;
428464 for (int row = 0 ; row < rows; ++row) {
429- int cols = ROW_LENGTHS [ row] ;
465+ int cols = _layout-> getRowLength ( row) ;
430466 for (int col = 0 ; col < cols; col++) {
431- const RawKey &k = KEYS [ row][ col] ;
467+ const RawKey &k = _layout-> getRawKey ( row, col) ;
432468 if (k._lower != K_NULL ) {
433469 _keys.add (new Key (k));
434470 }
435471 }
436472 }
437473}
438474
475+ void Keypad::selectLayout () {
476+ _layout = std::make_unique<MobileKeypadLayout::Impl>();
477+ }
478+
439479void Keypad::layout (int x, int y, int w, int h) {
440480 _posX = x;
441481 _posY = y;
442482 _width = w;
443483 _height = h;
444484
445485 const int width = _width - _padding;
446- const int keyW = width / ROW_LENGTHS [ QWERTY_ROW ] ;
486+ const int keyW = width / _layout-> getMaxRowLength () ;
447487 const int keyH = _context._charHeight + _padding * 2 ;
448488 const int xStart = _posX + ((w - _width) / 2 );
449- const int rows = _toolbar ? 1 : MAX_ROWS ;
489+ const int rows = _toolbar ? 1 : _layout-> getMaxRows () ;
450490 int yPos = _posY;
451491 int index = 0 ;
452492
453493 for (int row = 0 ; row < rows; ++row) {
454- const int cols = ROW_LENGTHS [ row] ;
494+ const int cols = _layout-> getRowLength ( row) ;
455495 int xPos = xStart;
456- if (row == QWERTY_ROW || row == ASDF_ROW ) {
496+ if (_layout-> isWideRow ( row) ) {
457497 const int rowWidth = keyW * cols;
458498 xPos += (_width - rowWidth) / 2 ;
459499 }
@@ -473,7 +513,7 @@ void Keypad::layout(int x, int y, int w, int h) {
473513 const int numKeys = 2 ;
474514 keyWidth = (_width - ((cols - numKeys) * keyW)) / numKeys;
475515 } else if (key->_key ._lower == K_SPACE ) {
476- keyWidth = (SPACE_COLS * keyW);
516+ keyWidth = (_layout-> getSpaceCols () * keyW);
477517 }
478518 key->_x = xPos;
479519 key->_y = yPos;
@@ -491,7 +531,7 @@ int Keypad::layoutHeight(int screenHeight) {
491531 int charHeight = _context._charHeight ;
492532 int maxHeight = static_cast <int >(screenHeight * MAX_HEIGHT_FACTOR );
493533 int padding = static_cast <int >(charHeight * PADDING_FACTOR );
494- int rows = _toolbar ? 1 : MAX_ROWS ;
534+ int rows = _toolbar ? 1 : _layout-> getMaxRows () ;
495535 int height = rows * ((padding * 2 ) + charHeight);
496536 if (height > maxHeight) {
497537 // h = r(ch + 2p) -> p = (h - r * ch) / (r * 2)
0 commit comments