Skip to content

Commit 05e366d

Browse files
committed
UI: experimental keypad to replace android keypad
1 parent da9d224 commit 05e366d

File tree

6 files changed

+218
-361
lines changed

6 files changed

+218
-361
lines changed

images/keypad/build.sh

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
11
#!/bin/bash
22

33
declare -a IMAGE_FILES=(\
4-
"proicons-cut.png"\
5-
"proicons-copy.png"\
6-
"proicons-clipboard-paste.png"\
7-
"proicons-save.png"\
8-
"proicons-bug-play.png"\
9-
"proicons-book-info-2.png"\
10-
"proicons-backspace.png"\
11-
"proicons-arrow-enter.png"\
12-
"proicons-search.png"\
4+
"cut"\
5+
"copy"\
6+
"clipboard-paste"\
7+
"save"\
8+
"bug-play"\
9+
"book-info-2"\
10+
"backspace"\
11+
"arrow-enter"\
12+
"search"\
13+
"keyboard-shift"\
14+
"keyboard"\
1315
)
1416

1517
echo "#pragma once" > keypad_icons.h
1618
echo "// https://procode-software.github.io/proicons/icons" >> keypad_icons.h
1719
for imageFile in "${IMAGE_FILES[@]}"
1820
do
19-
name=`ls -1 ${imageFile} | sed -e 's/proicons-/img-/' | sed -e 's/\.png//'`
20-
xxd -n ${name} -i ${imageFile} >> keypad_icons.h
21+
curl -sLO https://raw.githubusercontent.com/ProCode-Software/proicons/refs/heads/main/icons/svg/${imageFile}.svg
22+
23+
# set width, height, and fill
24+
sed -i 's/width="24" height="24"/width="30" height="30"/' ${imageFile}.svg
25+
sed -i 's/currentColor/#004455/' ${imageFile}.svg
26+
27+
# convert svg to png using ImageMagick
28+
convert -background none ${imageFile}.svg ${imageFile}.png
29+
30+
# convert png to byte array
31+
xxd -n img_${imageFile} -i proicons-${imageFile}.png >> keypad_icons.h
2132
done
2233

2334
cp keypad_icons.h ../../src/ui

src/ui/image_codec.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,44 @@
99

1010
#include "image_codec.h"
1111
#include "lib/lodepng/lodepng.h"
12-
#include <cstdlib>
13-
#include <cstring>
1412

1513
static char g_last_error[256] = {0};
1614

1715
static float lerp(float a, float b, float t) {
1816
return a + t * (b - a);
1917
}
2018

21-
ImageCodec::ImageCodec(const uint8_t *data, size_t size) :
19+
static void to_argb(unsigned char *image, unsigned w, unsigned h) {
20+
#if defined(_SDL)
21+
// convert from LCT_RGBA to ARGB
22+
for (unsigned y = 0; y < h; y++) {
23+
unsigned yoffs = (y * w * 4);
24+
for (unsigned x = 0; x < w; x++) {
25+
unsigned offs = yoffs + (x * 4);
26+
uint8_t r = image[offs + 2];
27+
uint8_t b = image[offs + 0];
28+
image[offs + 2] = b;
29+
image[offs + 0] = r;
30+
}
31+
}
32+
#endif
33+
}
34+
35+
ImageCodec::ImageCodec() :
2236
_width(0),
2337
_height(0),
2438
_pixels(nullptr) {
39+
}
40+
41+
bool ImageCodec::decode(const uint8_t *data, size_t size) {
2542
auto error = lodepng_decode32(&_pixels, &_width, &_height, data, size);
2643
if (error) {
2744
snprintf(g_last_error, sizeof(g_last_error), "%s", lodepng_error_text(error));
45+
} else {
46+
to_argb(_pixels, _width, _height);
2847
}
48+
49+
return !error;
2950
}
3051

