1 /**************************************************************************/
4 @author K. Townsend (microBuilder.eu)
6 @brief Shows an alpha-numeric input dialogue
11 #include "drivers/displays/tft/dialogues/alphanumeric.h"
13 // Print results from an alpha-numeric dialogue
14 char* results = alphaShowDialogue();
15 printf("%s\r\n", results);
21 Software License Agreement (BSD License)
23 Copyright (c) 2010, microBuilder SARL
26 Redistribution and use in source and binary forms, with or without
27 modification, are permitted provided that the following conditions are met:
28 1. Redistributions of source code must retain the above copyright
29 notice, this list of conditions and the following disclaimer.
30 2. Redistributions in binary form must reproduce the above copyright
31 notice, this list of conditions and the following disclaimer in the
32 documentation and/or other materials provided with the distribution.
33 3. Neither the name of the copyright holders nor the
34 names of its contributors may be used to endorse or promote products
35 derived from this software without specific prior written permission.
37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
38 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
41 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 /**************************************************************************/
51 #include "alphanumeric.h"
53 #include "core/systick/systick.h"
54 #include "drivers/displays/tft/lcd.h"
55 #include "drivers/displays/tft/drawing.h"
56 #include "drivers/displays/tft/touchscreen.h"
57 #include "drivers/displays/tft/fonts/dejavusans9.h"
59 // Background and text input region colors
60 #define ALPHA_COLOR_BACKGROUND COLOR_GRAY_15
61 #define ALPHA_COLOR_INPUTFILL COLOR_GRAY_30
62 #define ALPHA_COLOR_INPUTTEXT COLOR_WHITE
64 #define ALPHA_COLOR_BTN_BORDER COLOR_GRAY_30
65 #define ALPHA_COLOR_BTN_FILL COLOR_GRAY_30
66 #define ALPHA_COLOR_BTN_FONT COLOR_WHITE
67 // Active button colors
68 #define ALPHA_COLOR_BTNEN_BORDER COLOR_THEME_DEFAULT_DARKER
69 #define ALPHA_COLOR_BTNEN_FILL COLOR_THEME_DEFAULT_BASE
70 #define ALPHA_COLOR_BTNEN_FONT COLOR_BLACK
72 /* This kind of messes with your head, but defining the pixel locations
73 this way allows the calculator example to be rendered on another
74 TFT LCD with a different screen resolution or orientation without
75 having to rewrite all the individual pixel-level code */
77 #define ALPHA_BTN_SPACING (5)
78 #define ALPHA_BTN_WIDTH ((lcdGetWidth() - (ALPHA_BTN_SPACING * 6)) / 5)
79 #define ALPHA_KEYPAD_TOP ((lcdGetHeight() / 7) + (ALPHA_BTN_SPACING * 2))
80 #define ALPHA_BTN_HEIGHT (((lcdGetHeight() - ALPHA_KEYPAD_TOP) - (ALPHA_BTN_SPACING * 7)) / 6)
81 // #define ALPHA_BTN_WIDTH ((240 - (ALPHA_BTN_SPACING * 6)) / 5)
82 // #define ALPHA_KEYPAD_TOP ((320 / 6) + (ALPHA_BTN_SPACING * 2))
83 // #define ALPHA_BTN_HEIGHT (((320 - ALPHA_KEYPAD_TOP) - (ALPHA_BTN_SPACING * 7)) / 6)
85 /* X/Y positions for buttons */
86 #define ALPHA_ROW1_TOP (ALPHA_KEYPAD_TOP + ALPHA_BTN_SPACING)
87 #define ALPHA_ROW2_TOP (ALPHA_KEYPAD_TOP + ALPHA_BTN_HEIGHT + (ALPHA_BTN_SPACING * 2))
88 #define ALPHA_ROW3_TOP (ALPHA_KEYPAD_TOP + ((ALPHA_BTN_HEIGHT * 2) + ((ALPHA_BTN_SPACING) * 3)))
89 #define ALPHA_ROW4_TOP (ALPHA_KEYPAD_TOP + ((ALPHA_BTN_HEIGHT * 3) + ((ALPHA_BTN_SPACING) * 4)))
90 #define ALPHA_ROW5_TOP (ALPHA_KEYPAD_TOP + ((ALPHA_BTN_HEIGHT * 4) + ((ALPHA_BTN_SPACING) * 5)))
91 #define ALPHA_ROW6_TOP (ALPHA_KEYPAD_TOP + ((ALPHA_BTN_HEIGHT * 5) + ((ALPHA_BTN_SPACING) * 6)))
92 #define ALPHA_COL1_LEFT (ALPHA_BTN_SPACING)
93 #define ALPHA_COL2_LEFT ((ALPHA_BTN_SPACING * 2) + ALPHA_BTN_WIDTH)
94 #define ALPHA_COL3_LEFT ((ALPHA_BTN_SPACING * 3) + (ALPHA_BTN_WIDTH * 2))
95 #define ALPHA_COL4_LEFT ((ALPHA_BTN_SPACING * 4) + (ALPHA_BTN_WIDTH * 3))
96 #define ALPHA_COL5_LEFT ((ALPHA_BTN_SPACING * 5) + (ALPHA_BTN_WIDTH * 4))
98 /* Control which 'page' is currently shown on the keypad */
99 static uint8_t alphaPage
= 0;
101 /* Keeps track of the string contents */
102 static uint8_t alphaString
[80];
103 static uint8_t *alphaString_ptr
;
105 /* For quick retrieval of button X/Y locqtions */
106 uint32_t alphaBtnX
[5], alphaBtnY
[6];
108 /* Array showing which characters should be displayed on each alphaPage */
109 /* You can rearrange the keypad by modifying the array contents below */
110 /* -------------------- -------------------- -------------------- --------------------
111 A B C D BACK a b c d BACK . , : ; BACK 7 8 9 BACK
112 E F G H I e f g h i ' " ( ) 4 5 6
113 J K L M N j k l m n ? ! { } 7 8 9
114 O P Q R S o p q r s # & @ ~ . 0 SPC
115 T U V W SHFT t u v w SHFT % = / \ SHFT SHFT
116 X Y Z SPC OK x y z SPC OK + - _ SPC OK OK
117 -------------------- -------------------- -------------------- -------------------- */
118 char alphaKeys
[4][6][5] = { { { 'A', 'B', 'C', 'D', '<' },
119 { 'E', 'F', 'G', 'H', 'I' },
120 { 'J', 'K', 'L', 'M', 'N' },
121 { 'O', 'P', 'Q', 'R', 'S' },
122 { 'T', 'U', 'V', 'W', '*' },
123 { 'X', 'Y', 'Z', ' ', '>' } },
125 { { 'a', 'b', 'c', 'd', '<' },
126 { 'e', 'f', 'g', 'h', 'i' },
127 { 'j', 'k', 'l', 'm', 'n' },
128 { 'o', 'p', 'q', 'r', 's' },
129 { 't', 'u', 'v', 'w', '*' },
130 { 'x', 'y', 'z', ' ', '>' } },
132 { { '.', ',', ':', ';', '<' },
133 { '\'', '\"', '(', ')', ' ' },
134 { '?', '!', '{', '}', ' ' },
135 { '#', '&', '@', '~', ' ' },
136 { '%', '=', '/', '\\', '*' },
137 { '+', '-', '_', ' ', '>' } },
139 { { '7', '8', '9', ' ', '<' },
140 { '4', '5', '6', ' ', ' ' },
141 { '1', '2', '3', ' ', ' ' },
142 { '.', '0', ' ', ' ', ' ' },
143 { ' ', ' ', ' ', ' ', '*'},
144 { ' ', ' ', ' ', ' ', '>' } } };
146 /**************************************************************************/
148 @brief Renders the UI
150 /**************************************************************************/
151 void alphaRenderButton(uint8_t alphaPage
, uint8_t col
, uint8_t row
, bool selected
)
153 // Set colors depending on button state
154 uint16_t border
, fill
, font
;
157 border
= ALPHA_COLOR_BTNEN_BORDER
;
158 fill
= ALPHA_COLOR_BTNEN_FILL
;
159 font
= ALPHA_COLOR_BTNEN_FONT
;
163 border
= ALPHA_COLOR_BTN_BORDER
;
164 fill
= ALPHA_COLOR_BTN_FILL
;
165 font
= ALPHA_COLOR_BTN_FONT
;
168 char c
= alphaKeys
[alphaPage
][row
][col
];
169 char key
[2] = { alphaKeys
[alphaPage
][row
][col
], '\0' };
170 // Handle special characters
175 drawButton (alphaBtnX
[col
], alphaBtnY
[row
], ALPHA_BTN_WIDTH
, ALPHA_BTN_HEIGHT
, &dejaVuSans9ptFontInfo
, border
, fill
, font
, NULL
);
176 drawArrow (alphaBtnX
[col
] + ALPHA_BTN_WIDTH
/ 2 - 3, alphaBtnY
[row
] + ALPHA_BTN_HEIGHT
/ 2, 7, DRAW_DIRECTION_LEFT
, font
);
180 drawButton (alphaBtnX
[col
], alphaBtnY
[row
], ALPHA_BTN_WIDTH
, ALPHA_BTN_HEIGHT
, &dejaVuSans9ptFontInfo
, border
, fill
, font
, NULL
);
181 drawArrow (alphaBtnX
[col
] + ALPHA_BTN_WIDTH
/ 2, (alphaBtnY
[row
] + ALPHA_BTN_HEIGHT
/ 2) - 3, 7, DRAW_DIRECTION_UP
, font
);
185 drawButton (alphaBtnX
[col
], alphaBtnY
[row
], ALPHA_BTN_WIDTH
, ALPHA_BTN_HEIGHT
, &dejaVuSans9ptFontInfo
, border
, fill
, font
, "OK");
188 // Standard character
189 drawButton (alphaBtnX
[col
], alphaBtnY
[row
], ALPHA_BTN_WIDTH
, ALPHA_BTN_HEIGHT
, &dejaVuSans9ptFontInfo
, border
, fill
, font
, key
);
194 /**************************************************************************/
196 @brief Renders the UI
198 /**************************************************************************/
199 void alphaRefreshScreen(void)
204 for (y
= 0; y
< 6; y
++)
206 for (x
= 0; x
< 5; x
++)
208 alphaRenderButton(alphaPage
, x
, y
, false);
213 drawRectangleRounded(ALPHA_BTN_SPACING
, ALPHA_BTN_SPACING
, lcdGetWidth() - 1 - ALPHA_BTN_SPACING
, ALPHA_KEYPAD_TOP
- ALPHA_BTN_SPACING
, ALPHA_COLOR_INPUTFILL
, 10, DRAW_ROUNDEDCORNERS_ALL
);
214 fontsDrawString(ALPHA_BTN_SPACING
* 3, ALPHA_BTN_SPACING
* 3, ALPHA_COLOR_INPUTTEXT
, &dejaVuSans9ptFontInfo
, (char *)&alphaString
);
217 /**************************************************************************/
219 @brief Processes the supplied touch data
221 /**************************************************************************/
222 char alphaHandleTouchEvent(void)
227 int32_t tsError
= -1;
229 // Blocking delay until a valid touch event occurs
232 tsError
= tsWaitForEvent(&data
, 0);
235 // Attempt to convert touch data to char
236 if ((data
.ylcd
< ALPHA_ROW1_TOP
) || (data
.ylcd
> ALPHA_ROW6_TOP
+ ALPHA_BTN_HEIGHT
))
242 if ((data
.xlcd
> alphaBtnX
[0]) && (data
.xlcd
< alphaBtnX
[0] + ALPHA_BTN_WIDTH
))
244 else if ((data
.xlcd
> alphaBtnX
[1]) && (data
.xlcd
< alphaBtnX
[1] + ALPHA_BTN_WIDTH
))
246 else if ((data
.xlcd
> alphaBtnX
[2]) && (data
.xlcd
< alphaBtnX
[2] + ALPHA_BTN_WIDTH
))
248 else if ((data
.xlcd
> alphaBtnX
[3]) && (data
.xlcd
< alphaBtnX
[3] + ALPHA_BTN_WIDTH
))
250 else if ((data
.xlcd
> ALPHA_COL5_LEFT
) && (data
.xlcd
< ALPHA_COL5_LEFT
+ ALPHA_BTN_WIDTH
))
256 if ((data
.ylcd
> ALPHA_ROW1_TOP
) && (data
.ylcd
< ALPHA_ROW1_TOP
+ ALPHA_BTN_HEIGHT
))
258 else if ((data
.ylcd
> ALPHA_ROW2_TOP
) && (data
.ylcd
< ALPHA_ROW2_TOP
+ ALPHA_BTN_HEIGHT
))
260 else if ((data
.ylcd
> ALPHA_ROW3_TOP
) && (data
.ylcd
< ALPHA_ROW3_TOP
+ ALPHA_BTN_HEIGHT
))
262 else if ((data
.ylcd
> ALPHA_ROW4_TOP
) && (data
.ylcd
< ALPHA_ROW4_TOP
+ ALPHA_BTN_HEIGHT
))
264 else if ((data
.ylcd
> ALPHA_ROW5_TOP
) && (data
.ylcd
< ALPHA_ROW5_TOP
+ ALPHA_BTN_HEIGHT
))
266 else if ((data
.ylcd
> ALPHA_ROW6_TOP
) && (data
.ylcd
< ALPHA_ROW6_TOP
+ ALPHA_BTN_HEIGHT
))
271 // Match found ... update button and process the results
272 alphaRenderButton(alphaPage
, col
, row
, true);
273 result
= alphaKeys
[alphaPage
][row
][col
];
277 // Trim character if backspace was pressed
278 if (alphaString_ptr
> alphaString
)
281 *alphaString_ptr
= '\0';
284 else if (result
== '*')
286 // Switch page if the shift button was pressed
293 alphaRefreshScreen();
295 else if (result
== '>')
298 systickDelay(CFG_TFTLCD_TS_KEYPADDELAY
);
303 // Add text to string buffer
304 *alphaString_ptr
++ = result
;
308 systickDelay(CFG_TFTLCD_TS_KEYPADDELAY
);
310 // Return button to deselected state
311 alphaRefreshScreen();
315 /**************************************************************************/
317 @brief Displays the dialogue box and waits for valid user input
322 #include "drivers/displays/tft/dialogues/alphanumeric.h"
324 // Print results from an alpha-numeric dialogue
325 char* results = alphaShowDialogue();
326 printf("%s\r\n", results);
330 /**************************************************************************/
331 char* alphaShowDialogue(void)
335 /* These need to be instantiated here since the width and height of
336 the lcd is retrieved dynamically depending on screen orientation */
337 alphaBtnX
[0] = ALPHA_COL1_LEFT
;
338 alphaBtnX
[1] = ALPHA_COL2_LEFT
;
339 alphaBtnX
[2] = ALPHA_COL3_LEFT
;
340 alphaBtnX
[3] = ALPHA_COL4_LEFT
;
341 alphaBtnX
[4] = ALPHA_COL5_LEFT
;
342 alphaBtnY
[0] = ALPHA_ROW1_TOP
;
343 alphaBtnY
[1] = ALPHA_ROW2_TOP
;
344 alphaBtnY
[2] = ALPHA_ROW3_TOP
;
345 alphaBtnY
[3] = ALPHA_ROW4_TOP
;
346 alphaBtnY
[4] = ALPHA_ROW5_TOP
;
347 alphaBtnY
[5] = ALPHA_ROW6_TOP
;
349 /* Initialise the string buffer */
350 memset(&alphaString
[0], 0, sizeof(alphaString
));
351 alphaString_ptr
= alphaString
;
354 /* Draw the background and render the buttons */
355 drawFill(ALPHA_COLOR_BACKGROUND
);
356 alphaRefreshScreen();
358 /* Capture results until the 'OK' button is pressed */
361 result
= alphaHandleTouchEvent();
362 if (result
== '>') return (char *)&alphaString
;