Index: apps/settings.h =================================================================== RCS file: /cvsroot/rockbox/apps/settings.h,v retrieving revision 1.256 diff -u -r1.256 settings.h --- apps/settings.h 19 Dec 2006 01:26:37 -0000 1.256 +++ apps/settings.h 16 Jan 2007 01:18:28 -0000 @@ -577,6 +602,7 @@ unsigned int rec_timesplit_seconds(void); unsigned long rec_sizesplit_bytes(void); void settings_apply_trigger(void); +int hex_to_rgb(const char* hex); /* global settings */ extern struct user_settings global_settings; diff -u -r1.443 settings.c --- apps/settings.c 31 Dec 2006 02:44:53 -0000 1.443 +++ apps/settings.c 16 Jan 2007 01:20:14 -0000 @@ -762,7 +768,7 @@ #define hex2dec(c) (((c) >= '0' && ((c) <= '9')) ? (toupper(c)) - '0' : \ (toupper(c)) - 'A' + 10) -static int hex_to_rgb(const char* hex) +int hex_to_rgb(const char* hex) { int ok = 1; int i; int red, green, blue; diff -u -r gwps-common.c gwps-common.c --- apps/gui/gwps-common.c 2006-08-06 21:28:44.000000000 +0300 +++ apps/gui/gwps-common.c 2006-08-06 21:24:41.000000000 +0300 @@ -1294,6 +1294,42 @@ case 0: *buf++ = '%'; break; + case 'e': /* Line settings (x/y/width and font face */ + fmt++; + if (*fmt == '|') { + char *p=strchr(fmt, '|'); + if (p) { + fmt = ++p; + gwps->data->line_xpos = atoi(p); + p = strchr(p, '|'); + if (p) { + fmt = ++p; + gwps->data->line_ypos = atoi(p); + p = strchr(p, '|'); + if (p) { + fmt = ++p; + gwps->data->line_width = atoi(p); + p = strchr(p, '|'); + if (p) { + fmt = ++p; + gwps->data->line_font = atoi(p); + p = strchr(p, '|'); + if (p) { + fmt = ++p; + char fg_color[7]; + snprintf(fg_color, 7, "%s", p); + gwps->data->line_fgcolor = hex_to_rgb(fg_color); + p = strchr(p, '|'); + if (p) { + fmt = ++p; + } + } + } + } + } + } + } + break; case 'a': ++fmt; /* remember where the current aligned text started */ @@ -1844,6 +2329,46 @@ } #endif #ifdef HAVE_LCD_BITMAP + /* If need to refresh a line and we have a custom font we + should set the font face prior getting the font size */ + if (flags & (WPS_REFRESH_DYNAMIC | WPS_REFRESH_STATIC | WPS_REFRESH_SCROLL)) + { + if (((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC|WPS_REFRESH_SCROLL)) || + new_subline_refresh) && + ((int)data->line_xpos || (int)data->line_ypos || + (int)data->line_width || (int)data->line_font)) + { + if (data->line_font_prev != data->line_font) { + switch (data->line_font) + { + case 1: + display->setfont(FONT_USER1); + break; + case 2: + display->setfont(FONT_USER2); + break; + case 3: + display->setfont(FONT_USER3); + break; + case 4: + display->setfont(FONT_USER4); + break; + case 5: + display->setfont(FONT_USER5); + break; + case 6: + display->setfont(FONT_USER6); + break; + case 7: + display->setfont(FONT_USER7); + break; + } + + data->line_font_prev = data->line_font; + } + } + } + /* calculate different string sizes and positions */ display->getstringsize((unsigned char *)" ", &space_width, &string_height); if (format_align.left != 0) { @@ -1966,6 +2491,38 @@ #endif if (flags & WPS_REFRESH_SCROLL) { + /* Custom line with scroll capabilities */ + if (((refresh_mode & WPS_REFRESH_SCROLL) || + new_subline_refresh) && + ((int)data->line_xpos || (int)data->line_ypos || + (int)data->line_width || (int)data->line_font)) + { + /* Clear the area first if there is something to display */ + if (left_width || center_width || right_width) { + display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + display->fillrect((int)data->line_xpos, + (int)data->line_ypos, + (int)data->line_width, + string_height); + display->set_drawmode(DRMODE_SOLID); + } + + if (data->line_fgcolor_prev != data->line_fgcolor) { + display->set_foreground(data->line_fgcolor); + data->line_fgcolor_prev = data->line_fgcolor; + } + + display->setmargins(data->line_xpos, data->line_ypos); + display->set_custom_width(data->line_width); + + /* Nasty hack: we output an empty scrolling string, + which will reset the scroller for that line */ + display->puts_customline_scroll(i, (unsigned char *)""); + + display->puts_customline_scroll(i, + (unsigned char *)format_align.left + ); + } else /* scroll line */ if ((refresh_mode & WPS_REFRESH_SCROLL) || @@ -2014,8 +2567,59 @@ #endif } } + /* Custom lines with x/y/width coordinates and font face/color */ else if (flags & (WPS_REFRESH_DYNAMIC | WPS_REFRESH_STATIC)) { + if (((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC)) || + new_subline_refresh) && + ((int)data->line_xpos || (int)data->line_ypos || + (int)data->line_width || (int)data->line_font)) + { + update_line = true; + + /* Clear the area first if there is something to display */ + if (left_width || center_width || right_width) { + display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + display->fillrect((int)data->line_xpos, + (int)data->line_ypos, + (int)data->line_width, + string_height); + display->set_drawmode(DRMODE_SOLID); + } + + if (data->line_fgcolor_prev != data->line_fgcolor) { + display->set_foreground(data->line_fgcolor); + data->line_fgcolor_prev = data->line_fgcolor; + } + + display->setmargins(data->line_xpos, data->line_ypos); + display->set_custom_width(data->line_width); + + /* Print aligned strings */ + if (left_width != 0) + { + display->putsxy((int)data->line_xpos, + (int)data->line_ypos, + (unsigned char *)format_align.left + ); + } + if (center_width != 0) + { + display->putsxy((int)data->line_xpos+ + (int)((data->line_width-center_width)/2), + (int)data->line_ypos, + (unsigned char *)format_align.center + ); + } + if (right_width != 0) + { + display->putsxy((int)data->line_xpos+ + ((int)data->line_width-right_width), + (int)data->line_ypos, + (unsigned char *)format_align.right + ); + } + } else /* dynamic / static line */ if ((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC)) || new_subline_refresh) @@ -2025,9 +2633,11 @@ update_line = true; /* clear the line first */ - display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); - display->fillrect(0, ypos, display->width, string_height); - display->set_drawmode(DRMODE_SOLID); + if (left_width || center_width || right_width) { + display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + display->fillrect(0, ypos, display->width, string_height); + display->set_drawmode(DRMODE_SOLID); + } /* Nasty hack: we output an empty scrolling string, which will reset the scroller for that line */ @@ -2073,6 +2199,15 @@ /* Now we know wether the peak meter is used. So we can enable / disable the peak meter thread */ data->peak_meter_enabled = enable_pm; + /* Reset margins */ + data->line_xpos=0; + data->line_ypos=0; + data->line_width=0; + data->line_font=0; + /* Reset display color */ + data->line_fgcolor_prev = 0; + data->line_fgcolor = global_settings.fg_color; + display->set_foreground(global_settings.fg_color); #endif #ifdef CONFIG_BACKLIGHT diff -u -r gwps.h gwps.h --- apps/gui/gwps.h 2006-08-03 23:17:14.000000000 +0300 +++ apps/gui/gwps.h 2006-08-06 11:57:51.000000000 +0300 @@ -390,6 +390,9 @@ int progress_end; bool wps_loaded; bool peak_meter_enabled; + int line_xpos, line_ypos, line_width; + int line_font, line_font_prev; + int line_fgcolor, line_fgcolor_prev; }; /* initial setup of wps_data */ diff -u -r1.27 screen_access.h --- apps/screen_access.h 1 Jul 2006 10:14:27 -0000 1.27 +++ apps/screen_access.h 29 Sep 2006 11:10:05 -0000 @@ -116,6 +118,7 @@ #endif void (*init)(void); void (*puts_scroll)(int x, int y, const unsigned char *string); + void (*puts_customline_scroll)(int i, const unsigned char *string); void (*scroll_speed)(int speed); void (*scroll_delay)(int ms); void (*stop_scroll)(void); diff -u -r1.26 screen_access.c --- apps/screen_access.c 1 Jul 2006 10:14:26 -0000 1.26 +++ apps/screen_access.c 29 Sep 2006 11:11:44 -0000 @@ -176,6 +176,7 @@ screen->init=&lcd_init; screen->puts_scroll=&lcd_puts_scroll; + screen->puts_customline_scroll=&lcd_puts_customline_scroll; screen->stop_scroll=&lcd_stop_scroll; screen->clear_display=&lcd_clear_display; #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) diff -u -r1.68 lcd.h --- firmware/export/lcd.h 12 Aug 2006 09:27:26 -0000 1.68 +++ firmware/export/lcd.h 29 Sep 2006 11:12:31 -0000 @@ -66,6 +66,9 @@ extern void lcd_stop_scroll(void); extern void lcd_scroll_speed(int speed); extern void lcd_scroll_delay(int ms); +extern void lcd_puts_customline_scroll(int i, const unsigned char *string); +extern void lcd_puts_customline_scroll_style_offset(int i, const unsigned char *string, + int style, int offset); extern void lcd_puts_scroll(int x, int y, const unsigned char* string); extern void lcd_puts_scroll_style(int x, int y, const unsigned char* string, int style); @@ -345,6 +354,13 @@ bool bidir; bool invert; /* invert the scrolled text */ long start_tick; + /* Custome line arguments */ + bool customline; + int line_font; + int line_xpos; + int line_ypos; + int line_width; + int line_fgcolor; }; #else /* !HAVE_LCD_BITMAP */ diff -u -r1.39 lcd-16bit.c --- firmware/drivers/lcd-16bit.c 25 Sep 2006 12:45:13 -0000 1.39 +++ firmware/drivers/lcd-16bit.c 29 Sep 2006 11:13:57 -0000 @@ -837,6 +850,77 @@ bidir_limit = percent; } +void lcd_puts_customline_scroll(int i, const unsigned char *string) +{ + lcd_puts_customline_scroll_style_offset(i, string, + STYLE_DEFAULT, 0); +} + +void lcd_puts_customline_scroll_style_offset(int i, + const unsigned char *string, int style, int offset) +{ + struct scrollinfo* s; + int w, h; + + s = &scroll[i]; + + s->customline = true; + s->line_font = curfont; + s->line_xpos = lcd_getxmargin(); + s->line_ypos = lcd_getymargin(); + s->line_fgcolor = lcd_get_foreground(); + s->line_width = lcd_get_custom_width()-lcd_getxmargin(); + + s->start_tick = current_tick + scroll_delay; + s->invert = false; + if (style & STYLE_INVERT) { + s->invert = true; + lcd_puts_style_offset(0,0,string,STYLE_INVERT,offset); + } + else + lcd_puts_offset(0,0,string,offset); + + lcd_getstringsize(string, &w, &h); + + if (s->line_width < w) { + /* prepare scroll line */ + char *end; + + memset(s->line, 0, sizeof s->line); + strcpy(s->line, string); + + /* get width */ + s->width = lcd_getstringsize(s->line, &w, &h); + + /* scroll bidirectional or forward only depending on the string + width */ + if ( bidir_limit ) { + s->bidir = s->width < (lcd_get_custom_width() - xmargin) * + (100 + bidir_limit) / 100; + } + else + s->bidir = false; + + if (!s->bidir) { /* add spaces if scrolling in the round */ + strcat(s->line, " "); + /* get new width incl. spaces */ + s->width = lcd_getstringsize(s->line, &w, &h); + } + + end = strchr(s->line, '\0'); + strncpy(end, string, lcd_get_custom_width()/2); + + s->len = utf8length(string); + s->offset = offset; + s->startx = xmargin + xmargin * s->width / s->len; + s->backward = false; + scrolling_lines |= (1<start_tick)) continue; - + + if (s->customline) { + fgcolor_orig = lcd_get_foreground(); + lcd_setfont(s->line_font); + lcd_set_foreground(s->line_fgcolor); + lcd_setmargins(s->line_xpos, s->line_ypos); + lcd_set_custom_width(s->line_width); + } + if (s->backward) s->offset -= scroll_step; else @@ -941,6 +1032,11 @@ pf = font_get(curfont); xpos = s->startx; ypos = ymargin + index * pf->height; + + if (s->customline) { + xpos = s->line_xpos; + ypos = s->line_ypos; + } if (s->bidir) { /* scroll bidirectional */ if (s->offset <= 0) { @@ -990,6 +1067,10 @@ drawmode = lastmode; lcd_update_rect(xpos, ypos, lcd_get_custom_width() - xpos, pf->height); + + if (s->customline) { + lcd_set_foreground(fgcolor_orig); + } } sleep(scroll_ticks);