diff options
| -rw-r--r-- | apps/filetypes.c | 58 | ||||
| -rw-r--r-- | apps/filetypes.h | 6 | ||||
| -rw-r--r-- | apps/gui/list.c | 75 | ||||
| -rw-r--r-- | apps/gui/list.h | 46 | ||||
| -rw-r--r-- | apps/misc.c | 33 | ||||
| -rw-r--r-- | apps/misc.h | 4 | ||||
| -rw-r--r-- | apps/settings.c | 37 | ||||
| -rw-r--r-- | apps/settings.h | 3 | ||||
| -rw-r--r-- | apps/settings_list.c | 4 | ||||
| -rw-r--r-- | apps/tree.c | 13 | ||||
| -rw-r--r-- | docs/FILES | 1 | ||||
| -rw-r--r-- | docs/sample.colors | 4 | ||||
| -rw-r--r-- | firmware/drivers/lcd-16bit.c | 9 | ||||
| -rw-r--r-- | firmware/export/lcd-remote.h | 4 | ||||
| -rw-r--r-- | firmware/export/lcd.h | 6 |
15 files changed, 227 insertions, 76 deletions
diff --git a/apps/filetypes.c b/apps/filetypes.c index e826efc..a6ccff3 100644 --- a/apps/filetypes.c +++ b/apps/filetypes.c @@ -34,12 +34,11 @@ #include "plugin.h" #include "filetypes.h" #include "screens.h" -#include "icons.h" #include "dir.h" #include "file.h" -#include "icons.h" #include "splash.h" #include "buffer.h" +#include "icons.h" /* max filetypes (plugins & icons stored here) */ #if CONFIG_CODEC == SWCODEC @@ -125,6 +124,9 @@ struct file_type { static struct file_type filetypes[MAX_FILETYPES]; static int custom_filetype_icons[MAX_FILETYPES]; static bool custom_icons_loaded = false; +#ifdef HAVE_LCD_COLOR +static int custom_colors[MAX_FILETYPES]; +#endif static int filetype_count = 0; static unsigned char heighest_attr = 0; @@ -136,6 +138,41 @@ static char *filetypes_strdup(char* string) } static void read_builtin_types(void); static void read_config(char* config_file); +#ifdef HAVE_LCD_COLOR +/* Colors file format is similar to icons: + * ext:hex_color + * load a colors file from a theme with: + * filetype colors: filename.colors */ +void read_color_theme_file(void) { + char buffer[MAX_PATH]; + int fd; + char *ext, *color; + int i; + for (i = 0; i < filetype_count; i++) { + custom_colors[i] = -1; + } + snprintf(buffer, MAX_PATH, "%s/%s.colors", THEME_DIR, + global_settings.colors_file); + fd = open(buffer, O_RDONLY); + if (fd < 0) + return; + while (read_line(fd, buffer, MAX_PATH) > 0) + { + if (!settings_parseline(buffer, &ext, &color)) + continue; + for (i=0; i<filetype_count; i++) + { + if (filetypes[i].extension && + !strcasecmp(ext, filetypes[i].extension)) + { + custom_colors[i] = hex_to_rgb(color); + break; + } + } + } + close(fd); +} +#endif #ifdef HAVE_LCD_BITMAP void read_viewer_theme_file(void) { @@ -162,7 +199,8 @@ void read_viewer_theme_file(void) continue; for (i=0; i<filetype_count; i++) { - if (filetypes[i].extension && !strcasecmp(ext, filetypes[i].extension)) + if (filetypes[i].extension && + !strcasecmp(ext, filetypes[i].extension)) { if (*icon == '*') custom_filetype_icons[i] = atoi(icon+1); @@ -198,6 +236,9 @@ void filetype_init(void) #ifdef HAVE_LCD_BITMAP read_viewer_theme_file(); #endif +#ifdef HAVE_LCD_COLOR + read_color_theme_file(); +#endif } /* remove all white spaces from string */ @@ -327,6 +368,17 @@ static int find_attr(int attr) return -1; } +#ifdef HAVE_LCD_COLOR +int filetype_get_color(int attr) +{ + int index = find_attr(attr); + if (index < 0) + return -1; + return custom_colors[index]; + return -1; +} +#endif + int filetype_get_icon(int attr) { int index = find_attr(attr); diff --git a/apps/filetypes.h b/apps/filetypes.h index a38b4bc..13f4e56 100644 --- a/apps/filetypes.h +++ b/apps/filetypes.h @@ -53,9 +53,15 @@ void tree_get_filetypes(const struct filetype**, int*); uses audio buffer for storage, so call early in init... */ void filetype_init(void); void read_viewer_theme_file(void); +#ifdef HAVE_LCD_COLOR +void read_color_theme_file(void); +#endif /* Return the attribute (FILE_ATTR_*) of the file */ int filetype_get_attr(const char* file); +#ifdef HAVE_LCD_COLOR +int filetype_get_color(int attr); +#endif int filetype_get_icon(int attr); /* return the plugin filename associated with the file */ char* filetype_get_plugin(const struct entry* file); diff --git a/apps/gui/list.c b/apps/gui/list.c index 1aa189d..5e073cc 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); /* * Initializes a scrolling list * - gui_list : the list structure to initialize - * - callback_get_item_icon : pointer to a function that associates an icon - * to a given item number * - callback_get_item_name : pointer to a function that associates a label * to a given item number * - data : extra data passed to the list callback + * - scroll_all : + * - selected_size : */ static void gui_list_init(struct gui_list * gui_list, list_get_name callback_get_item_name, @@ -97,6 +97,11 @@ static void gui_list_init(struct gui_list * gui_list, gui_list->last_displayed_selected_item = -1 ; gui_list->last_displayed_start_item = -1 ; gui_list->show_selection_marker = true; + +#ifdef HAVE_LCD_COLOR + gui_list->title_color = -1; + gui_list->callback_get_item_color = NULL; +#endif } /* this toggles the selection bar or cursor */ @@ -274,13 +279,23 @@ static void gui_list_draw_smart(struct gui_list *gui_list) } #ifdef HAVE_LCD_BITMAP + int title_style = STYLE_DEFAULT; +#ifdef HAVE_LCD_COLOR + if (gui_list->title_color >= 0) + { + title_style |= STYLE_COLORED; + title_style |= gui_list->title_color; + } +#endif screen_set_xmargin(display, text_pos); /* margin for title */ item_offset = gui_list_get_item_offset(gui_list, gui_list->title_width, text_pos); if (item_offset > gui_list->title_width - (display->width - text_pos)) - display->puts_offset(0, 0, gui_list->title, item_offset); + display->puts_style_offset(0, 0, gui_list->title, + title_style, item_offset); else - display->puts_scroll_offset(0, 0, gui_list->title, item_offset); + display->puts_scroll_style_offset(0, 0, gui_list->title, + title_style, item_offset); #else display->puts_scroll(text_pos, 0, gui_list->title); #endif @@ -333,6 +348,7 @@ static void gui_list_draw_smart(struct gui_list *gui_list) unsigned char *entry_name; int current_item = gui_list->start_item + (SHOW_LIST_TITLE ? i-1 : i); + int style = STYLE_DEFAULT; /* When there are less items to display than the * current available space on the screen, we stop*/ @@ -350,6 +366,21 @@ static void gui_list_draw_smart(struct gui_list *gui_list) item_offset = gui_list_get_item_offset(gui_list, item_width, text_pos); #endif +#ifdef HAVE_LCD_COLOR + /* if the list has a color callback */ + if (gui_list->callback_get_item_color) + { + int color = gui_list->callback_get_item_color(current_item, + gui_list->data); + /* if color selected */ + if (color >= 0) + { + style |= STYLE_COLORED; + style |= color; + } + } +#endif + if(gui_list->show_selection_marker && current_item >= gui_list->selected_item && 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) #ifdef HAVE_LCD_BITMAP if (global_settings.invert_cursor)/* Display inverted-line-style*/ { - /* if text got out of view */ - if (item_offset > item_width - (display->width - text_pos)) - { - /* don't scroll */ - display->puts_style_offset(0, i, entry_name, - STYLE_INVERT,item_offset); - } - else - { - display->puts_scroll_style_offset(0, i, entry_name, - STYLE_INVERT, - item_offset); - } + style |= STYLE_INVERT; } else /* if (!global_settings.invert_cursor) */ { - if (item_offset > item_width - (display->width - text_pos)) - display->puts_offset(0, i, entry_name,item_offset); - else - display->puts_scroll_offset(0, i, entry_name,item_offset); if (current_item % gui_list->selected_size != 0) draw_cursor = false; } + /* if the text is smaller than the viewport size */ + if (item_offset > item_width - (display->width - text_pos)) + { + /* don't scroll */ + display->puts_style_offset(0, i, entry_name, + style, item_offset); + } + else + { + display->puts_scroll_style_offset(0, i, entry_name, + style, item_offset); + } #else display->puts_scroll(text_pos, i, entry_name); #endif @@ -397,7 +424,8 @@ static void gui_list_draw_smart(struct gui_list *gui_list) if(gui_list->scroll_all) { #ifdef HAVE_LCD_BITMAP - display->puts_scroll_offset(0, i, entry_name,item_offset); + display->puts_scroll_style_offset(0, i, entry_name, + style, item_offset); #else display->puts_scroll(text_pos, i, entry_name); #endif @@ -405,7 +433,8 @@ static void gui_list_draw_smart(struct gui_list *gui_list) else { #ifdef HAVE_LCD_BITMAP - display->puts_offset(0, i, entry_name,item_offset); + display->puts_style_offset(0, i, entry_name, + style, item_offset); #else display->puts(text_pos, i, entry_name); #endif diff --git a/apps/gui/list.h b/apps/gui/list.h index 021f55e..d0bc59b 100644 --- a/apps/gui/list.h +++ b/apps/gui/list.h @@ -36,34 +36,43 @@ enum list_wrap { * The gui_list is based on callback functions, if you want the list * to display something you have to provide it a function that * tells it what to display. - * There are two callback function : - * one to get the text and one to get the icon + * There are three callback function : + * one to get the text, one to get the icon and one to get the color */ /* * Icon callback * - selected_item : an integer that tells the number of the item to display - * - data : a void pointer to the data you gave to the list when - * you initialized it - * - icon : a pointer to the icon, the value inside it is used to display - * the icon after the function returns. + * - data : a void pointer to the data you gave to the list when you + * initialized it + * Returns a pointer to the icon, the value inside it is used to display the + * icon after the function returns. * Note : we use the ICON type because the real type depends of the plateform */ typedef enum themable_icons list_get_icon(int selected_item, void * data); /* * Text callback * - selected_item : an integer that tells the number of the item to display - * - data : a void pointer to the data you gave to the list when - * you initialized it + * - data : a void pointer to the data you gave to the list when you + * initialized it * - buffer : a buffer to put the resulting text on it * (The content of the buffer may not be used by the list, we use * the return value of the function in all cases to avoid filling * a buffer when it's not necessary) * Returns a pointer to a string that contains the text to display */ -typedef char * list_get_name(int selected_item, - void * data, - char *buffer); +typedef char * list_get_name(int selected_item, void * data, char * buffer); +#ifdef HAVE_LCD_COLOR +/* + * Color callback + * - selected_item : an integer that tells the number of the item to display + * - data : a void pointer to the data you gave to the list when you + * initialized it + * Returns an int with the lower 16 bits representing the color to display the + * selected item, negative value for default coloring. + */ +typedef int list_get_color(int selected_item, void * data); +#endif struct gui_list { @@ -101,6 +110,11 @@ struct gui_list /* Optional title icon */ enum themable_icons title_icon; bool show_selection_marker; /* set to true by default */ + +#ifdef HAVE_LCD_COLOR + int title_color; + list_get_color *callback_get_item_color; +#endif }; /* @@ -127,6 +141,16 @@ struct gui_list #define gui_list_set_icon_callback(gui_list, _callback) \ (gui_list)->callback_get_item_icon=_callback +#ifdef HAVE_LCD_COLOR +/* + * Sets the color callback function + * - gui_list : the list structure + * - _callback : the callback function + */ +#define gui_list_set_color_callback(gui_list, _callback) \ + (gui_list)->callback_get_item_color=_callback +#endif + /* * Gives the position of the selected item * - gui_list : the list structure diff --git a/apps/misc.c b/apps/misc.c index 0113825..6187cf4 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -984,3 +984,36 @@ void setvol(void) settings_save(); } +#ifdef HAVE_LCD_COLOR +/* + * Helper function to convert a string of 6 hex digits to a native colour + */ + +#define hex2dec(c) (((c) >= '0' && ((c) <= '9')) ? (toupper(c)) - '0' : \ + (toupper(c)) - 'A' + 10) + +int hex_to_rgb(const char* hex) +{ int ok = 1; + int i; + int red, green, blue; + + if (strlen(hex) == 6) { + for (i=0; i < 6; i++ ) { + if (!isxdigit(hex[i])) { + ok=0; + break; + } + } + + if (ok) { + red = (hex2dec(hex[0]) << 4) | hex2dec(hex[1]); + green = (hex2dec(hex[2]) << 4) | hex2dec(hex[3]); + blue = (hex2dec(hex[4]) << 4) | hex2dec(hex[5]); + return LCD_RGBPACK(red,green,blue); + } + } + + return 0; +} +#endif /* HAVE_LCD_COLOR */ + diff --git a/apps/misc.h b/apps/misc.h index 926170e..b0adb92 100644 --- a/apps/misc.h +++ b/apps/misc.h @@ -109,4 +109,8 @@ void check_bootfile(bool do_rolo); /* check range, set volume and save settings */ void setvol(void); +#ifdef HAVE_LCD_COLOR +int hex_to_rgb(const char* hex); +#endif + #endif /* MISC_H */ diff --git a/apps/settings.c b/apps/settings.c index 09c90af..11d719f 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -227,38 +227,6 @@ void settings_load(int which) settings_load_config(FIXEDSETTINGSFILE,false); } } -#ifdef HAVE_LCD_COLOR -/* - * Helper function to convert a string of 6 hex digits to a native colour - */ - -#define hex2dec(c) (((c) >= '0' && ((c) <= '9')) ? (toupper(c)) - '0' : \ - (toupper(c)) - 'A' + 10) - -static int hex_to_rgb(const char* hex) -{ int ok = 1; - int i; - int red, green, blue; - - if (strlen(hex) == 6) { - for (i=0; i < 6; i++ ) { - if (!isxdigit(hex[i])) { - ok=0; - break; - } - } - - if (ok) { - red = (hex2dec(hex[0]) << 4) | hex2dec(hex[1]); - green = (hex2dec(hex[2]) << 4) | hex2dec(hex[3]); - blue = (hex2dec(hex[4]) << 4) | hex2dec(hex[5]); - return LCD_RGBPACK(red,green,blue); - } - } - - return 0; -} -#endif /* HAVE_LCD_COLOR */ static bool cfg_string_to_int(int setting_id, int* out, char* str) { @@ -891,6 +859,11 @@ void settings_apply(void) #endif /* load the icon set */ icons_init(); + +#ifdef HAVE_LCD_COLOR + if (global_settings.colors_file) + read_color_theme_file(); +#endif } diff --git a/apps/settings.h b/apps/settings.h index 4761ba4..05e3ada 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -725,6 +725,9 @@ struct user_settings unsigned char remote_icon_file[MAX_FILENAME+1]; unsigned char remote_viewers_icon_file[MAX_FILENAME+1]; #endif +#ifdef HAVE_LCD_COLOR + unsigned char colors_file[MAX_FILENAME+1]; +#endif #ifdef HAVE_BUTTON_LIGHT int button_light_timeout; #endif diff --git a/apps/settings_list.c b/apps/settings_list.c index 91c4cab..fb9ac17 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -1214,6 +1214,10 @@ const struct settings_list settings[] = { "remote viewers iconset", "", ICON_DIR "/", ".bmp", MAX_FILENAME+1), #endif /* HAVE_REMOTE_LCD */ +#ifdef HAVE_LCD_COLOR + FILENAME_SETTING(F_THEMESETTING, colors_file, "filetype colors", "", + THEME_DIR "/", ".colors", MAX_FILENAME+1), +#endif #ifdef HAVE_BUTTON_LIGHT INT_SETTING_W_CFGVALS(F_FLIPLIST, button_light_timeout, LANG_BUTTONLIGHT_TIMEOUT, 6, diff --git a/apps/tree.c b/apps/tree.c index 1f76994..a790400 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) return(name); } +#ifdef HAVE_LCD_COLOR +static int tree_get_filecolor(int selected_item, void * data) +{ + struct tree_context * local_tc=(struct tree_context *)data; + struct entry* dc = local_tc->dircache; + struct entry* e = &dc[selected_item]; + return filetype_get_color(e->attr); +} +#endif static int tree_get_fileicon(int selected_item, void * data) { @@ -223,6 +232,10 @@ void tree_gui_init(void) #endif gui_synclist_init(&tree_lists, &tree_get_filename, &tc, false, 1); gui_synclist_set_icon_callback(&tree_lists, &tree_get_fileicon); +#ifdef HAVE_LCD_COLOR + gui_list_set_color_callback(&tree_lists.gui_list[SCREEN_MAIN], + &tree_get_filecolor); +#endif } @@ -14,3 +14,4 @@ README TECH UISIMULATOR KNOWN_ISSUES +sample.colors diff --git a/docs/sample.colors b/docs/sample.colors new file mode 100644 index 0000000..2f90dee --- /dev/null +++ b/docs/sample.colors @@ -0,0 +1,4 @@ +mp3:904010 +ogg:D04040 +txt:FF0000 +cfg:00FF00 diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index 44e42ad..16c97c9 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, { int xpos,ypos,w,h,xrect; int lastmode = drawmode; + int oldcolor = fg_pattern; /* make sure scrolling is turned off on the line we are updating */ scrolling_lines &= ~(1 << y); @@ -819,11 +820,15 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, ypos = ymargin + y*h; drawmode = (style & STYLE_INVERT) ? (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + if (drawmode == DRMODE_SOLID && style & STYLE_COLORED) { + fg_pattern = style & STYLE_COLOR_MASK; + } lcd_putsxyofs(xpos, ypos, offset, str); drawmode ^= DRMODE_INVERSEVID; xrect = xpos + MAX(w - offset, 0); lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h); drawmode = lastmode; + fg_pattern = oldcolor; } /*** scrolling ***/ @@ -896,10 +901,8 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, s->invert = false; if (style & STYLE_INVERT) { s->invert = true; - lcd_puts_style_offset(x,y,string,STYLE_INVERT,offset); } - else - lcd_puts_offset(x,y,string,offset); + lcd_puts_style_offset(x,y,string,style,offset); lcd_getstringsize(string, &w, &h); diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h index ad311a8..cfb643f 100644 --- a/firmware/export/lcd-remote.h +++ b/firmware/export/lcd-remote.h @@ -43,8 +43,8 @@ int remote_type(void); extern struct event_queue remote_scroll_queue; #endif -#define STYLE_DEFAULT 0 -#define STYLE_INVERT 1 +#define STYLE_DEFAULT 0x00000000 +#define STYLE_INVERT 0x20000000 #if LCD_REMOTE_DEPTH <= 8 #if (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED) \ diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 0776640..cebcf54 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -24,8 +24,10 @@ #include "cpu.h" #include "config.h" -#define STYLE_DEFAULT 0 -#define STYLE_INVERT 1 +#define STYLE_DEFAULT 0x00000000 +#define STYLE_INVERT 0x20000000 +#define STYLE_COLORED 0x10000000 +#define STYLE_COLOR_MASK 0x0000FFFF #ifdef SIMULATOR #ifndef MAX_PATH |