summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 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
}
diff --git a/docs/FILES b/docs/FILES
index 6eab98d..80e27a2 100644
--- a/docs/FILES
+++ b/docs/FILES
@@ -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