summaryrefslogtreecommitdiffstats
path: root/apps/gui/skin_engine
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/skin_engine')
-rw-r--r--apps/gui/skin_engine/skin_display.c29
-rw-r--r--apps/gui/skin_engine/skin_display.h6
-rw-r--r--apps/gui/skin_engine/skin_parser.c84
-rw-r--r--apps/gui/skin_engine/skin_render.c45
-rw-r--r--apps/gui/skin_engine/skin_tokens.h1
-rw-r--r--apps/gui/skin_engine/wps_internals.h13
6 files changed, 150 insertions, 28 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index a967114125..02e9d39711 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -450,15 +450,12 @@ int evaluate_conditional(struct gui_wps *gwps, int offset,
line is the index of the line on the screen.
scroll indicates whether the line is a scrolling one or not.
*/
-void write_line(struct screen *display,
- struct align_pos *format_align,
- int line,
- bool scroll)
+void write_line(struct screen *display, struct align_pos *format_align,
+ int line, bool scroll, unsigned style)
{
int left_width = 0, left_xpos;
int center_width = 0, center_xpos;
int right_width = 0, right_xpos;
- int ypos;
int space_width;
int string_height;
int scroll_width;
@@ -565,22 +562,19 @@ void write_line(struct screen *display,
right_width = 0;
}
- ypos = (line * string_height);
-
-
if (scroll && ((left_width > scroll_width) ||
(center_width > scroll_width) ||
(right_width > scroll_width)))
{
- display->puts_scroll(0, line,
- (unsigned char *)format_align->left);
+ display->puts_scroll_style(0, line,
+ (unsigned char *)format_align->left, style);
}
else
{
#ifdef HAVE_LCD_BITMAP
/* clear the line first */
display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- display->fillrect(left_xpos, ypos, display->getwidth(), string_height);
+ display->fillrect(left_xpos, line*string_height, display->getwidth(), string_height);
display->set_drawmode(DRMODE_SOLID);
#endif
@@ -591,18 +585,19 @@ void write_line(struct screen *display,
/* print aligned strings */
if (left_width != 0)
{
- display->putsxy(left_xpos, ypos,
- (unsigned char *)format_align->left);
+ display->puts_style_xyoffset(left_xpos/space_width, line,
+ (unsigned char *)format_align->left, style, 0, 0);
+
}
if (center_width != 0)
{
- display->putsxy(center_xpos, ypos,
- (unsigned char *)format_align->center);
+ display->puts_style_xyoffset(center_xpos/space_width, line,
+ (unsigned char *)format_align->center, style, 0, 0);
}
if (right_width != 0)
{
- display->putsxy(right_xpos, ypos,
- (unsigned char *)format_align->right);
+ display->puts_style_xyoffset(right_xpos/space_width, line,
+ (unsigned char *)format_align->right, style, 0, 0);
}
}
}
diff --git a/apps/gui/skin_engine/skin_display.h b/apps/gui/skin_engine/skin_display.h
index da4bb92aef..9faaea30cf 100644
--- a/apps/gui/skin_engine/skin_display.h
+++ b/apps/gui/skin_engine/skin_display.h
@@ -48,10 +48,8 @@ int evaluate_conditional(struct gui_wps *gwps, int offset,
line is the index of the line on the screen.
scroll indicates whether the line is a scrolling one or not.
*/
-void write_line(struct screen *display,
- struct align_pos *format_align,
- int line,
- bool scroll);
+void write_line(struct screen *display, struct align_pos *format_align,
+ int line, bool scroll, unsigned style);
void draw_peakmeters(struct gui_wps *gwps, int line_number,
struct viewport *viewport);
#endif
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 53e1efedd8..b7bb045411 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -453,6 +453,77 @@ static int parse_playlistview(struct skin_element *element,
return 0;
}
#endif
+#ifdef HAVE_LCD_COLOR
+static int parse_viewport_gradient_setup(struct skin_element *element,
+ struct wps_token *token,
+ struct wps_data *wps_data)
+{
+ (void)wps_data;
+ struct gradient_config *cfg;
+ if (element->params_count < 2) /* only start and end are required */
+ return 1;
+ cfg = (struct gradient_config *)skin_buffer_alloc(sizeof(struct gradient_config));
+ if (!cfg)
+ return 1;
+ if (!parse_color(curr_screen, element->params[0].data.text, &cfg->start) ||
+ !parse_color(curr_screen, element->params[1].data.text, &cfg->end))
+ return 1;
+ if (element->params_count > 2)
+ {
+ if (!parse_color(curr_screen, element->params[2].data.text, &cfg->text))
+ return 1;
+ }
+ else
+ {
+ cfg->text = curr_vp->vp.fg_pattern;
+ }
+
+ token->value.data = cfg;
+ return 0;
+}
+#endif
+static int parse_viewporttextstyle(struct skin_element *element,
+ struct wps_token *token,
+ struct wps_data *wps_data)
+{
+ (void)wps_data;
+ int style;
+ char *mode = element->params[0].data.text;
+ unsigned colour;
+
+ if (!strcmp(mode, "invert"))
+ {
+ style = STYLE_INVERT;
+ }
+ else if (!strcmp(mode, "colour") || !strcmp(mode, "color"))
+ {
+ if (element->params_count < 2 ||
+ !parse_color(curr_screen, element->params[1].data.text, &colour))
+ return 1;
+ style = STYLE_COLORED|(STYLE_COLOR_MASK&colour);
+ }
+#ifdef HAVE_LCD_COLOR
+ else if (!strcmp(mode, "gradient"))
+ {
+ int num_lines;
+ if (element->params_count < 2)
+ num_lines = 1;
+ else /* atoi() instead of using a number in the parser is because [si]
+ * will select the number for something which looks like a colour
+ * making the "colour" case (above) harder to parse */
+ num_lines = atoi(element->params[1].data.text);
+ style = STYLE_GRADIENT|NUMLN_PACK(num_lines)|CURLN_PACK(0);
+ }
+#endif
+ else if (!strcmp(mode, "clear"))
+ {
+ style = STYLE_DEFAULT;
+ }
+ else
+ return 1;
+ token->value.l = style;
+ return 0;
+}
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
@@ -1514,6 +1585,11 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
skin_vp->start_fgcolour = skin_vp->vp.fg_pattern;
skin_vp->start_bgcolour = skin_vp->vp.bg_pattern;
#endif
+#ifdef HAVE_LCD_COLOR
+ skin_vp->start_gradient.start = skin_vp->vp.lss_pattern;
+ skin_vp->start_gradient.end = skin_vp->vp.lse_pattern;
+ skin_vp->start_gradient.text = skin_vp->vp.lst_pattern;
+#endif
struct skin_tag_parameter *param = element->params;
@@ -1684,6 +1760,14 @@ static int skin_element_callback(struct skin_element* element, void* data)
function = parse_image_special;
break;
#endif
+ case SKIN_TOKEN_VIEWPORT_TEXTSTYLE:
+ function = parse_viewporttextstyle;
+ break;
+#ifdef HAVE_LCD_COLOR
+ case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP:
+ function = parse_viewport_gradient_setup;
+ break;
+#endif
case SKIN_TOKEN_TRANSLATEDSTRING:
case SKIN_TOKEN_SETTING:
function = parse_setting_and_lang;
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 13eb69c744..27e6747c29 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -55,6 +55,7 @@ struct skin_draw_info {
struct skin_viewport *skin_vp;
int line_number;
unsigned long refresh_type;
+ unsigned text_style;
char* cur_align_start;
struct align_pos align;
@@ -106,6 +107,19 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
col->vp->bg_pattern = col->colour;
}
break;
+ case SKIN_TOKEN_VIEWPORT_TEXTSTYLE:
+ info->text_style = token->value.l;
+ break;
+#endif
+#ifdef HAVE_LCD_COLOR
+ case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP:
+ {
+ struct gradient_config *cfg = token->value.data;
+ vp->lss_pattern = cfg->start;
+ vp->lse_pattern = cfg->end;
+ vp->lst_pattern = cfg->text;
+ }
+ break;
#endif
case SKIN_TOKEN_VIEWPORT_ENABLE:
{
@@ -614,7 +628,8 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
.line_scrolls = false,
.refresh_type = refresh_type,
.skin_vp = skin_viewport,
- .offset = 0
+ .offset = 0,
+ .text_style = STYLE_DEFAULT
};
struct align_pos * align = &info.align;
@@ -636,7 +651,17 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
info.no_line_break = false;
info.line_scrolls = false;
info.force_redraw = false;
-
+#ifdef HAVE_LCD_COLOR
+ if (info.text_style&STYLE_GRADIENT)
+ {
+ int cur = CURLN_UNPACK(info.text_style);
+ int num = NUMLN_UNPACK(info.text_style);
+ if (cur+1 == num)
+ info.text_style = STYLE_DEFAULT;
+ else
+ info.text_style = STYLE_GRADIENT|CURLN_PACK(cur+1)|NUMLN_PACK(num);
+ }
+#endif
info.cur_align_start = info.buf;
align->left = info.buf;
align->center = NULL;
@@ -668,10 +693,10 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
/* if the line is a scrolling one we don't want to update
too often, so that it has the time to scroll */
if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw)
- write_line(display, align, info.line_number, true);
+ write_line(display, align, info.line_number, true, info.text_style);
}
else
- write_line(display, align, info.line_number, false);
+ write_line(display, align, info.line_number, false, info.text_style);
}
if (!info.no_line_break)
info.line_number++;
@@ -717,6 +742,11 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour;
skin_viewport->vp.bg_pattern = skin_viewport->start_bgcolour;
#endif
+#ifdef HAVE_LCD_COLOR
+ skin_viewport->vp.lss_pattern = skin_viewport->start_gradient.start;
+ skin_viewport->vp.lse_pattern = skin_viewport->start_gradient.end;
+ skin_viewport->vp.lst_pattern = skin_viewport->start_gradient.text;
+#endif
/* dont redraw the viewport if its disabled */
if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE)
@@ -772,7 +802,8 @@ static __attribute__((noinline)) void skin_render_playlistviewer(struct playlist
.line_scrolls = false,
.refresh_type = refresh_type,
.skin_vp = skin_viewport,
- .offset = viewer->start_offset
+ .offset = viewer->start_offset,
+ .text_style = STYLE_DEFAULT
};
struct align_pos * align = &info.align;
@@ -829,10 +860,10 @@ static __attribute__((noinline)) void skin_render_playlistviewer(struct playlist
/* if the line is a scrolling one we don't want to update
too often, so that it has the time to scroll */
if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw)
- write_line(display, align, info.line_number, true);
+ write_line(display, align, info.line_number, true, info.text_style);
}
else
- write_line(display, align, info.line_number, false);
+ write_line(display, align, info.line_number, false, info.text_style);
}
info.line_number++;
info.offset++;
diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h
index d259fe431c..9df2137ece 100644
--- a/apps/gui/skin_engine/skin_tokens.h
+++ b/apps/gui/skin_engine/skin_tokens.h
@@ -35,6 +35,7 @@ struct wps_token {
union {
char c;
unsigned short i;
+ long l;
void* data;
} value;
};
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index 6de98455a7..01f67d4a0b 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -161,6 +161,14 @@ enum wps_parse_error {
PARSE_FAIL_COND_INVALID_PARAM,
PARSE_FAIL_LIMITS_EXCEEDED,
};
+#ifdef HAVE_LCD_COLOR
+struct gradient_config {
+ unsigned start;
+ unsigned end;
+ unsigned text;
+ int lines_count;
+};
+#endif
#define VP_DRAW_HIDEABLE 0x1
#define VP_DRAW_HIDDEN 0x2
@@ -173,8 +181,13 @@ struct skin_viewport {
char hidden_flags;
bool is_infovp;
char* label;
+#if LCD_DEPTH > 1
unsigned start_fgcolour;
unsigned start_bgcolour;
+#ifdef HAVE_LCD_COLOR
+ struct gradient_config start_gradient;
+#endif
+#endif
};
struct viewport_colour {
struct viewport *vp;