1414#include " ui/keypad_icons.h"
1515#include " keypad.h"
1616
17- constexpr int maxRows = 5 ;
18- constexpr int maxCols = 10 ;
19- constexpr int defaultPadding = 16 ;
17+ constexpr int MAX_ROWS = 5 ;
18+ constexpr int MAX_COLS = 10 ;
19+ constexpr int NARROW_ROW = 2 ;
20+ constexpr int SPACE_COLS = 3 ;
21+ constexpr int DEFAULT_PADDING = 24 ;
2022constexpr double PI = 3.14159 ;
2123
22- KeypadTheme modernDarkTheme = {
23- ._bg = 0x101114 , // Cool dark slate (true dark with a bluish tint)
24- ._key = 0x1c1e22 , // Cool gray keys
25- ._keyHighlight = 0x2b2e34 , // Slightly brighter for key press
26- ._text = 0xe4e6ea , // Icy white-gray text (bluish white)
27- ._outline = 0x2f3137 , // Subtle cool gray outlines
28- ._funcKeyBg = 0x8e88aa , // Muted lavender-gray (soft cool purple)
29- ._funcKeyHighlight = 0xc6c2dc , // Light lavender highlight
30- ._funcText = 0xffffff , // Crisp white function key text
24+ KeypadTheme MODERN_DARK_THEME = {
25+ ._bg = 0x0d0d0d , // Deep black background
26+ ._key = 0x1a1a1a , // Dark gray keys
27+ ._keyHighlight = 0x333333 , // Slightly lighter for key press
28+ ._text = 0xe0e0e0 , // Soft white text
29+ ._outline = 0x2a2a2a , // Subtle key outlines
30+ ._funcKeyBg = 0x9f7aea , // Soft faint purple (Material Purple 300~400)
31+ ._funcKeyHighlight = 0xd1c4e9 , // Pale lavender for highlight effect
3132};
3233
33- constexpr RawKey letters [][maxCols ] = {
34+ constexpr RawKey LETTERS [][MAX_COLS ] = {
3435 {{K_CUT, K_CUT}, {K_COPY, K_COPY}, {K_PASTE, K_PASTE}, {K_SAVE, K_SAVE}, {K_RUN, K_RUN}, {K_HELP, K_HELP}},
3536 {{K_q, K_Q}, {K_w, K_W}, {K_e, K_E}, {K_r, K_R}, {K_t, K_T}, {K_y, K_Y}, {K_u, K_U}, {K_i, K_I}, {K_o, K_O}, {K_p, K_P}},
3637 {{K_a, K_A}, {K_s, K_S}, {K_d, K_D}, {K_f, K_F}, {K_g, K_G}, {K_h, K_H}, {K_j, K_J}, {K_k, K_K}, {K_l, K_L}},
3738 {{K_SHIFT, K_SHIFT}, {K_z, K_Z}, {K_x, K_X}, {K_c, K_C}, {K_v, K_V}, {K_b, K_B}, {K_n, K_N}, {K_m, K_M}, {K_BACKSPACE, K_BACKSPACE}},
38- {{K_TOGGLE, K_TOGGLE}, {K_SPACE, K_SPACE}, {K_ENTER, K_ENTER}}
39+ {{K_TOGGLE, K_TOGGLE}, {K_LBRACKET, K_LPAREN}, { K_SPACE, K_SPACE}, {K_RBRACKET, K_RPAREN }, {K_ENTER, K_ENTER}}
3940};
4041
41- constexpr RawKey symbols [][maxCols ] = {
42+ constexpr RawKey SYMBOLS [][MAX_COLS ] = {
4243 {{K_CUT, K_CUT}, {K_COPY, K_COPY}, {K_PASTE, K_PASTE}, {K_SAVE, K_SAVE}, {K_RUN, K_RUN}, {K_HELP, K_HELP}},
4344 {{K_1, K_EXCLAIM}, {K_2, K_AT}, {K_3, K_HASH}, {K_4, K_DOLLAR}, {K_5, K_PERCENT}, {K_6, K_CARET}, {K_7, K_AMPERSAND}, {K_8, K_ASTERISK}, {K_9, K_LPAREN}, {K_0, K_RPAREN}},
44- {{K_BACKTICK, K_TILDE}, {K_MINUS, K_UNDERSCORE}, {K_EQUALS, K_PLUS}, {K_LBRACKET, K_LBRACE}, {K_RBRACKET, K_RBRACE}, {K_BACKSLASH, K_PIPE}, {K_SEMICOLON, K_COLON}, {K_LPAREN , K_QUOTE}, {K_RPAREN, K_COMMA }},
45- {{K_SHIFT, K_SHIFT}, {K_LESS, K_COMMA}, {K_GREATER, K_PERIOD}, {K_QUESTION, K_SLASH}, {K_SEMICOLON, K_COLON }, {K_APOSTROPHE, K_QUOTE }, {K_LBRACKET, K_LBRACE }, {K_RBRACKET, K_RBRACE }, {K_BACKSPACE, K_BACKSPACE}},
46- {{K_TOGGLE, K_TOGGLE}, {K_SPACE, K_SPACE}, {K_ENTER, K_ENTER}}
45+ {{K_BACKTICK, K_TILDE}, {K_MINUS, K_UNDERSCORE}, {K_EQUALS, K_PLUS}, {K_LBRACKET, K_LBRACE}, {K_RBRACKET, K_RBRACE}, {K_BACKSLASH, K_PIPE}, {K_SEMICOLON, K_COLON}, {K_APOSTROPHE , K_QUOTE}, {K_HASH, K_EXT1 }},
46+ {{K_SHIFT, K_SHIFT}, {K_LESS, K_COMMA}, {K_GREATER, K_PERIOD}, {K_QUESTION, K_SLASH}, {K_PLUS, K_EXT2 }, {K_ASTERISK, K_EXT3 }, {K_LPAREN, K_EXT4 }, {K_RPAREN, K_EXT5 }, {K_BACKSPACE, K_BACKSPACE}},
47+ {{K_TOGGLE, K_TOGGLE}, {K_LBRACKET, K_LPAREN}, { K_SPACE, K_SPACE}, {K_RBRACKET, K_RPAREN }, {K_ENTER, K_ENTER}}
4748};
4849
49- constexpr int rowLengths[][5 ] = {
50- {6 , 10 , 9 , 9 , 3 }, // letters
51- {6 , 10 , 9 , 9 , 3 }, // symbols
52- };
53-
54- constexpr int rowCharLengths[][5 ] = {
55- {12 , 10 , 9 , 12 , 14 },// letters
56- {12 , 10 , 9 , 12 , 14 },// letters
50+ constexpr int ROW_LENGTHS[][5 ] = {
51+ {6 , 10 , 9 , 9 , 7 }, // letters
52+ {6 , 10 , 9 , 9 , 7 }, // symbols
5753};
5854
5955//
@@ -104,20 +100,16 @@ KeypadDrawContext::KeypadDrawContext(int charWidth, int charHeight) :
104100 !_searchImage.decode (img_search, img_search_len) ||
105101 !_shiftImage.decode (img_keyboard_shift, img_keyboard_shift_len) ||
106102 !_toggleImage.decode (img_keyboard, img_keyboard_len)) {
107- deviceLog (_cutImage.getLastError ());
103+ deviceLog (" %s " , _cutImage.getLastError ());
108104 }
109105}
110106
111107void KeypadDrawContext::toggleShift () {
112108 _shiftActive = !_shiftActive;
113109}
114110
115- bool KeypadDrawContext::useShift (bool specialKey) {
116- bool useShift = _shiftActive ^ _capsLockActive;
117- if (_shiftActive && !specialKey) {
118- _shiftActive = false ;
119- }
120- return useShift;
111+ bool KeypadDrawContext::useShift () const {
112+ return _shiftActive ^ _capsLockActive;
121113}
122114
123115const KeypadImage *KeypadDrawContext::getImage (const KeyCode keycode) const {
@@ -147,12 +139,12 @@ Key::Key(const RawKey &k) :
147139 _alt(k._shifted) {
148140 _pressed = false ;
149141 _number = isNumber (k._normal );
150- _printable = isPrintable (k._normal );
142+ _printable = isPrintable (k._normal ) || isExtended (k. _normal ) ;
151143}
152144
153145int Key::color (const KeypadTheme *theme, bool shiftActive) const {
154146 int result;
155- if (_pressed || (( _key == K_SHIFT) && shiftActive) ) {
147+ if (( _key == K_SHIFT) && shiftActive) {
156148 result = !_printable ? theme->_funcKeyHighlight : theme->_keyHighlight ;
157149 } else if (_number) {
158150 result = theme->_funcKeyHighlight ;
@@ -162,6 +154,22 @@ int Key::color(const KeypadTheme *theme, bool shiftActive) const {
162154 return result;
163155}
164156
157+ char Key::getKey (bool useShift) const {
158+ char result;
159+ KeyCode keyCode = useShift ? _alt : _key;
160+ switch (keyCode) {
161+ case K_EXT1: result = 164 ; break ;
162+ case K_EXT2: result = 172 ; break ;
163+ case K_EXT3: result = 182 ; break ;
164+ case K_EXT4: result = 222 ; break ;
165+ case K_EXT5: result = 223 ; break ;
166+ default :
167+ result = keyCode;
168+ break ;
169+ }
170+ return result;
171+ }
172+
165173void Key::draw (const KeypadTheme *theme, const KeypadDrawContext *context) const {
166174 int rc = 5 ;
167175 int pad = 2 ;
@@ -177,10 +185,20 @@ void Key::draw(const KeypadTheme *theme, const KeypadDrawContext *context) const
177185 int ycB = by - rc; // y center for bottom arcs
178186
179187 // Set background color
180- maSetColor (_printable ? theme->_key : theme->_funcKeyBg );
181- maFillRect (_x, _y, _w, _h);
188+ if (_printable) {
189+ maSetColor (theme->_key );
190+ maFillRect (_x, _y, _w, _h);
191+ } else {
192+ maSetColor (theme->_funcKeyBg );
193+ maFillRect (_x + 1 , _y + 1 , _w - 2 , _h - 2 );
194+ }
182195
183196 if (_printable || _pressed) {
197+ if (_printable && _pressed) {
198+ maSetColor (theme->_outline );
199+ maFillRect (_x + 4 , _y + 4 , _w - 8 , _h - 8 );
200+ }
201+
184202 maSetColor (_printable ? theme->_keyHighlight : theme->_funcKeyHighlight );
185203
186204 // Draw edges (excluding the rounded corners)
@@ -196,7 +214,7 @@ void Key::draw(const KeypadTheme *theme, const KeypadDrawContext *context) const
196214 maArc (xcR, ycT, rc, PI * 3 / 2 , 0 , aspect); // Top-right corner
197215 maArc (xcR, ycB, rc, 0 , PI / 2 , aspect); // Bottom-right corner
198216 maArc (xcL, ycB, rc, PI / 2 , PI, aspect); // Bottom-left corner
199- }
217+ }
200218
201219 if (_printable) {
202220 bool useShift = context->_shiftActive ^ context->_capsLockActive ;
@@ -205,6 +223,9 @@ void Key::draw(const KeypadTheme *theme, const KeypadDrawContext *context) const
205223 int yOffset = (_h - context->_charHeight ) / 2 ;
206224 int textX = _x + xOffset;
207225 int textY = _y + yOffset;
226+ if (isExtended (useShift ? _alt : _key)) {
227+ key[0 ] = getKey (useShift);
228+ }
208229 maSetColor (color (theme, context->_shiftActive ));
209230 maDrawText (textX, textY, key, 1 );
210231 } else {
@@ -222,7 +243,7 @@ bool Key::inside(int x, int y) const {
222243 y <= _y + _h);
223244}
224245
225- void Key::onClick (bool useShift) {
246+ void Key::onClick (bool useShift) const {
226247 auto *event = new MAEvent ();
227248 event->type = EVENT_TYPE_KEY_PRESSED;
228249 event->nativeKey = 0 ;
@@ -258,7 +279,7 @@ void Key::onClick(bool useShift) {
258279 event->key = SB_KEY_F (1 );
259280 break ;
260281 default :
261- event->key = _key ;
282+ event->key = getKey (useShift) ;
262283 break ;
263284 }
264285 maPushEvent (event);
@@ -273,30 +294,30 @@ Keypad::Keypad(int charWidth, int charHeight)
273294 _width(0 ),
274295 _height(0 ),
275296 _context(charWidth, charHeight),
276- _theme(&modernDarkTheme ),
297+ _theme(&MODERN_DARK_THEME ),
277298 _currentLayout(LayoutLetters) {
278299 generateKeys ();
279300}
280301
281302int Keypad::outerHeight (int charHeight) {
282- return maxRows * ((defaultPadding * 2 ) + charHeight);
303+ return MAX_ROWS * ((DEFAULT_PADDING * 2 ) + charHeight);
283304}
284305
285306void Keypad::generateKeys () {
286307 _keys.clear ();
287308
288- const RawKey (*activeLayout)[maxCols ];
309+ const RawKey (*activeLayout)[MAX_COLS ];
289310 switch (_currentLayout) {
290311 case LayoutLetters:
291- activeLayout = letters ;
312+ activeLayout = LETTERS ;
292313 break ;
293314 default :
294- activeLayout = symbols ;
315+ activeLayout = SYMBOLS ;
295316 break ;
296317 }
297318
298- for (int row = 0 ; row < maxRows ; ++row) {
299- int cols = rowLengths [_currentLayout][row];
319+ for (int row = 0 ; row < MAX_ROWS ; ++row) {
320+ int cols = ROW_LENGTHS [_currentLayout][row];
300321 for (int col = 0 ; col < cols; col++) {
301322 const RawKey &k = activeLayout[row][col];
302323 if (k._normal != K_NULL) {
@@ -316,27 +337,27 @@ void Keypad::layout(int x, int y, int w, int h) {
316337 const int charHeight = _context._charHeight ;
317338
318339 // start with optimum padding, then reduce to fit width
319- int padding = defaultPadding ;
320- int width = maxCols * (charWidth + (padding * 2 ));
340+ int padding = DEFAULT_PADDING ;
341+ int width = MAX_COLS * (charWidth + (padding * 2 ));
321342
322343 while (width > w && padding > 0 ) {
323- padding-- ;
324- width = maxCols * (charWidth + (padding * 2 ));
344+ padding -= 2 ;
345+ width = MAX_COLS * (charWidth + (padding * 2 ));
325346 }
347+ padding *= 2 ;
326348
327- int keyW = charWidth + (padding * 2 );
328- int keyH = charHeight + (padding * 2 );
349+ int keyW = charWidth + (padding);
350+ int keyH = charHeight + (padding);
329351 int xStart = _posX + ((w - width) / 2 );
330352 int yPos = _posY;
331353 int index = 0 ;
354+ int boardWidth = (MAX_COLS * charWidth) + (MAX_COLS * padding);
332355
333- for (int row = 0 ; row < maxRows; ++row) {
334- int cols = rowLengths[_currentLayout][row];
335- int chars = rowCharLengths[_currentLayout][row];
356+ for (int row = 0 ; row < MAX_ROWS; ++row) {
357+ int cols = ROW_LENGTHS[_currentLayout][row];
336358 int xPos = xStart;
337- if (cols < maxCols) {
338- // center narrow row
339- int rowWidth = (chars * charWidth) + (cols * padding * 2 );
359+ if (row == NARROW_ROW) {
360+ int rowWidth = (cols * charWidth) + (cols * padding);
340361 if (rowWidth > width) {
341362 xPos -= (rowWidth - width) / 2 ;
342363 } else {
@@ -350,11 +371,18 @@ void Keypad::layout(int x, int y, int w, int h) {
350371 Key *key = _keys[index++];
351372 int length = key->_printable ? 1 : 2 ;
352373 int keyWidth = keyW;
353- if (key->_key == K_SPACE) {
354- length = 12 ;
355- }
356- if (length > 1 ) {
357- keyWidth = (length * charWidth) + (padding * 2 );
374+ if (row == 0 ) {
375+ keyWidth = (boardWidth / cols);
376+ if (col < 2 || col > 3 ) {
377+ keyWidth += 1 ;
378+ }
379+ } else if (!key->_printable ) {
380+ int numKeys = 2 ;
381+ keyWidth = (boardWidth - ((cols - numKeys) * keyW)) / numKeys;
382+ } else if (key->_key == K_SPACE) {
383+ keyWidth = (SPACE_COLS * keyW);
384+ } else if (length > 1 ) {
385+ keyWidth = (length * charWidth) + (padding);
358386 }
359387 key->_x = xPos;
360388 key->_y = yPos;
@@ -380,7 +408,7 @@ void Keypad::clicked(int x, int y, bool pressed) {
380408 layout (_posX, _posY, _width, _height);
381409 break ;
382410 } else {
383- key->onClick (_context.useShift (!key-> _printable ));
411+ key->onClick (_context.useShift ());
384412 }
385413 break ;
386414 }
@@ -423,7 +451,7 @@ void KeypadInput::draw(int x, int y, int w, int h, int chw) {
423451 if (_keypad) {
424452 _keypad->draw ();
425453 } else {
426- maSetColor (modernDarkTheme ._bg );
454+ maSetColor (MODERN_DARK_THEME ._bg );
427455 maFillRect (x, y, _width, _height);
428456 }
429457}
0 commit comments