SSD1306 OLED display driver 1.8.2 This library is developed to control SSD1306/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays

ssd1306_menu.c
1 /*
2 MIT License
3
4 Copyright (c) 2017-2019, Alexey Dynda
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24
25 #include "font6x8.h"
26 #include "ssd1306.h"
27
28 #ifndef min
29 #define min(x,y) ((x)<(y)?(x):(y))
30 #endif
31
32 #ifndef max
33 #define max(x,y) ((x)>(y)?(x):(y))
34 #endif
35
36 extern SFixedFontInfo s_fixedFont;
37 extern uint16_t ssd1306_color;
38
39 static uint8_t getMaxScreenItems(void)
40 {
41 return ((ssd1306_displayHeight() - 16) / (s_fixedFont.pages * 8));
42 }
43
44 static uint8_t getMaxScreenItems8(void)
45 {
46 return ((ssd1306_displayHeight() - 16) / (s_fixedFont.h.height + 0));
47 }
48
49 void ssd1306_createMenu(SAppMenu *menu, const char **items, uint8_t count)
50 {
51 menu->items = items;
52 menu->count = count;
53 menu->selection = 0;
54 menu->oldSelection = 0;
55 menu->scrollPosition = 0;
56 }
57
58 static uint8_t calculateScrollPosition(SAppMenu *menu, uint8_t selection)
59 {
60 if ( selection < menu->scrollPosition )
61 {
62 return selection;
63 }
64 else if ( selection - menu->scrollPosition > getMaxScreenItems() - 1)
65 {
66 return selection - getMaxScreenItems() + 1;
67 }
68 return menu->scrollPosition;
69 }
70
71 static uint8_t calculateScrollPosition8(SAppMenu *menu, uint8_t selection)
72 {
73 if ( selection < menu->scrollPosition )
74 {
75 return selection;
76 }
77 else if ( selection - menu->scrollPosition > getMaxScreenItems8() - 1)
78 {
79 return selection - getMaxScreenItems8() + 1;
80 }
81 return menu->scrollPosition;
82 }
83
84 static void drawMenuItem(SAppMenu *menu, uint8_t index)
85 {
86 if (index == menu->selection)
87 {
88 ssd1306_negativeMode();
89 }
90 else
91 {
92 ssd1306_positiveMode();
93 }
94 ssd1306_printFixed(8, (index - menu->scrollPosition)* (s_fixedFont.pages * 8) + 8, menu->items[index], STYLE_NORMAL );
95 ssd1306_positiveMode();
96 }
97
98 static void drawMenuItem8(SAppMenu *menu, uint8_t index)
99 {
100 if (index == menu->selection)
101 {
102 ssd1306_negativeMode();
103 }
104 else
105 {
106 ssd1306_positiveMode();
107 }
108 ssd1306_printFixed8(8, (index - menu->scrollPosition)*(s_fixedFont.h.height + 0) + 8, menu->items[index], STYLE_NORMAL );
109 ssd1306_positiveMode();
110 }
111
112 static void drawMenuItem16(SAppMenu *menu, uint8_t index)
113 {
114 if (index == menu->selection)
115 {
116 ssd1306_negativeMode();
117 }
118 else
119 {
120 ssd1306_positiveMode();
121 }
122 ssd1306_printFixed16(8, (index - menu->scrollPosition) * (s_fixedFont.h.height + 0) + 8, menu->items[index], STYLE_NORMAL );
123 ssd1306_positiveMode();
124 }
125
126 void ssd1306_showMenu(SAppMenu *menu)
127 {
128 ssd1306_drawRect(4, 4, ssd1306_displayWidth() - 5, ssd1306_displayHeight() - 5);
129 menu->scrollPosition = calculateScrollPosition( menu, menu->selection );
130 for (uint8_t i = menu->scrollPosition; i < min(menu->count, menu->scrollPosition + getMaxScreenItems()); i++)
131 {
132 drawMenuItem(menu, i);
133 }
134 menu->oldSelection = menu->selection;
135 }
136
137 void ssd1306_showMenu8(SAppMenu *menu)
138 {
139 ssd1306_drawRect8(4, 4, ssd1306_displayWidth() - 5, ssd1306_displayHeight() - 5);
140 menu->scrollPosition = calculateScrollPosition8( menu, menu->selection );
141 for (uint8_t i = menu->scrollPosition; i < min(menu->count, menu->scrollPosition + getMaxScreenItems8()); i++)
142 {
143 drawMenuItem8(menu, i);
144 }
145 menu->oldSelection = menu->selection;
146 }
147
148 void ssd1306_showMenu16(SAppMenu *menu)
149 {
150 ssd1306_drawRect16(4, 4, ssd1306_displayWidth() - 5, ssd1306_displayHeight() - 5);
151 menu->scrollPosition = calculateScrollPosition8( menu, menu->selection );
152 for (uint8_t i = menu->scrollPosition; i < min(menu->count, menu->scrollPosition + getMaxScreenItems8()); i++)
153 {
154 drawMenuItem16(menu, i);
155 }
156 menu->oldSelection = menu->selection;
157 }
158
159 void ssd1306_updateMenu(SAppMenu *menu)
160 {
161 if (menu->selection != menu->oldSelection)
162 {
163 uint8_t scrollPosition = calculateScrollPosition( menu, menu->selection );
164 if ( scrollPosition != menu->scrollPosition )
165 {
166 ssd1306_clearScreen();
167 ssd1306_showMenu(menu);
168 }
169 else
170 {
171 drawMenuItem(menu, menu->oldSelection);
172 drawMenuItem(menu, menu->selection);
173 menu->oldSelection = menu->selection;
174 }
175 }
176 }
177
178 void ssd1306_updateMenu8(SAppMenu *menu)
179 {
180 if (menu->selection != menu->oldSelection)
181 {
182 uint8_t scrollPosition = calculateScrollPosition8( menu, menu->selection );
183 if ( scrollPosition != menu->scrollPosition )
184 {
185 ssd1306_clearScreen8();
186 ssd1306_showMenu8(menu);
187 }
188 else
189 {
190 drawMenuItem8(menu, menu->oldSelection);
191 drawMenuItem8(menu, menu->selection);
192 menu->oldSelection = menu->selection;
193 }
194 }
195 }
196
197 void ssd1306_updateMenu16(SAppMenu *menu)
198 {
199 if (menu->selection != menu->oldSelection)
200 {
201 uint8_t scrollPosition = calculateScrollPosition8( menu, menu->selection );
202 if ( scrollPosition != menu->scrollPosition )
203 {
204 ssd1306_clearScreen16();
205 ssd1306_showMenu16(menu);
206 }
207 else
208 {
209 drawMenuItem16(menu, menu->oldSelection);
210 drawMenuItem16(menu, menu->selection);
211 menu->oldSelection = menu->selection;
212 }
213 }
214 }
215
216 uint8_t ssd1306_menuSelection(SAppMenu *menu)
217 {
218 return menu->selection;
219 }
220
221 void ssd1306_menuDown(SAppMenu *menu)
222 {
223 if (menu->selection < menu->count - 1)
224 {
225 menu->selection++;
226 }
227 else
228 {
229 menu->selection = 0;
230 }
231 }
232
233 void ssd1306_menuUp(SAppMenu *menu)
234 {
235 if (menu->selection > 0)
236 {
237 menu->selection--;
238 }
239 else
240 {
241 menu->selection = menu->count - 1;
242 }
243 }
244
245 void ssd1306_drawProgressBar(int8_t progress)
246 {
247 lcduint_t height = 8;
248 lcduint_t width = 8;
249 char str[5] = "100%";
250 if ( progress < 100 )
251 {
252 str[0] = ' ';
253 str[1] = progress / 10 + '0';
254 str[2] = progress % 10 + '0';
255 str[3] = '%';
256 }
257 if ( s_fixedFont.primary_table != NULL )
258 {
259 width = ssd1306_getTextSize( str, &height );
260 }
261 lcdint_t middle = ssd1306_displayHeight() / 2;
262 lcdint_t progress_pos = 8 + (int16_t)(ssd1306_displayWidth() - 16) * progress / 100;
263 uint16_t color = ssd1306_color;
264 ssd1306_color = 0x0000;
265 ssd1306_fillRect( progress_pos, middle, ssd1306_displayWidth() - 8, middle + height );
266 ssd1306_color = color;
267 ssd1306_printFixed( ssd1306_displayWidth() / 2 - width / 2, middle - height, str, STYLE_NORMAL );
268 ssd1306_drawRect( 8, middle, ssd1306_displayWidth() - 8, middle + height );
269 ssd1306_fillRect( 8, middle, progress_pos, middle + height );
270 }
271
272 void ssd1306_drawProgressBar8(int8_t progress)
273 {
274 lcduint_t height = 8;
275 lcduint_t width = 8;
276 char str[5] = "100%";
277 if ( progress < 100 )
278 {
279 str[0] = ' ';
280 str[1] = progress / 10 + '0';
281 str[2] = progress % 10 + '0';
282 str[3] = '%';
283 }
284 if ( s_fixedFont.primary_table != NULL )
285 {
286 width = ssd1306_getTextSize( str, &height );
287 }
288 lcdint_t middle = ssd1306_displayHeight() / 2;
289 lcdint_t progress_pos = 8 + (int16_t)(ssd1306_displayWidth() - 16) * progress / 100;
290 uint16_t color = ssd1306_color;
291 ssd1306_color = 0x0000;
292 ssd1306_fillRect8( progress_pos, middle, ssd1306_displayWidth() - 8, middle + height );
293 ssd1306_color = color;
294 ssd1306_printFixed8( ssd1306_displayWidth() / 2 - width / 2, middle - height, str, STYLE_NORMAL );
295 ssd1306_drawRect8( 8, middle, ssd1306_displayWidth() - 8, middle + height );
296 ssd1306_fillRect8( 8, middle, progress_pos, middle + height );
297 }
ssd1306_displayWidth
lcduint_t ssd1306_displayWidth(void)
Definition: ssd1306_generic.c:63
ssd1306_drawRect8
void ssd1306_drawRect8(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: ssd1306_8bit.c:211
ssd1306_printFixed8
uint8_t ssd1306_printFixed8(lcdint_t x, lcdint_t y, const char *ch, EFontStyle style)
Definition: ssd1306_8bit.c:371
ssd1306_createMenu
void ssd1306_createMenu(SAppMenu *menu, const char **items, uint8_t count)
Definition: ssd1306_menu.c:49
ssd1306_positiveMode
void ssd1306_positiveMode()
Definition: ssd1306_1bit.c:1089
SFixedFontInfo::primary_table
const uint8_t * primary_table
font chars bits
Definition: nano_gfx_types.h:111
ssd1306.h
ssd1306_printFixed16
uint8_t ssd1306_printFixed16(lcdint_t x, lcdint_t y, const char *ch, EFontStyle style)
Definition: ssd1306_16bit.c:359
font6x8.h
ssd1306_printFixed
uint8_t ssd1306_printFixed(uint8_t xpos, uint8_t y, const char *ch, EFontStyle style)
Definition: ssd1306_1bit.c:79
ssd1306_updateMenu
void ssd1306_updateMenu(SAppMenu *menu)
Definition: ssd1306_menu.c:159
ssd1306_drawRect
void ssd1306_drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
Definition: ssd1306_1bit.c:717
ssd1306_drawRect16
void ssd1306_drawRect16(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: ssd1306_16bit.c:200
ssd1306_drawProgressBar8
void ssd1306_drawProgressBar8(int8_t progress)
Definition: ssd1306_menu.c:272
ssd1306_updateMenu16
void ssd1306_updateMenu16(SAppMenu *menu)
Definition: ssd1306_menu.c:197
SFontHeaderRecord::height
uint8_t height
height in pixels
Definition: nano_gfx_types.h:91
SFixedFontInfo
Definition: nano_gfx_types.h:105
ssd1306_drawProgressBar
void ssd1306_drawProgressBar(int8_t progress)
Definition: ssd1306_menu.c:245
ssd1306_fillRect
void ssd1306_fillRect(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: ssd1306_1bit.c:942
min
#define min(a, b)
Definition: nano_gfx_types.h:35
s_fixedFont
SFixedFontInfo s_fixedFont
Definition: tiler.h:44
ssd1306_clearScreen16
void ssd1306_clearScreen16(void)
Definition: ssd1306_16bit.c:116
SFixedFontInfo::h
SFontHeaderRecord h
record, containing information on font
Definition: nano_gfx_types.h:107
ssd1306_getTextSize
lcduint_t ssd1306_getTextSize(const char *text, lcduint_t *height)
Definition: ssd1306_generic.c:372
ssd1306_menuDown
void ssd1306_menuDown(SAppMenu *menu)
Definition: ssd1306_menu.c:221
ssd1306_clearScreen8
void ssd1306_clearScreen8(void)
Definition: ssd1306_8bit.c:127
ssd1306_displayHeight
lcduint_t ssd1306_displayHeight(void)
Definition: ssd1306_generic.c:58
ssd1306_updateMenu8
void ssd1306_updateMenu8(SAppMenu *menu)
Definition: ssd1306_menu.c:178
ssd1306_showMenu8
void ssd1306_showMenu8(SAppMenu *menu)
Definition: ssd1306_menu.c:137
ssd1306_menuSelection
uint8_t ssd1306_menuSelection(SAppMenu *menu)
Definition: ssd1306_menu.c:216
ssd1306_clearScreen
void ssd1306_clearScreen()
Definition: ssd1306_1bit.c:65
ssd1306_fillRect8
void ssd1306_fillRect8(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: ssd1306_8bit.c:219
ssd1306_showMenu
void ssd1306_showMenu(SAppMenu *menu)
Definition: ssd1306_menu.c:126
SFixedFontInfo::pages
uint8_t pages
height in pages (each page height is 8-pixels)
Definition: nano_gfx_types.h:109
ssd1306_menuUp
void ssd1306_menuUp(SAppMenu *menu)
Definition: ssd1306_menu.c:233
ssd1306_negativeMode
void ssd1306_negativeMode()
Definition: ssd1306_1bit.c:1084
ssd1306_showMenu16
void ssd1306_showMenu16(SAppMenu *menu)
Definition: ssd1306_menu.c:148