3152
ImageCodec::~ImageCodec() {

src/ui/image_codec.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@ class ImageCodec {
1717
//
1818
// Decode IMG to raw RGBA image
1919
//
20-
ImageCodec(const uint8_t *data, size_t size);
20+
ImageCodec();
2121
virtual ~ImageCodec();
2222

2323
// Prevent copy and move
2424
ImageCodec(const ImageCodec &) = delete;
2525
ImageCodec& operator=(const ImageCodec &) = delete;
2626

27+
//
28+
// decode the png image to a raw RGBA
29+
//
30+
bool decode(const uint8_t *data, size_t size);
31+
2732
//
2833
// Encode the raw image RGBA data to png
2934
// The function allocates *data which must be freed.

src/ui/keypad.cpp

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,24 @@ constexpr int rowCharLengths[][5] = {
8686
{6, 10, 8, 14, 0}, // symbols
8787
};
8888

89+
//
90+
// KeypadImage
91+
//
92+
KeypadImage::KeypadImage() : ImageCodec() {
93+
}
94+
95+
void KeypadImage::draw(int x, int y, int w, int h) const {
96+
MAPoint2d dstPoint;
97+
MARect srcRect;
98+
dstPoint.x = x + (w - _width) / 2;
99+
dstPoint.y = y + (h - _height) / 2;
100+
srcRect.left = 0;
101+
srcRect.top = 0;
102+
srcRect.width = _width;
103+
srcRect.height = _height;
104+
maDrawRGB(&dstPoint, _pixels, &srcRect, 0, _width);
105+
}
106+
89107
//
90108
// KeypadDrawContext
91109
//
@@ -94,15 +112,30 @@ KeypadDrawContext::KeypadDrawContext(int charWidth, int charHeight) :
94112
_charHeight(charHeight),
95113
_shiftActive(false),
96114
_capsLockActive(false),
97-
_cutImage(img_cut, img_cut_len),
98-
_copyImage(img_copy, img_copy_len),
99-
_pasteImage(img_clipboard_paste, img_clipboard_paste_len),
100-
_saveImage(img_save, img_save_len),
101-
_runImage(img_bug_play, img_bug_play_len),
102-
_helpImage(img_book_info_2, img_book_info_2_len),
103-
_backImage(img_backspace, img_backspace_len),
104-
_enterImage(img_arrow_enter, img_arrow_enter_len),
105-
_searchImage(img_search, img_search_len) {
115+
_cutImage(),
116+
_copyImage(),
117+
_pasteImage(),
118+
_saveImage(),
119+
_runImage(),
120+
_helpImage(),
121+
_backImage(),
122+
_enterImage(),
123+
_searchImage(),
124+
_shiftImage() {
125+
126+
if (!_cutImage.decode(img_cut, img_cut_len) ||
127+
!_copyImage.decode(img_copy, img_copy_len) ||
128+
!_pasteImage.decode(img_clipboard_paste, img_clipboard_paste_len) ||
129+
!_saveImage.decode(img_save, img_save_len) ||
130+
!_runImage.decode(img_bug_play, img_bug_play_len) ||
131+
!_helpImage.decode(img_book_info_2, img_book_info_2_len) ||
132+
!_backImage.decode(img_backspace, img_backspace_len) ||
133+
!_enterImage.decode(img_arrow_enter, img_arrow_enter_len) ||
134+
!_searchImage.decode(img_search, img_search_len) ||
135+
!_shiftImage.decode(img_keyboard_shift, img_keyboard_shift_len) ||
136+
!_toggleImage.decode(img_keyboard, img_keyboard_len)) {
137+
deviceLog(_cutImage.getLastError());
138+
}
106139
}
107140

108141
void KeypadDrawContext::toggleShift() {
@@ -117,6 +150,25 @@ bool KeypadDrawContext::useShift(bool specialKey) {
117150
return useShift;
118151
}
119152

153+
const KeypadImage *KeypadDrawContext::getImage(const KeyCode keycode) const {
154+
const KeypadImage *result;
155+
switch (keycode) {
156+
case K_CUT: result = &_cutImage; break;
157+
case K_COPY: result = &_copyImage; break;
158+
case K_PASTE: result = &_pasteImage; break;
159+
case K_SAVE: result = &_saveImage; break;
160+
case K_RUN: result = &_runImage; break;
161+
case K_HELP: result = &_helpImage; break;
162+
case K_BACKSPACE: result = &_backImage;break;
163+
case K_ENTER: result = &_enterImage; break;
164+
case K_SEARCH: result = &_searchImage; break;
165+
case K_SHIFT: result = &_shiftImage; break;
166+
case K_TOGGLE: result = &_toggleImage; break;
167+
default: result = nullptr; break;
168+
}
169+
return result;
170+
}
171+
120172
//
121173
// Key
122174
//
@@ -142,18 +194,6 @@ int Key::color(const KeypadTheme *theme, bool shiftActive) const {
142194
return result;
143195
}
144196

145-
void Key::drawImage(const ImageCodec *image) const {
146-
MAPoint2d dstPoint;
147-
MARect srcRect;
148-
dstPoint.x = _x;
149-
dstPoint.y = _y;
150-
srcRect.left = 0;
151-
srcRect.top = 0;
152-
// srcRect.width = image->_width;
153-
// srcRect.height = image->_height;
154-
// maDrawRGB(&dstPoint, image->_pixels, &srcRect, 0, image->_width);
155-
}
156-
157197
void Key::draw(const KeypadTheme *theme, const KeypadDrawContext *context) const {
158198
int rc = 5;
159199
int pad = 2;
@@ -198,7 +238,10 @@ void Key::draw(const KeypadTheme *theme, const KeypadDrawContext *context) const
198238
maSetColor(color(theme, context->_shiftActive));
199239
maDrawText(textX, textY, key, 1);
200240
} else {
201-
drawImage(&context->_enterImage);
241+
auto *image = context->getImage(_key);
242+
if (image) {
243+
image->draw(_x, _y, _w, _h);
244+
}
202245
}
203246
}
204247

src/ui/keypad.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,34 @@ struct KeypadTheme {
2626
int _funcText;
2727
};
2828

29+
struct KeypadImage : ImageCodec {
30+
KeypadImage();
31+
~KeypadImage() = default;
32+
void draw(int x, int y, int w, int h) const;
33+
};
34+
2935
struct KeypadDrawContext {
3036
explicit KeypadDrawContext(int charWidth, int charHeight);
3137
void toggleShift();
3238
bool useShift(bool specialKey);
39+
const KeypadImage *getImage(const KeyCode keycode) const;
3340

3441
int _charWidth;
3542
int _charHeight;
3643
bool _shiftActive;
3744
bool _capsLockActive;
3845

39-
ImageCodec _cutImage;
40-
ImageCodec _copyImage;
41-
ImageCodec _pasteImage;
42-
ImageCodec _saveImage;
43-
ImageCodec _runImage;
44-
ImageCodec _helpImage;
45-
ImageCodec _backImage;
46-
ImageCodec _enterImage;
47-
ImageCodec _searchImage;
46+
KeypadImage _cutImage;
47+
KeypadImage _copyImage;
48+
KeypadImage _pasteImage;
49+
KeypadImage _saveImage;
50+
KeypadImage _runImage;
51+
KeypadImage _helpImage;
52+
KeypadImage _backImage;
53+
KeypadImage _enterImage;
54+
KeypadImage _searchImage;
55+
KeypadImage _shiftImage;
56+
KeypadImage _toggleImage;
4857
};
4958

5059
enum KeypadLayout {
@@ -61,7 +70,6 @@ struct Key {
6170

6271
int color(const KeypadTheme *theme, bool shiftActive) const;
6372
void draw(const KeypadTheme *theme, const KeypadDrawContext *context) const;
64-
void drawImage(const ImageCodec *image) const;
6573
bool inside(int x, int y) const;
6674
void onClick(bool useShift);
6775

0 commit comments

Comments
 (0)