components/u8g2/csrc/u8g2_selection_list.c

changeset 0
88d965579617
equal deleted inserted replaced
-1:000000000000 0:88d965579617
1 /*
2
3 u8g2_selection_list.c
4
5 selection list with scroll option
6
7 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
8
9 Copyright (c) 2016, olikraus@gmail.com
10 All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without modification,
13 are permitted provided that the following conditions are met:
14
15 * Redistributions of source code must retain the above copyright notice, this list
16 of conditions and the following disclaimer.
17
18 * Redistributions in binary form must reproduce the above copyright notice, this
19 list of conditions and the following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
34 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36 */
37
38 #include "u8g2.h"
39
40 #define MY_BORDER_SIZE 1
41
42
43 /*
44 Draw a string at x,y
45 Center string within w (left adjust if w < pixel len of s)
46
47 Side effects:
48 u8g2_SetFontDirection(u8g2, 0);
49 u8g2_SetFontPosBaseline(u8g2);
50
51 */
52 void u8g2_DrawUTF8Line(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, const char *s, uint8_t border_size, uint8_t is_invert)
53 {
54 u8g2_uint_t d, str_width;
55 u8g2_uint_t fx, fy, fw, fh;
56
57 /* only horizontal strings are supported, so force this here */
58 u8g2_SetFontDirection(u8g2, 0);
59
60 /* revert y position back to baseline ref */
61 y += u8g2->font_calc_vref(u8g2);
62
63 /* calculate the width of the string in pixel */
64 str_width = u8g2_GetUTF8Width(u8g2, s);
65
66 /* calculate delta d within the box */
67 d = 0;
68 if ( str_width < w )
69 {
70 d = w;
71 d -=str_width;
72 d /= 2;
73 }
74 else
75 {
76 w = str_width;
77 }
78
79 /* caluclate text box */
80 fx = x;
81 fy = y - u8g2_GetAscent(u8g2) ;
82 fw = w;
83 fh = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) ;
84
85 /* draw the box, if inverted */
86 u8g2_SetDrawColor(u8g2, 1);
87 if ( is_invert )
88 {
89 u8g2_DrawBox(u8g2, fx, fy, fw, fh);
90 }
91
92 /* draw the frame */
93 while( border_size > 0 )
94 {
95 fx--;
96 fy--;
97 fw +=2;
98 fh +=2;
99 u8g2_DrawFrame(u8g2, fx, fy, fw, fh );
100 border_size--;
101 }
102
103 if ( is_invert )
104 {
105 u8g2_SetDrawColor(u8g2, 0);
106 }
107 else
108 {
109 u8g2_SetDrawColor(u8g2, 1);
110 }
111
112 /* draw the text */
113 u8g2_DrawUTF8(u8g2, x+d, y, s);
114
115 /* revert draw color */
116 u8g2_SetDrawColor(u8g2, 1);
117
118 }
119
120
121 /*
122 draw several lines at position x,y.
123 lines are stored in s and must be separated with '\n'.
124 lines can be centered with respect to "w"
125 if s == NULL nothing is drawn and 0 is returned
126 returns the number of lines in s multiplied with line_height
127 */
128 u8g2_uint_t u8g2_DrawUTF8Lines(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t line_height, const char *s)
129 {
130 uint8_t i;
131 uint8_t cnt;
132 u8g2_uint_t yy = 0;
133 cnt = u8x8_GetStringLineCnt(s);
134 //printf("str=%s\n", s);
135 //printf("cnt=%d, y=%d, line_height=%d\n", cnt, y, line_height);
136 for( i = 0; i < cnt; i++ )
137 {
138 //printf(" i=%d, y=%d, line_height=%d\n", i, y, line_height);
139 u8g2_DrawUTF8Line(u8g2, x, y, w, u8x8_GetStringLineStart(i, s), 0, 0);
140 y+=line_height;
141 yy+=line_height;
142 }
143 return yy;
144 }
145
146 /*
147 selection list with string line
148 returns line height
149 */
150 static u8g2_uint_t u8g2_draw_selection_list_line(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, uint8_t idx, const char *s) U8G2_NOINLINE;
151 static u8g2_uint_t u8g2_draw_selection_list_line(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, uint8_t idx, const char *s)
152 {
153 u8g2_uint_t yy;
154 uint8_t border_size = 0;
155 uint8_t is_invert = 0;
156
157 u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2)+MY_BORDER_SIZE;
158
159 /* calculate offset from display upper border */
160 yy = idx;
161 yy -= u8sl->first_pos;
162 yy *= line_height;
163 yy += y;
164
165 /* check whether this is the current cursor line */
166 if ( idx == u8sl->current_pos )
167 {
168 border_size = MY_BORDER_SIZE;
169 is_invert = 1;
170 }
171
172 /* get the line from the array */
173 s = u8x8_GetStringLineStart(idx, s);
174
175 /* draw the line */
176 if ( s == NULL )
177 s = "";
178 u8g2_DrawUTF8Line(u8g2, MY_BORDER_SIZE, y, u8g2_GetDisplayWidth(u8g2)-2*MY_BORDER_SIZE, s, border_size, is_invert);
179 return line_height;
180 }
181
182 void u8g2_DrawSelectionList(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, const char *s)
183 {
184 uint8_t i;
185 for( i = 0; i < u8sl->visible; i++ )
186 {
187 y += u8g2_draw_selection_list_line(u8g2, u8sl, y, i+u8sl->first_pos, s);
188 }
189 }
190
191
192 /*
193 title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n'
194 start_pos: default position for the cursor, first line is 1.
195 sl: string list (list of strings separated by \n)
196 returns 0 if user has pressed the home key
197 returns the selected line if user has pressed the select key
198 side effects:
199 u8g2_SetFontDirection(u8g2, 0);
200 u8g2_SetFontPosBaseline(u8g2);
201
202 */
203 uint8_t u8g2_UserInterfaceSelectionList(u8g2_t *u8g2, const char *title, uint8_t start_pos, const char *sl)
204 {
205 u8sl_t u8sl;
206 u8g2_uint_t yy;
207
208 uint8_t event;
209
210 u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2)+MY_BORDER_SIZE;
211
212 uint8_t title_lines = u8x8_GetStringLineCnt(title);
213 uint8_t display_lines;
214
215
216 if ( start_pos > 0 ) /* issue 112 */
217 start_pos--; /* issue 112 */
218
219
220 if ( title_lines > 0 )
221 {
222 display_lines = (u8g2_GetDisplayHeight(u8g2)-3) / line_height;
223 u8sl.visible = display_lines;
224 u8sl.visible -= title_lines;
225 }
226 else
227 {
228 display_lines = u8g2_GetDisplayHeight(u8g2) / line_height;
229 u8sl.visible = display_lines;
230 }
231
232 u8sl.total = u8x8_GetStringLineCnt(sl);
233 u8sl.first_pos = 0;
234 u8sl.current_pos = start_pos;
235
236 if ( u8sl.current_pos >= u8sl.total )
237 u8sl.current_pos = u8sl.total-1;
238 if ( u8sl.first_pos+u8sl.visible <= u8sl.current_pos )
239 u8sl.first_pos = u8sl.current_pos-u8sl.visible+1;
240
241 u8g2_SetFontPosBaseline(u8g2);
242
243 for(;;)
244 {
245 u8g2_FirstPage(u8g2);
246 do
247 {
248 yy = u8g2_GetAscent(u8g2);
249 if ( title_lines > 0 )
250 {
251 yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title);
252
253 u8g2_DrawHLine(u8g2, 0, yy-line_height- u8g2_GetDescent(u8g2) + 1, u8g2_GetDisplayWidth(u8g2));
254
255 yy += 3;
256 }
257 u8g2_DrawSelectionList(u8g2, &u8sl, yy, sl);
258 } while( u8g2_NextPage(u8g2) );
259
260 #ifdef U8G2_REF_MAN_PIC
261 return 0;
262 #endif
263
264
265 for(;;)
266 {
267 event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2));
268 if ( event == U8X8_MSG_GPIO_MENU_SELECT )
269 return u8sl.current_pos+1; /* +1, issue 112 */
270 else if ( event == U8X8_MSG_GPIO_MENU_HOME )
271 return 0; /* issue 112: return 0 instead of start_pos */
272 else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN )
273 {
274 u8sl_Next(&u8sl);
275 break;
276 }
277 else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP )
278 {
279 u8sl_Prev(&u8sl);
280 break;
281 }
282 }
283 }
284 }

mercurial