summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Low <lostlogic@rockbox.org>2007-06-17 21:16:34 +0000
committerBrandon Low <lostlogic@rockbox.org>2007-06-17 21:16:34 +0000
commit74cbb0a1b24a5d2e32d2667b236483b5e7253e98 (patch)
tree4a9bd83a01bbb822305e3a567362fb3b36dfc28b
parentb57806237d275b54380be5b73e3d783bd6972bf8 (diff)
downloadrockbox-74cbb0a1b24a5d2e32d2667b236483b5e7253e98.tar.gz
rockbox-74cbb0a1b24a5d2e32d2667b236483b5e7253e98.zip
Give color targets the ability to display each LCD line a different color and use this newfangled ability to provide themable colored file types. See the comments on read_color_theme_file and the sample.colors file provided for how to use this. .colors files go in themes directory for now. This separate line color function should be trivial to add to menus and wpss.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13656 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/filetypes.c58
-rw-r--r--apps/filetypes.h6
-rw-r--r--apps/gui/list.c75
-rw-r--r--apps/gui/list.h46
-rw-r--r--apps/misc.c33
-rw-r--r--apps/misc.h4
-rw-r--r--apps/settings.c37
-rw-r--r--apps/settings.h3
-rw-r--r--apps/settings_list.c4
-rw-r--r--apps/tree.c13
-rw-r--r--docs/FILES1
-rw-r--r--docs/sample.colors4
-rw-r--r--firmware/drivers/lcd-16bit.c9
-rw-r--r--firmware/export/lcd-remote.h4
-rw-r--r--firmware/export/lcd.h6
15 files changed, 227 insertions, 76 deletions
diff --git a/apps/filetypes.c b/apps/filetypes.c
index e826efc7dc..a6ccff32ba 100644
--- a/apps/filetypes.c
+++ b/apps/filetypes.c
@@ -34,12 +34,11 @@
34#include "plugin.h" 34#include "plugin.h"
35#include "filetypes.h" 35#include "filetypes.h"
36#include "screens.h" 36#include "screens.h"
37#include "icons.h"
38#include "dir.h" 37#include "dir.h"
39#include "file.h" 38#include "file.h"
40#include "icons.h"
41#include "splash.h" 39#include "splash.h"
42#include "buffer.h" 40#include "buffer.h"
41#include "icons.h"
43 42
44/* max filetypes (plugins & icons stored here) */ 43/* max filetypes (plugins & icons stored here) */
45#if CONFIG_CODEC == SWCODEC 44#if CONFIG_CODEC == SWCODEC
@@ -125,6 +124,9 @@ struct file_type {
125static struct file_type filetypes[MAX_FILETYPES]; 124static struct file_type filetypes[MAX_FILETYPES];
126static int custom_filetype_icons[MAX_FILETYPES]; 125static int custom_filetype_icons[MAX_FILETYPES];
127static bool custom_icons_loaded = false; 126static bool custom_icons_loaded = false;
127#ifdef HAVE_LCD_COLOR
128static int custom_colors[MAX_FILETYPES];
129#endif
128static int filetype_count = 0; 130static int filetype_count = 0;
129static unsigned char heighest_attr = 0; 131static unsigned char heighest_attr = 0;
130 132
@@ -136,6 +138,41 @@ static char *filetypes_strdup(char* string)
136} 138}
137static void read_builtin_types(void); 139static void read_builtin_types(void);
138static void read_config(char* config_file); 140static void read_config(char* config_file);
141#ifdef HAVE_LCD_COLOR
142/* Colors file format is similar to icons:
143 * ext:hex_color
144 * load a colors file from a theme with:
145 * filetype colors: filename.colors */
146void read_color_theme_file(void) {
147 char buffer[MAX_PATH];
148 int fd;
149 char *ext, *color;
150 int i;
151 for (i = 0; i < filetype_count; i++) {
152 custom_colors[i] = -1;
153 }
154 snprintf(buffer, MAX_PATH, "%s/%s.colors", THEME_DIR,
155 global_settings.colors_file);
156 fd = open(buffer, O_RDONLY);
157 if (fd < 0)
158 return;
159 while (read_line(fd, buffer, MAX_PATH) > 0)
160 {
161 if (!settings_parseline(buffer, &ext, &color))
162 continue;
163 for (i=0; i<filetype_count; i++)
164 {
165 if (filetypes[i].extension &&
166 !strcasecmp(ext, filetypes[i].extension))
167 {
168 custom_colors[i] = hex_to_rgb(color);
169 break;
170 }
171 }
172 }
173 close(fd);
174}
175#endif
139#ifdef HAVE_LCD_BITMAP 176#ifdef HAVE_LCD_BITMAP
140void read_viewer_theme_file(void) 177void read_viewer_theme_file(void)
141{ 178{
@@ -162,7 +199,8 @@ void read_viewer_theme_file(void)
162 continue; 199 continue;
163 for (i=0; i<filetype_count; i++) 200 for (i=0; i<filetype_count; i++)
164 { 201 {
165 if (filetypes[i].extension && !strcasecmp(ext, filetypes[i].extension)) 202 if (filetypes[i].extension &&
203 !strcasecmp(ext, filetypes[i].extension))
166 { 204 {
167 if (*icon == '*') 205 if (*icon == '*')
168 custom_filetype_icons[i] = atoi(icon+1); 206 custom_filetype_icons[i] = atoi(icon+1);
@@ -198,6 +236,9 @@ void filetype_init(void)
198#ifdef HAVE_LCD_BITMAP 236#ifdef HAVE_LCD_BITMAP
199 read_viewer_theme_file(); 237 read_viewer_theme_file();
200#endif 238#endif
239#ifdef HAVE_LCD_COLOR
240 read_color_theme_file();
241#endif
201} 242}
202 243
203/* remove all white spaces from string */ 244/* remove all white spaces from string */
@@ -327,6 +368,17 @@ static int find_attr(int attr)
327 return -1; 368 return -1;
328} 369}
329 370
371#ifdef HAVE_LCD_COLOR
372int filetype_get_color(int attr)
373{
374 int index = find_attr(attr);
375 if (index < 0)
376 return -1;
377 return custom_colors[index];
378 return -1;
379}
380#endif
381
330int filetype_get_icon(int attr) 382int filetype_get_icon(int attr)
331{ 383{
332 int index = find_attr(attr); 384 int index = find_attr(attr);
diff --git a/apps/filetypes.h b/apps/filetypes.h
index a38b4bc000..13f4e56161 100644
--- a/apps/filetypes.h
+++ b/apps/filetypes.h
@@ -53,9 +53,15 @@ void tree_get_filetypes(const struct filetype**, int*);
53 uses audio buffer for storage, so call early in init... */ 53 uses audio buffer for storage, so call early in init... */
54void filetype_init(void); 54void filetype_init(void);
55void read_viewer_theme_file(void); 55void read_viewer_theme_file(void);
56#ifdef HAVE_LCD_COLOR
57void read_color_theme_file(void);
58#endif
56 59
57/* Return the attribute (FILE_ATTR_*) of the file */ 60/* Return the attribute (FILE_ATTR_*) of the file */
58int filetype_get_attr(const char* file); 61int filetype_get_attr(const char* file);
62#ifdef HAVE_LCD_COLOR
63int filetype_get_color(int attr);
64#endif
59int filetype_get_icon(int attr); 65int filetype_get_icon(int attr);
60/* return the plugin filename associated with the file */ 66/* return the plugin filename associated with the file */
61char* filetype_get_plugin(const struct entry* file); 67char* filetype_get_plugin(const struct entry* file);
diff --git a/apps/gui/list.c b/apps/gui/list.c
index 1aa189d9bf..5e073cc93b 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -63,11 +63,11 @@ static void gui_list_select_at_offset(struct gui_list * gui_list, int offset);
63/* 63/*
64 * Initializes a scrolling list 64 * Initializes a scrolling list
65 * - gui_list : the list structure to initialize 65 * - gui_list : the list structure to initialize
66 * - callback_get_item_icon : pointer to a function that associates an icon
67 * to a given item number
68 * - callback_get_item_name : pointer to a function that associates a label 66 * - callback_get_item_name : pointer to a function that associates a label
69 * to a given item number 67 * to a given item number
70 * - data : extra data passed to the list callback 68 * - data : extra data passed to the list callback
69 * - scroll_all :
70 * - selected_size :
71 */ 71 */
72static void gui_list_init(struct gui_list * gui_list, 72static void gui_list_init(struct gui_list * gui_list,
73 list_get_name callback_get_item_name, 73 list_get_name callback_get_item_name,
@@ -97,6 +97,11 @@ static void gui_list_init(struct gui_list * gui_list,
97 gui_list->last_displayed_selected_item = -1 ; 97 gui_list->last_displayed_selected_item = -1 ;
98 gui_list->last_displayed_start_item = -1 ; 98 gui_list->last_displayed_start_item = -1 ;
99 gui_list->show_selection_marker = true; 99 gui_list->show_selection_marker = true;
100
101#ifdef HAVE_LCD_COLOR
102 gui_list->title_color = -1;
103 gui_list->callback_get_item_color = NULL;
104#endif
100} 105}
101 106
102/* this toggles the selection bar or cursor */ 107/* this toggles the selection bar or cursor */
@@ -274,13 +279,23 @@ static void gui_list_draw_smart(struct gui_list *gui_list)
274 } 279 }
275 280
276#ifdef HAVE_LCD_BITMAP 281#ifdef HAVE_LCD_BITMAP
282 int title_style = STYLE_DEFAULT;
283#ifdef HAVE_LCD_COLOR
284 if (gui_list->title_color >= 0)
285 {
286 title_style |= STYLE_COLORED;
287 title_style |= gui_list->title_color;
288 }
289#endif
277 screen_set_xmargin(display, text_pos); /* margin for title */ 290 screen_set_xmargin(display, text_pos); /* margin for title */
278 item_offset = gui_list_get_item_offset(gui_list, gui_list->title_width, 291 item_offset = gui_list_get_item_offset(gui_list, gui_list->title_width,
279 text_pos); 292 text_pos);
280 if (item_offset > gui_list->title_width - (display->width - text_pos)) 293 if (item_offset > gui_list->title_width - (display->width - text_pos))
281 display->puts_offset(0, 0, gui_list->title, item_offset); 294 display->puts_style_offset(0, 0, gui_list->title,
295 title_style, item_offset);
282 else 296 else
283 display->puts_scroll_offset(0, 0, gui_list->title, item_offset); 297 display->puts_scroll_style_offset(0, 0, gui_list->title,
298 title_style, item_offset);
284#else 299#else
285 display->puts_scroll(text_pos, 0, gui_list->title); 300 display->puts_scroll(text_pos, 0, gui_list->title);
286#endif 301#endif
@@ -333,6 +348,7 @@ static void gui_list_draw_smart(struct gui_list *gui_list)
333 unsigned char *entry_name; 348 unsigned char *entry_name;
334 int current_item = gui_list->start_item + 349 int current_item = gui_list->start_item +
335 (SHOW_LIST_TITLE ? i-1 : i); 350 (SHOW_LIST_TITLE ? i-1 : i);
351 int style = STYLE_DEFAULT;
336 352
337 /* When there are less items to display than the 353 /* When there are less items to display than the
338 * current available space on the screen, we stop*/ 354 * current available space on the screen, we stop*/
@@ -350,6 +366,21 @@ static void gui_list_draw_smart(struct gui_list *gui_list)
350 item_offset = gui_list_get_item_offset(gui_list, item_width, text_pos); 366 item_offset = gui_list_get_item_offset(gui_list, item_width, text_pos);
351#endif 367#endif
352 368
369#ifdef HAVE_LCD_COLOR
370 /* if the list has a color callback */
371 if (gui_list->callback_get_item_color)
372 {
373 int color = gui_list->callback_get_item_color(current_item,
374 gui_list->data);
375 /* if color selected */
376 if (color >= 0)
377 {
378 style |= STYLE_COLORED;
379 style |= color;
380 }
381 }
382#endif
383
353 if(gui_list->show_selection_marker && 384 if(gui_list->show_selection_marker &&
354 current_item >= gui_list->selected_item && 385 current_item >= gui_list->selected_item &&
355 current_item < gui_list->selected_item + gui_list->selected_size) 386 current_item < gui_list->selected_item + gui_list->selected_size)
@@ -357,29 +388,25 @@ static void gui_list_draw_smart(struct gui_list *gui_list)
357#ifdef HAVE_LCD_BITMAP 388#ifdef HAVE_LCD_BITMAP
358 if (global_settings.invert_cursor)/* Display inverted-line-style*/ 389 if (global_settings.invert_cursor)/* Display inverted-line-style*/
359 { 390 {
360 /* if text got out of view */ 391 style |= STYLE_INVERT;
361 if (item_offset > item_width - (display->width - text_pos))
362 {
363 /* don't scroll */
364 display->puts_style_offset(0, i, entry_name,
365 STYLE_INVERT,item_offset);
366 }
367 else
368 {
369 display->puts_scroll_style_offset(0, i, entry_name,
370 STYLE_INVERT,
371 item_offset);
372 }
373 } 392 }
374 else /* if (!global_settings.invert_cursor) */ 393 else /* if (!global_settings.invert_cursor) */
375 { 394 {
376 if (item_offset > item_width - (display->width - text_pos))
377 display->puts_offset(0, i, entry_name,item_offset);
378 else
379 display->puts_scroll_offset(0, i, entry_name,item_offset);
380 if (current_item % gui_list->selected_size != 0) 395 if (current_item % gui_list->selected_size != 0)
381 draw_cursor = false; 396 draw_cursor = false;
382 } 397 }
398 /* if the text is smaller than the viewport size */
399 if (item_offset > item_width - (display->width - text_pos))
400 {
401 /* don't scroll */
402 display->puts_style_offset(0, i, entry_name,
403 style, item_offset);
404 }
405 else
406 {
407 display->puts_scroll_style_offset(0, i, entry_name,
408 style, item_offset);
409 }
383#else 410#else
384 display->puts_scroll(text_pos, i, entry_name); 411 display->puts_scroll(text_pos, i, entry_name);
385#endif 412#endif
@@ -397,7 +424,8 @@ static void gui_list_draw_smart(struct gui_list *gui_list)
397 if(gui_list->scroll_all) 424 if(gui_list->scroll_all)
398 { 425 {
399#ifdef HAVE_LCD_BITMAP 426#ifdef HAVE_LCD_BITMAP
400 display->puts_scroll_offset(0, i, entry_name,item_offset); 427 display->puts_scroll_style_offset(0, i, entry_name,
428 style, item_offset);
401#else 429#else
402 display->puts_scroll(text_pos, i, entry_name); 430 display->puts_scroll(text_pos, i, entry_name);
403#endif 431#endif
@@ -405,7 +433,8 @@ static void gui_list_draw_smart(struct gui_list *gui_list)
405 else 433 else
406 { 434 {
407#ifdef HAVE_LCD_BITMAP 435#ifdef HAVE_LCD_BITMAP
408 display->puts_offset(0, i, entry_name,item_offset); 436 display->puts_style_offset(0, i, entry_name,
437 style, item_offset);
409#else 438#else
410 display->puts(text_pos, i, entry_name); 439 display->puts(text_pos, i, entry_name);
411#endif 440#endif
diff --git a/apps/gui/list.h b/apps/gui/list.h
index 021f55ef94..d0bc59b7bc 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -36,34 +36,43 @@ enum list_wrap {
36 * The gui_list is based on callback functions, if you want the list 36 * The gui_list is based on callback functions, if you want the list
37 * to display something you have to provide it a function that 37 * to display something you have to provide it a function that
38 * tells it what to display. 38 * tells it what to display.
39 * There are two callback function : 39 * There are three callback function :
40 * one to get the text and one to get the icon 40 * one to get the text, one to get the icon and one to get the color
41 */ 41 */
42 42
43/* 43/*
44 * Icon callback 44 * Icon callback
45 * - selected_item : an integer that tells the number of the item to display 45 * - selected_item : an integer that tells the number of the item to display
46 * - data : a void pointer to the data you gave to the list when 46 * - data : a void pointer to the data you gave to the list when you
47 * you initialized it 47 * initialized it
48 * - icon : a pointer to the icon, the value inside it is used to display 48 * Returns a pointer to the icon, the value inside it is used to display the
49 * the icon after the function returns. 49 * icon after the function returns.
50 * Note : we use the ICON type because the real type depends of the plateform 50 * Note : we use the ICON type because the real type depends of the plateform
51 */ 51 */
52typedef enum themable_icons list_get_icon(int selected_item, void * data); 52typedef enum themable_icons list_get_icon(int selected_item, void * data);
53/* 53/*
54 * Text callback 54 * Text callback
55 * - selected_item : an integer that tells the number of the item to display 55 * - selected_item : an integer that tells the number of the item to display
56 * - data : a void pointer to the data you gave to the list when 56 * - data : a void pointer to the data you gave to the list when you
57 * you initialized it 57 * initialized it
58 * - buffer : a buffer to put the resulting text on it 58 * - buffer : a buffer to put the resulting text on it
59 * (The content of the buffer may not be used by the list, we use 59 * (The content of the buffer may not be used by the list, we use
60 * the return value of the function in all cases to avoid filling 60 * the return value of the function in all cases to avoid filling
61 * a buffer when it's not necessary) 61 * a buffer when it's not necessary)
62 * Returns a pointer to a string that contains the text to display 62 * Returns a pointer to a string that contains the text to display
63 */ 63 */
64typedef char * list_get_name(int selected_item, 64typedef char * list_get_name(int selected_item, void * data, char * buffer);
65 void * data, 65#ifdef HAVE_LCD_COLOR
66 char *buffer); 66/*
67 * Color callback
68 * - selected_item : an integer that tells the number of the item to display
69 * - data : a void pointer to the data you gave to the list when you
70 * initialized it
71 * Returns an int with the lower 16 bits representing the color to display the
72 * selected item, negative value for default coloring.
73 */
74typedef int list_get_color(int selected_item, void * data);
75#endif
67 76
68struct gui_list 77struct gui_list
69{ 78{
@@ -101,6 +110,11 @@ struct gui_list
101 /* Optional title icon */ 110 /* Optional title icon */
102 enum themable_icons title_icon; 111 enum themable_icons title_icon;
103 bool show_selection_marker; /* set to true by default */ 112 bool show_selection_marker; /* set to true by default */
113
114#ifdef HAVE_LCD_COLOR
115 int title_color;
116 list_get_color *callback_get_item_color;
117#endif
104}; 118};
105 119
106/* 120/*
@@ -127,6 +141,16 @@ struct gui_list
127#define gui_list_set_icon_callback(gui_list, _callback) \ 141#define gui_list_set_icon_callback(gui_list, _callback) \
128 (gui_list)->callback_get_item_icon=_callback 142 (gui_list)->callback_get_item_icon=_callback
129 143
144#ifdef HAVE_LCD_COLOR
145/*
146 * Sets the color callback function
147 * - gui_list : the list structure
148 * - _callback : the callback function
149 */
150#define gui_list_set_color_callback(gui_list, _callback) \
151 (gui_list)->callback_get_item_color=_callback
152#endif
153
130/* 154/*
131 * Gives the position of the selected item 155 * Gives the position of the selected item
132 * - gui_list : the list structure 156 * - gui_list : the list structure
diff --git a/apps/misc.c b/apps/misc.c
index 0113825ac4..6187cf425b 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -984,3 +984,36 @@ void setvol(void)
984 settings_save(); 984 settings_save();
985} 985}
986 986
987#ifdef HAVE_LCD_COLOR
988/*
989 * Helper function to convert a string of 6 hex digits to a native colour
990 */
991
992#define hex2dec(c) (((c) >= '0' && ((c) <= '9')) ? (toupper(c)) - '0' : \
993 (toupper(c)) - 'A' + 10)
994
995int hex_to_rgb(const char* hex)
996{ int ok = 1;
997 int i;
998 int red, green, blue;
999
1000 if (strlen(hex) == 6) {
1001 for (i=0; i < 6; i++ ) {
1002 if (!isxdigit(hex[i])) {
1003 ok=0;
1004 break;
1005 }
1006 }
1007
1008 if (ok) {
1009 red = (hex2dec(hex[0]) << 4) | hex2dec(hex[1]);
1010 green = (hex2dec(hex[2]) << 4) | hex2dec(hex[3]);
1011 blue = (hex2dec(hex[4]) << 4) | hex2dec(hex[5]);
1012 return LCD_RGBPACK(red,green,blue);
1013 }
1014 }
1015
1016 return 0;
1017}
1018#endif /* HAVE_LCD_COLOR */
1019
diff --git a/apps/misc.h b/apps/misc.h
index 926170ebe5..b0adb92a0e 100644
--- a/apps/misc.h
+++ b/apps/misc.h
@@ -109,4 +109,8 @@ void check_bootfile(bool do_rolo);
109/* check range, set volume and save settings */ 109/* check range, set volume and save settings */
110void setvol(void); 110void setvol(void);
111 111
112#ifdef HAVE_LCD_COLOR
113int hex_to_rgb(const char* hex);
114#endif
115
112#endif /* MISC_H */ 116#endif /* MISC_H */
diff --git a/apps/settings.c b/apps/settings.c
index 09c90af066..11d719f3f3 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -227,38 +227,6 @@ void settings_load(int which)
227 settings_load_config(FIXEDSETTINGSFILE,false); 227 settings_load_config(FIXEDSETTINGSFILE,false);
228 } 228 }
229} 229}
230#ifdef HAVE_LCD_COLOR
231/*
232 * Helper function to convert a string of 6 hex digits to a native colour
233 */
234
235#define hex2dec(c) (((c) >= '0' && ((c) <= '9')) ? (toupper(c)) - '0' : \
236 (toupper(c)) - 'A' + 10)
237
238static int hex_to_rgb(const char* hex)
239{ int ok = 1;
240 int i;
241 int red, green, blue;
242
243 if (strlen(hex) == 6) {
244 for (i=0; i < 6; i++ ) {
245 if (!isxdigit(hex[i])) {
246 ok=0;
247 break;
248 }
249 }
250
251 if (ok) {
252 red = (hex2dec(hex[0]) << 4) | hex2dec(hex[1]);
253 green = (hex2dec(hex[2]) << 4) | hex2dec(hex[3]);
254 blue = (hex2dec(hex[4]) << 4) | hex2dec(hex[5]);
255 return LCD_RGBPACK(red,green,blue);
256 }
257 }
258
259 return 0;
260}
261#endif /* HAVE_LCD_COLOR */
262 230
263static bool cfg_string_to_int(int setting_id, int* out, char* str) 231static bool cfg_string_to_int(int setting_id, int* out, char* str)
264{ 232{
@@ -891,6 +859,11 @@ void settings_apply(void)
891#endif 859#endif
892 /* load the icon set */ 860 /* load the icon set */
893 icons_init(); 861 icons_init();
862
863#ifdef HAVE_LCD_COLOR
864 if (global_settings.colors_file)
865 read_color_theme_file();
866#endif
894 867
895} 868}
896 869
diff --git a/apps/settings.h b/apps/settings.h
index 4761ba4bfc..05e3ada41d 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -725,6 +725,9 @@ struct user_settings
725 unsigned char remote_icon_file[MAX_FILENAME+1]; 725 unsigned char remote_icon_file[MAX_FILENAME+1];
726 unsigned char remote_viewers_icon_file[MAX_FILENAME+1]; 726 unsigned char remote_viewers_icon_file[MAX_FILENAME+1];
727#endif 727#endif
728#ifdef HAVE_LCD_COLOR
729 unsigned char colors_file[MAX_FILENAME+1];
730#endif
728#ifdef HAVE_BUTTON_LIGHT 731#ifdef HAVE_BUTTON_LIGHT
729 int button_light_timeout; 732 int button_light_timeout;
730#endif 733#endif
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 91c4cabe1b..fb9ac17539 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1214,6 +1214,10 @@ const struct settings_list settings[] = {
1214 "remote viewers iconset", "", 1214 "remote viewers iconset", "",
1215 ICON_DIR "/", ".bmp", MAX_FILENAME+1), 1215 ICON_DIR "/", ".bmp", MAX_FILENAME+1),
1216#endif /* HAVE_REMOTE_LCD */ 1216#endif /* HAVE_REMOTE_LCD */
1217#ifdef HAVE_LCD_COLOR
1218 FILENAME_SETTING(F_THEMESETTING, colors_file, "filetype colors", "",
1219 THEME_DIR "/", ".colors", MAX_FILENAME+1),
1220#endif
1217#ifdef HAVE_BUTTON_LIGHT 1221#ifdef HAVE_BUTTON_LIGHT
1218 INT_SETTING_W_CFGVALS(F_FLIPLIST, button_light_timeout, 1222 INT_SETTING_W_CFGVALS(F_FLIPLIST, button_light_timeout,
1219 LANG_BUTTONLIGHT_TIMEOUT, 6, 1223 LANG_BUTTONLIGHT_TIMEOUT, 6,
diff --git a/apps/tree.c b/apps/tree.c
index 1f76994968..a790400754 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -165,6 +165,15 @@ static char * tree_get_filename(int selected_item, void * data, char *buffer)
165 return(name); 165 return(name);
166} 166}
167 167
168#ifdef HAVE_LCD_COLOR
169static int tree_get_filecolor(int selected_item, void * data)
170{
171 struct tree_context * local_tc=(struct tree_context *)data;
172 struct entry* dc = local_tc->dircache;
173 struct entry* e = &dc[selected_item];
174 return filetype_get_color(e->attr);
175}
176#endif
168 177
169static int tree_get_fileicon(int selected_item, void * data) 178static int tree_get_fileicon(int selected_item, void * data)
170{ 179{
@@ -223,6 +232,10 @@ void tree_gui_init(void)
223#endif 232#endif
224 gui_synclist_init(&tree_lists, &tree_get_filename, &tc, false, 1); 233 gui_synclist_init(&tree_lists, &tree_get_filename, &tc, false, 1);
225 gui_synclist_set_icon_callback(&tree_lists, &tree_get_fileicon); 234 gui_synclist_set_icon_callback(&tree_lists, &tree_get_fileicon);
235#ifdef HAVE_LCD_COLOR
236 gui_list_set_color_callback(&tree_lists.gui_list[SCREEN_MAIN],
237 &tree_get_filecolor);
238#endif
226} 239}
227 240
228 241
diff --git a/docs/FILES b/docs/FILES
index 6eab98d824..80e27a2e51 100644
--- a/docs/FILES
+++ b/docs/FILES
@@ -14,3 +14,4 @@ README
14TECH 14TECH
15UISIMULATOR 15UISIMULATOR
16KNOWN_ISSUES 16KNOWN_ISSUES
17sample.colors
diff --git a/docs/sample.colors b/docs/sample.colors
new file mode 100644
index 0000000000..2f90dee125
--- /dev/null
+++ b/docs/sample.colors
@@ -0,0 +1,4 @@
1mp3:904010
2ogg:D04040
3txt:FF0000
4cfg:00FF00
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 44e42ad617..16c97c9e99 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -807,6 +807,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style,
807{ 807{
808 int xpos,ypos,w,h,xrect; 808 int xpos,ypos,w,h,xrect;
809 int lastmode = drawmode; 809 int lastmode = drawmode;
810 int oldcolor = fg_pattern;
810 811
811 /* make sure scrolling is turned off on the line we are updating */ 812 /* make sure scrolling is turned off on the line we are updating */
812 scrolling_lines &= ~(1 << y); 813 scrolling_lines &= ~(1 << y);
@@ -819,11 +820,15 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style,
819 ypos = ymargin + y*h; 820 ypos = ymargin + y*h;
820 drawmode = (style & STYLE_INVERT) ? 821 drawmode = (style & STYLE_INVERT) ?
821 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; 822 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
823 if (drawmode == DRMODE_SOLID && style & STYLE_COLORED) {
824 fg_pattern = style & STYLE_COLOR_MASK;
825 }
822 lcd_putsxyofs(xpos, ypos, offset, str); 826 lcd_putsxyofs(xpos, ypos, offset, str);
823 drawmode ^= DRMODE_INVERSEVID; 827 drawmode ^= DRMODE_INVERSEVID;
824 xrect = xpos + MAX(w - offset, 0); 828 xrect = xpos + MAX(w - offset, 0);
825 lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h); 829 lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h);
826 drawmode = lastmode; 830 drawmode = lastmode;
831 fg_pattern = oldcolor;
827} 832}
828 833
829/*** scrolling ***/ 834/*** scrolling ***/
@@ -896,10 +901,8 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
896 s->invert = false; 901 s->invert = false;
897 if (style & STYLE_INVERT) { 902 if (style & STYLE_INVERT) {
898 s->invert = true; 903 s->invert = true;
899 lcd_puts_style_offset(x,y,string,STYLE_INVERT,offset);
900 } 904 }
901 else 905 lcd_puts_style_offset(x,y,string,style,offset);
902 lcd_puts_offset(x,y,string,offset);
903 906
904 lcd_getstringsize(string, &w, &h); 907 lcd_getstringsize(string, &w, &h);
905 908
diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h
index ad311a8255..cfb643ff96 100644
--- a/firmware/export/lcd-remote.h
+++ b/firmware/export/lcd-remote.h
@@ -43,8 +43,8 @@ int remote_type(void);
43extern struct event_queue remote_scroll_queue; 43extern struct event_queue remote_scroll_queue;
44#endif 44#endif
45 45
46#define STYLE_DEFAULT 0 46#define STYLE_DEFAULT 0x00000000
47#define STYLE_INVERT 1 47#define STYLE_INVERT 0x20000000
48 48
49#if LCD_REMOTE_DEPTH <= 8 49#if LCD_REMOTE_DEPTH <= 8
50#if (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED) \ 50#if (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED) \
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 077664040e..cebcf54c9b 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -24,8 +24,10 @@
24#include "cpu.h" 24#include "cpu.h"
25#include "config.h" 25#include "config.h"
26 26
27#define STYLE_DEFAULT 0 27#define STYLE_DEFAULT 0x00000000
28#define STYLE_INVERT 1 28#define STYLE_INVERT 0x20000000
29#define STYLE_COLORED 0x10000000
30#define STYLE_COLOR_MASK 0x0000FFFF
29 31
30#ifdef SIMULATOR 32#ifdef SIMULATOR
31#ifndef MAX_PATH 33#ifndef MAX_PATH