|
1 /* |
|
2 |
|
3 u8x8_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 "u8x8.h" |
|
39 |
|
40 /* |
|
41 increase the cursor position |
|
42 */ |
|
43 void u8sl_Next(u8sl_t *u8sl) |
|
44 { |
|
45 u8sl->current_pos++; |
|
46 if ( u8sl->current_pos >= u8sl->total ) |
|
47 { |
|
48 u8sl->current_pos = 0; |
|
49 u8sl->first_pos = 0; |
|
50 } |
|
51 else |
|
52 { |
|
53 if ( u8sl->first_pos + u8sl->visible <= u8sl->current_pos + 1 ) |
|
54 { |
|
55 u8sl->first_pos = u8sl->current_pos - u8sl->visible + 1; |
|
56 } |
|
57 } |
|
58 } |
|
59 |
|
60 void u8sl_Prev(u8sl_t *u8sl) |
|
61 { |
|
62 if ( u8sl->current_pos == 0 ) |
|
63 { |
|
64 u8sl->current_pos = u8sl->total - 1; |
|
65 u8sl->first_pos = 0; |
|
66 if ( u8sl->total > u8sl->visible ) |
|
67 u8sl->first_pos = u8sl->total - u8sl->visible; |
|
68 } |
|
69 else |
|
70 { |
|
71 u8sl->current_pos--; |
|
72 if ( u8sl->first_pos > u8sl->current_pos ) |
|
73 u8sl->first_pos = u8sl->current_pos; |
|
74 } |
|
75 } |
|
76 |
|
77 void u8x8_DrawSelectionList(u8x8_t *u8x8, u8sl_t *u8sl, u8x8_sl_cb sl_cb, const void *aux) |
|
78 { |
|
79 uint8_t i; |
|
80 for( i = 0; i < u8sl->visible; i++ ) |
|
81 { |
|
82 sl_cb(u8x8, u8sl, i+u8sl->first_pos, aux); |
|
83 } |
|
84 } |
|
85 |
|
86 /* selection list with string line */ |
|
87 void u8x8_sl_string_line_cb(u8x8_t *u8x8, u8sl_t *u8sl, uint8_t idx, const void *aux) |
|
88 { |
|
89 const char *s; |
|
90 uint8_t row; |
|
91 /* calculate offset from display upper border */ |
|
92 row = u8sl->y; |
|
93 |
|
94 /* calculate target pos */ |
|
95 row += idx; |
|
96 row -= u8sl->first_pos; |
|
97 |
|
98 /* check whether this is the current cursor line */ |
|
99 if ( idx == u8sl->current_pos ) |
|
100 u8x8_SetInverseFont(u8x8, 1); |
|
101 else |
|
102 u8x8_SetInverseFont(u8x8, 0); |
|
103 |
|
104 /* get the line from the array */ |
|
105 s = u8x8_GetStringLineStart(idx, (const char *)aux); |
|
106 |
|
107 /* draw the line */ |
|
108 if ( s == NULL ) |
|
109 s = ""; |
|
110 u8x8_DrawUTF8Line(u8x8, u8sl->x, row, u8x8_GetCols(u8x8), s); |
|
111 u8x8_SetInverseFont(u8x8, 0); |
|
112 } |
|
113 |
|
114 /* |
|
115 title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n' |
|
116 start_pos: default position for the cursor (starts with 1) |
|
117 sl: string list (list of strings separated by \n) |
|
118 returns 0 if user has pressed the home key |
|
119 returns the selected line+1 if user has pressed the select key (e.g. 1 for the first line) |
|
120 */ |
|
121 uint8_t u8x8_UserInterfaceSelectionList(u8x8_t *u8x8, const char *title, uint8_t start_pos, const char *sl) |
|
122 { |
|
123 u8sl_t u8sl; |
|
124 uint8_t event; |
|
125 uint8_t title_lines; |
|
126 |
|
127 if ( start_pos > 0 ) |
|
128 start_pos--; |
|
129 |
|
130 u8sl.visible = u8x8_GetRows(u8x8); |
|
131 u8sl.total = u8x8_GetStringLineCnt(sl); |
|
132 u8sl.first_pos = 0; |
|
133 u8sl.current_pos = start_pos; |
|
134 u8sl.x = 0; |
|
135 u8sl.y = 0; |
|
136 |
|
137 |
|
138 //u8x8_ClearDisplay(u8x8); /* not required because all is 100% filled */ |
|
139 u8x8_SetInverseFont(u8x8, 0); |
|
140 |
|
141 if ( title != NULL ) |
|
142 { |
|
143 title_lines = u8x8_DrawUTF8Lines(u8x8, u8sl.x, u8sl.y, u8x8_GetCols(u8x8), title); |
|
144 u8sl.y+=title_lines; |
|
145 u8sl.visible-=title_lines; |
|
146 } |
|
147 |
|
148 if ( u8sl.current_pos >= u8sl.total ) |
|
149 u8sl.current_pos = u8sl.total-1; |
|
150 |
|
151 |
|
152 u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); |
|
153 |
|
154 for(;;) |
|
155 { |
|
156 event = u8x8_GetMenuEvent(u8x8); |
|
157 if ( event == U8X8_MSG_GPIO_MENU_SELECT ) |
|
158 return u8sl.current_pos+1; |
|
159 else if ( event == U8X8_MSG_GPIO_MENU_HOME ) |
|
160 return 0; |
|
161 else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN ) |
|
162 { |
|
163 u8sl_Next(&u8sl); |
|
164 u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); |
|
165 } |
|
166 else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP ) |
|
167 { |
|
168 u8sl_Prev(&u8sl); |
|
169 u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); |
|
170 } |
|
171 } |
|
172 } |
|
173 |