diff options
Diffstat (limited to 'apps/gui/color_picker.c')
-rw-r--r-- | apps/gui/color_picker.c | 234 |
1 files changed, 117 insertions, 117 deletions
diff --git a/apps/gui/color_picker.c b/apps/gui/color_picker.c index 026ae82c4c..d70b98c198 100644 --- a/apps/gui/color_picker.c +++ b/apps/gui/color_picker.c | |||
@@ -110,14 +110,10 @@ static inline unsigned get_black_or_white(const struct rgb_pick *rgb) | |||
110 | LCD_BLACK : LCD_WHITE; | 110 | LCD_BLACK : LCD_WHITE; |
111 | } | 111 | } |
112 | 112 | ||
113 | #define MARGIN_LEFT 0 /* Left margin of screen */ | ||
114 | #define MARGIN_TOP 2 /* Top margin of screen */ | 113 | #define MARGIN_TOP 2 /* Top margin of screen */ |
115 | #define MARGIN_RIGHT 0 /* Right margin of screen */ | ||
116 | #define MARGIN_BOTTOM 6 /* Bottom margin of screen */ | 114 | #define MARGIN_BOTTOM 6 /* Bottom margin of screen */ |
117 | #define SLIDER_MARGIN_LEFT 2 /* Gap to left of sliders */ | 115 | #define SLIDER_TEXT_MARGIN 2 /* Gap between text and sliders */ |
118 | #define SLIDER_MARGIN_RIGHT 2 /* Gap to right of sliders */ | ||
119 | #define TITLE_MARGIN_BOTTOM 4 /* Space below title bar */ | 116 | #define TITLE_MARGIN_BOTTOM 4 /* Space below title bar */ |
120 | #define SELECTOR_LR_MARGIN 0 /* Margin between ">" and text */ | ||
121 | #define SELECTOR_TB_MARGIN 1 /* Margin on top and bottom of selector */ | 117 | #define SELECTOR_TB_MARGIN 1 /* Margin on top and bottom of selector */ |
122 | #define SWATCH_TOP_MARGIN 4 /* Space between last slider and swatch */ | 118 | #define SWATCH_TOP_MARGIN 4 /* Space between last slider and swatch */ |
123 | #define SELECTOR_WIDTH get_icon_width(display->screen_type) | 119 | #define SELECTOR_WIDTH get_icon_width(display->screen_type) |
@@ -135,15 +131,33 @@ static void set_drawinfo(struct screen *display, int mode, | |||
135 | } | 131 | } |
136 | } | 132 | } |
137 | 133 | ||
134 | /* Figure out widest label character in case they vary - | ||
135 | this function assumes labels are one character */ | ||
136 | static int label_get_max_width(struct screen *display) | ||
137 | { | ||
138 | int max_width, i; | ||
139 | char buf[4]; | ||
140 | for (i = 0, max_width = 0; i < 3; i++) | ||
141 | { | ||
142 | int width; | ||
143 | buf[0] = str(LANG_COLOR_RGB_LABELS)[i]; | ||
144 | buf[1] = '\0'; | ||
145 | width = display->getstringsize(buf, NULL, NULL); | ||
146 | if (width > max_width) | ||
147 | max_width = width; | ||
148 | } | ||
149 | return max_width; | ||
150 | } | ||
151 | |||
138 | static void draw_screen(struct screen *display, char *title, | 152 | static void draw_screen(struct screen *display, char *title, |
139 | struct rgb_pick *rgb, int row) | 153 | struct rgb_pick *rgb, int row) |
140 | { | 154 | { |
141 | unsigned text_color = LCD_BLACK; | 155 | unsigned text_color = LCD_BLACK; |
142 | unsigned background_color = LCD_WHITE; | 156 | unsigned background_color = LCD_WHITE; |
143 | char buf[32]; | 157 | char buf[32]; |
144 | int i, x, y; | 158 | int i, text_x, y, line_height; |
145 | int text_top; | 159 | int text_top; |
146 | int slider_left, slider_width; | 160 | int slider_x, slider_width; |
147 | bool display_three_rows; | 161 | bool display_three_rows; |
148 | int max_label_width; | 162 | int max_label_width; |
149 | struct viewport vp; | 163 | struct viewport vp; |
@@ -159,40 +173,30 @@ static void draw_screen(struct screen *display, char *title, | |||
159 | background_color = display->get_background(); | 173 | background_color = display->get_background(); |
160 | } | 174 | } |
161 | 175 | ||
162 | /* Find out if there's enough room for three sliders or just | 176 | max_label_width = label_get_max_width(display); |
163 | enough to display the selected slider - calculate total height | ||
164 | of display with three sliders present */ | ||
165 | display_three_rows = | ||
166 | vp.height >= | ||
167 | MARGIN_TOP + | ||
168 | display->getcharheight()*4 + /* Title + 3 sliders */ | ||
169 | TITLE_MARGIN_BOTTOM + | ||
170 | SELECTOR_TB_MARGIN*6 + /* 2 margins/slider */ | ||
171 | MARGIN_BOTTOM; | ||
172 | |||
173 | /* Figure out widest label character in case they vary - | ||
174 | this function assumes labels are one character */ | ||
175 | for (i = 0, max_label_width = 0; i < 3; i++) | ||
176 | { | ||
177 | buf[0] = str(LANG_COLOR_RGB_LABELS)[i]; | ||
178 | buf[1] = '\0'; | ||
179 | x = display->getstringsize(buf, NULL, NULL); | ||
180 | if (x > max_label_width) | ||
181 | max_label_width = x; | ||
182 | } | ||
183 | 177 | ||
184 | /* Draw title string */ | 178 | /* Draw title string */ |
185 | set_drawinfo(display, DRMODE_SOLID, text_color, background_color); | 179 | set_drawinfo(display, DRMODE_SOLID, text_color, background_color); |
186 | display->getstringsize(title, &x, &y); | 180 | vp.flags |= VP_FLAG_CENTER_ALIGN; |
187 | display->putsxy((vp.width - x) / 2, MARGIN_TOP, title); | 181 | display->getstringsize(title, NULL, &y); |
182 | display->putsxy(0, MARGIN_TOP, title); | ||
188 | 183 | ||
189 | /* Get slider positions and top starting position */ | 184 | /* Get slider positions and top starting position */ |
190 | text_top = MARGIN_TOP + y + TITLE_MARGIN_BOTTOM + SELECTOR_TB_MARGIN; | 185 | text_top = MARGIN_TOP + y + TITLE_MARGIN_BOTTOM + SELECTOR_TB_MARGIN; |
191 | slider_left = MARGIN_LEFT + SELECTOR_WIDTH + SELECTOR_LR_MARGIN + | 186 | text_x = SELECTOR_WIDTH; |
192 | max_label_width + SLIDER_MARGIN_LEFT; | 187 | slider_x = text_x + max_label_width + SLIDER_TEXT_MARGIN; |
193 | slider_width = vp.width - slider_left - SLIDER_MARGIN_RIGHT - | 188 | slider_width = vp.width - slider_x*2 - max_label_width; |
194 | display->getcharwidth()*2 - SELECTOR_LR_MARGIN - | 189 | line_height = display->getcharheight() + 2*SELECTOR_TB_MARGIN; |
195 | SELECTOR_WIDTH - MARGIN_RIGHT; | 190 | |
191 | /* Find out if there's enough room for three sliders or just | ||
192 | enough to display the selected slider - calculate total height | ||
193 | of display with three sliders present */ | ||
194 | display_three_rows = | ||
195 | vp.height >= | ||
196 | text_top + line_height*3 + /* Title + 3 sliders */ | ||
197 | SWATCH_TOP_MARGIN + /* at least 2 lines */ | ||
198 | display->getcharheight()*2 + /* + margins for bottom */ | ||
199 | MARGIN_BOTTOM; /* colored rectangle */ | ||
196 | 200 | ||
197 | for (i = 0; i < 3; i++) | 201 | for (i = 0; i < 3; i++) |
198 | { | 202 | { |
@@ -201,9 +205,6 @@ static void draw_screen(struct screen *display, char *title, | |||
201 | unsigned fg = text_color; | 205 | unsigned fg = text_color; |
202 | unsigned bg = background_color; | 206 | unsigned bg = background_color; |
203 | 207 | ||
204 | if (!display_three_rows) | ||
205 | i = row; | ||
206 | |||
207 | if (i == row) | 208 | if (i == row) |
208 | { | 209 | { |
209 | set_drawinfo(display, DRMODE_SOLID, text_color, | 210 | set_drawinfo(display, DRMODE_SOLID, text_color, |
@@ -229,9 +230,9 @@ static void draw_screen(struct screen *display, char *title, | |||
229 | /* Draw "> <" around sliders */ | 230 | /* Draw "> <" around sliders */ |
230 | int top = text_top + (display->getcharheight() - | 231 | int top = text_top + (display->getcharheight() - |
231 | SELECTOR_HEIGHT) / 2; | 232 | SELECTOR_HEIGHT) / 2; |
232 | screen_put_iconxy(display, MARGIN_LEFT, top, Icon_Cursor); | 233 | screen_put_iconxy(display, 0, top, Icon_Cursor); |
233 | screen_put_iconxy(display, | 234 | screen_put_iconxy(display, |
234 | vp.width - MARGIN_RIGHT - | 235 | vp.width - |
235 | get_icon_width(display->screen_type), | 236 | get_icon_width(display->screen_type), |
236 | top, Icon_Cursor); | 237 | top, Icon_Cursor); |
237 | } | 238 | } |
@@ -244,85 +245,77 @@ static void draw_screen(struct screen *display, char *title, | |||
244 | bg = prim_rgb[SB_FILL][i]; | 245 | bg = prim_rgb[SB_FILL][i]; |
245 | } | 246 | } |
246 | } | 247 | } |
248 | else if (!display_three_rows) | ||
249 | continue; | ||
247 | 250 | ||
248 | set_drawinfo(display, mode, fg, bg); | 251 | set_drawinfo(display, mode, fg, bg); |
249 | 252 | ||
250 | /* Draw label */ | 253 | /* Draw label */ |
251 | buf[0] = str(LANG_COLOR_RGB_LABELS)[i]; | 254 | buf[0] = str(LANG_COLOR_RGB_LABELS)[i]; |
252 | buf[1] = '\0'; | 255 | buf[1] = '\0'; |
253 | display->putsxy(slider_left - max_label_width - | 256 | vp.flags &= ~VP_FLAG_ALIGNMENT_MASK; |
254 | SLIDER_MARGIN_LEFT, text_top, buf); | 257 | display->putsxy(text_x, text_top, buf); |
255 | |||
256 | /* Draw color value */ | 258 | /* Draw color value */ |
257 | snprintf(buf, 3, "%02d", rgb->rgb_val[i]); | 259 | snprintf(buf, 3, "%02d", rgb->rgb_val[i]); |
258 | display->putsxy(slider_left + slider_width + SLIDER_MARGIN_RIGHT, | 260 | vp.flags |= VP_FLAG_IS_RTL; |
259 | text_top, buf); | 261 | display->putsxy(text_x, text_top, buf); |
260 | 262 | ||
261 | /* Draw scrollbar */ | 263 | /* Draw scrollbar */ |
262 | gui_scrollbar_draw(display, | 264 | gui_scrollbar_draw(display, /* screen */ |
263 | slider_left, | 265 | slider_x, /* x */ |
264 | text_top + display->getcharheight() / 4, | 266 | text_top + display->getcharheight() / 4,/* y */ |
265 | slider_width, | 267 | slider_width, /* width */ |
266 | display->getcharheight() / 2, | 268 | display->getcharheight() / 2, /* height */ |
267 | rgb_max[i], | 269 | rgb_max[i], /* items */ |
268 | 0, | 270 | 0, /* min_shown */ |
269 | rgb->rgb_val[i], | 271 | rgb->rgb_val[i], /* max_shown */ |
270 | sb_flags); | 272 | sb_flags); /* flags */ |
271 | 273 | ||
272 | /* Advance to next line */ | 274 | /* Advance to next line */ |
273 | text_top += display->getcharheight() + 2*SELECTOR_TB_MARGIN; | 275 | text_top += line_height; |
274 | |||
275 | if (!display_three_rows) | ||
276 | break; | ||
277 | } /* end for */ | 276 | } /* end for */ |
278 | 277 | ||
279 | /* Format RGB: #rrggbb */ | 278 | /* Format RGB: #rrggbb */ |
280 | snprintf(buf, sizeof(buf), str(LANG_COLOR_RGB_VALUE), | 279 | snprintf(buf, sizeof(buf), str(LANG_COLOR_RGB_VALUE), |
281 | rgb->red, rgb->green, rgb->blue); | 280 | rgb->red, rgb->green, rgb->blue); |
282 | 281 | vp.flags |= VP_FLAG_CENTER_ALIGN; | |
283 | if (display->depth >= 16) | 282 | if (display->depth >= 16) |
284 | { | 283 | { |
285 | /* Display color swatch on color screens only */ | 284 | /* Display color swatch on color screens only */ |
286 | int left = MARGIN_LEFT + SELECTOR_WIDTH + SELECTOR_LR_MARGIN; | ||
287 | int top = text_top + SWATCH_TOP_MARGIN; | 285 | int top = text_top + SWATCH_TOP_MARGIN; |
288 | int width = vp.width - left - SELECTOR_LR_MARGIN - | 286 | int width = vp.width - text_x*2; |
289 | SELECTOR_WIDTH - MARGIN_RIGHT; | ||
290 | int height = vp.height - top - MARGIN_BOTTOM; | 287 | int height = vp.height - top - MARGIN_BOTTOM; |
291 | 288 | ||
292 | /* Only draw if room */ | 289 | /* Only draw if room */ |
293 | if (height >= display->getcharheight() + 2) | 290 | if (height >= display->getcharheight() + 2) |
294 | { | 291 | { |
292 | /* draw the big rectangle */ | ||
295 | display->set_foreground(rgb->color); | 293 | display->set_foreground(rgb->color); |
296 | display->fillrect(left, top, width, height); | 294 | display->fillrect(text_x, top, width, height); |
297 | 295 | ||
298 | /* Draw RGB: #rrggbb in middle of swatch */ | 296 | /* Draw RGB: #rrggbb in middle of swatch */ |
299 | display->set_drawmode(DRMODE_FG); | 297 | set_drawinfo(display, DRMODE_FG, get_black_or_white(rgb), |
300 | display->getstringsize(buf, &x, &y); | 298 | background_color); |
301 | display->set_foreground(get_black_or_white(rgb)); | 299 | display->getstringsize(buf, NULL, &y); |
302 | |||
303 | x = left + (width - x) / 2; | ||
304 | y = top + (height - y) / 2; | ||
305 | 300 | ||
306 | display->putsxy(x, y, buf); | 301 | display->putsxy(0, top + (height - y) / 2, buf); |
307 | display->set_drawmode(DRMODE_SOLID); | ||
308 | 302 | ||
309 | /* Draw border */ | 303 | /* Draw border around the rect */ |
310 | display->set_foreground(text_color); | 304 | set_drawinfo(display, DRMODE_SOLID, text_color, |
311 | display->drawrect(left, top, width, height); | 305 | background_color); |
306 | display->drawrect(text_x, top, width, height); | ||
312 | } | 307 | } |
313 | } | 308 | } |
314 | else | 309 | else |
315 | { | 310 | { |
316 | /* Display RGB value only centered on remaining display if room */ | 311 | /* Display RGB value only centered on remaining display if room */ |
317 | display->getstringsize(buf, &x, &y); | 312 | display->getstringsize(buf, NULL, &y); |
318 | i = text_top + SWATCH_TOP_MARGIN; | 313 | i = text_top + SWATCH_TOP_MARGIN; |
319 | 314 | ||
320 | if (i + y <= display->getheight() - MARGIN_BOTTOM) | 315 | if (i + y <= display->getheight() - MARGIN_BOTTOM) |
321 | { | 316 | { |
322 | set_drawinfo(display, DRMODE_SOLID, text_color, background_color); | 317 | set_drawinfo(display, DRMODE_SOLID, text_color, background_color); |
323 | x = (vp.width - x) / 2; | 318 | display->putsxy(0, (i + vp.height - MARGIN_BOTTOM - y) / 2, buf); |
324 | y = (i + vp.height - MARGIN_BOTTOM - y) / 2; | ||
325 | display->putsxy(x, y, buf); | ||
326 | } | 319 | } |
327 | } | 320 | } |
328 | 321 | ||
@@ -335,53 +328,55 @@ static void draw_screen(struct screen *display, char *title, | |||
335 | } | 328 | } |
336 | 329 | ||
337 | #ifdef HAVE_TOUCHSCREEN | 330 | #ifdef HAVE_TOUCHSCREEN |
338 | static int touchscreen_slider(struct rgb_pick *rgb, int *selected_slider) | 331 | static int touchscreen_slider(struct screen *display, |
332 | struct rgb_pick *rgb, | ||
333 | const char* title, | ||
334 | int *selected_slider) | ||
339 | { | 335 | { |
340 | short x,y; | 336 | short x,y; |
341 | int text_top,i,x1; | 337 | int text_top, slider_x, slider_width, title_height; |
342 | int slider_left, slider_width; | ||
343 | unsigned button = action_get_touchscreen_press(&x, &y); | 338 | unsigned button = action_get_touchscreen_press(&x, &y); |
344 | bool display_three_rows; | 339 | bool display_three_rows; |
345 | int max_label_width; | 340 | int max_label_width; |
346 | struct screen *display = &screens[SCREEN_MAIN]; | ||
347 | int pressed_slider; | 341 | int pressed_slider; |
348 | char buf[2]; | 342 | struct viewport vp; |
343 | int line_height; | ||
344 | |||
345 | viewport_set_defaults(&vp, display->screen_type); | ||
349 | 346 | ||
350 | if (button == BUTTON_NONE) | 347 | if (button == BUTTON_NONE) |
351 | return ACTION_NONE; | 348 | return ACTION_NONE; |
352 | /* same logic as draw_screen */ | 349 | |
353 | /* Figure out widest label character in case they vary - | 350 | max_label_width = label_get_max_width(display); |
354 | this function assumes labels are one character */ | 351 | display->getstringsize(title, NULL, &title_height); |
355 | for (i = 0, max_label_width = 0; i < 3; i++) | 352 | |
356 | { | 353 | /* Get slider positions and top starting position |
357 | buf[0] = str(LANG_COLOR_RGB_LABELS)[i]; | 354 | * need vp.y here, because of the statusbar, since touchscreen |
358 | buf[1] = '\0'; | 355 | * coordinates are absolute */ |
359 | x1 = display->getstringsize(buf, NULL, NULL); | 356 | text_top = vp.y + MARGIN_TOP + title_height + TITLE_MARGIN_BOTTOM + |
360 | if (x1 > max_label_width) | ||
361 | max_label_width = x1; | ||
362 | } | ||
363 | /* Get slider positions and top starting position */ | ||
364 | text_top = MARGIN_TOP + display->getcharheight() + TITLE_MARGIN_BOTTOM + | ||
365 | SELECTOR_TB_MARGIN; | 357 | SELECTOR_TB_MARGIN; |
366 | slider_left = MARGIN_LEFT + SELECTOR_WIDTH + SELECTOR_LR_MARGIN + | 358 | slider_x = SELECTOR_WIDTH + max_label_width + SLIDER_TEXT_MARGIN; |
367 | max_label_width + SLIDER_MARGIN_LEFT; | 359 | slider_width = vp.width - slider_x*2 - max_label_width; |
368 | slider_width = display->getwidth() - slider_left - SLIDER_MARGIN_RIGHT - | 360 | line_height = display->getcharheight() + 2*SELECTOR_TB_MARGIN; |
369 | display->getcharwidth()*2 - SELECTOR_LR_MARGIN - | 361 | |
370 | SELECTOR_WIDTH - MARGIN_RIGHT; | 362 | /* same logic as in draw_screen */ |
363 | /* Find out if there's enough room for three sliders or just | ||
364 | enough to display the selected slider - calculate total height | ||
365 | of display with three sliders present */ | ||
371 | display_three_rows = | 366 | display_three_rows = |
372 | display->getheight() >= | 367 | vp.height >= |
373 | MARGIN_TOP + | 368 | text_top + title_height*3 + /* Title + 3 sliders */ |
374 | display->getcharheight()*4 + /* Title + 3 sliders */ | 369 | SWATCH_TOP_MARGIN + /* at least 2 lines */ |
375 | TITLE_MARGIN_BOTTOM + | 370 | display->getcharheight()*2 + /* + margins for bottom */ |
376 | SELECTOR_TB_MARGIN*6 + /* 2 margins/slider */ | 371 | MARGIN_BOTTOM; /* colored rectangle */ |
377 | MARGIN_BOTTOM; | 372 | |
378 | if (y < MARGIN_TOP+display->getcharheight()) | 373 | if (y < text_top) |
379 | { | 374 | { |
380 | if (button == BUTTON_REL) | 375 | if (button == BUTTON_REL) |
381 | return ACTION_STD_CANCEL; | 376 | return ACTION_STD_CANCEL; |
382 | } | 377 | } |
383 | y -= text_top; | 378 | |
384 | pressed_slider = y/display->getcharheight(); | 379 | pressed_slider = (y - text_top)/line_height; |
385 | if (pressed_slider > (display_three_rows?2:0)) | 380 | if (pressed_slider > (display_three_rows?2:0)) |
386 | { | 381 | { |
387 | if (button == BUTTON_REL) | 382 | if (button == BUTTON_REL) |
@@ -389,12 +384,16 @@ static int touchscreen_slider(struct rgb_pick *rgb, int *selected_slider) | |||
389 | } | 384 | } |
390 | if (pressed_slider != *selected_slider) | 385 | if (pressed_slider != *selected_slider) |
391 | *selected_slider = pressed_slider; | 386 | *selected_slider = pressed_slider; |
392 | if (x < slider_left+slider_width && | 387 | /* add max_label_width to overcome integer division limits, |
393 | x > slider_left) | 388 | * cap value later since that may lead to an overflow */ |
389 | if (x < slider_x+(slider_width+max_label_width) && | ||
390 | x > slider_x) | ||
394 | { | 391 | { |
395 | x -= slider_left; | 392 | char computed_val; |
396 | rgb->rgb_val[pressed_slider] = | 393 | x -= slider_x; |
397 | (x*rgb_max[pressed_slider]/(slider_width-slider_left)); | 394 | computed_val = (x*rgb_max[pressed_slider]/(slider_width)); |
395 | rgb->rgb_val[pressed_slider] = | ||
396 | MIN(computed_val,rgb_max[pressed_slider]); | ||
398 | pack_rgb(rgb); | 397 | pack_rgb(rgb); |
399 | } | 398 | } |
400 | return ACTION_NONE; | 399 | return ACTION_NONE; |
@@ -433,8 +432,9 @@ bool set_color(struct screen *display, char *title, unsigned *color, | |||
433 | 432 | ||
434 | button = get_action(CONTEXT_SETTINGS_COLOURCHOOSER, TIMEOUT_BLOCK); | 433 | button = get_action(CONTEXT_SETTINGS_COLOURCHOOSER, TIMEOUT_BLOCK); |
435 | #ifdef HAVE_TOUCHSCREEN | 434 | #ifdef HAVE_TOUCHSCREEN |
436 | if (button == ACTION_TOUCHSCREEN) | 435 | if (button == ACTION_TOUCHSCREEN |
437 | button = touchscreen_slider(&rgb, &slider); | 436 | && display->screen_type == SCREEN_MAIN) |
437 | button = touchscreen_slider(display, &rgb, title, &slider); | ||
438 | #endif | 438 | #endif |
439 | 439 | ||
440 | switch (button) | 440 | switch (button) |