Added inner fill option to normal scrollbar and foreground only option. Added a left-pointing cursor for using pointer. Updated color picker and now sliders look very good on color, grayscale and mono screens when using bar selector. Some misc. changes for appearance.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11210 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/gui/color_picker.c b/apps/gui/color_picker.c
index 719112d..32b392c 100644
--- a/apps/gui/color_picker.c
+++ b/apps/gui/color_picker.c
@@ -31,6 +31,7 @@
 #include "lang.h"
 #include "splash.h"
 #include "action.h"
+#include "icons.h"
 
 /* structure for color info */
 struct rgb_pick
@@ -51,20 +52,31 @@
     };
 };
 
-/* maximum values for components */
-static const unsigned char max_val[3] =
-{
-    LCD_MAX_RED,
-    LCD_MAX_GREEN,
-    LCD_MAX_BLUE
-};
 
 /* list of primary colors */
-static const unsigned prim_rgb[3] =
+#define SB_PRIM 0
+#define SB_FILL 1
+#define SB_MAX  2
+static const unsigned short prim_rgb[][3] =
 {
-    LCD_RGBPACK(255, 0, 0),
-    LCD_RGBPACK(0, 255, 0),
-    LCD_RGBPACK(0, 0 ,255),
+    /* Foreground colors for sliders */
+    {
+        LCD_RGBPACK(255,   0,   0),
+        LCD_RGBPACK(  0, 255,   0),
+        LCD_RGBPACK(  0,   0, 255),
+    },
+    /* Fill colors for sliders */
+    {
+        LCD_RGBPACK( 85,   0,   0),
+        LCD_RGBPACK(  0,  85,   0),
+        LCD_RGBPACK(  0,   0,  85),
+    },
+    /* maximum values for components */
+    {
+        LCD_MAX_RED,
+        LCD_MAX_GREEN,
+        LCD_MAX_BLUE
+    }
 };
 
 /* Unpacks the color value into native rgb values and 24 bit rgb values */
@@ -98,20 +110,22 @@
    else return LCD_WHITE */
 static inline unsigned get_black_or_white(const struct rgb_pick *rgb)
 {
-    return (4*rgb->r + 5*rgb->g + 2*rgb->b) >= 256 ?
+    return (2*rgb->red + 5*rgb->green + rgb->blue) >= 1024 ?
         LCD_BLACK : LCD_WHITE;
 }
 
-#define MARGIN_LEFT             2 /* Left margin of screen                */
-#define MARGIN_TOP              4 /* Top margin of screen                 */
-#define MARGIN_RIGHT            2 /* Right margin of screen               */
-#define MARGIN_BOTTOM           4 /* Bottom margin of screen              */
+#define MARGIN_LEFT             0 /* Left margin of screen                */
+#define MARGIN_TOP              2 /* Top margin of screen                 */
+#define MARGIN_RIGHT            0 /* Right margin of screen               */
+#define MARGIN_BOTTOM           6 /* Bottom margin of screen              */
 #define SLIDER_MARGIN_LEFT      2 /* Gap to left of sliders               */
 #define SLIDER_MARGIN_RIGHT     2 /* Gap to right of sliders              */
 #define TITLE_MARGIN_BOTTOM     4 /* Space below title bar                */
-#define SELECTOR_LR_MARGIN      1 /* Margin between ">" and text          */
+#define SELECTOR_LR_MARGIN      0 /* Margin between ">" and text          */
 #define SELECTOR_TB_MARGIN      1 /* Margin on top and bottom of selector */
 #define SWATCH_TOP_MARGIN       4 /* Space between last slider and swatch */
+#define SELECTOR_WIDTH          6 /* Width of > and < bitmaps             */
+#define SELECTOR_HEIGHT         8 /* Height of > and < bitmaps            */
 
 /* dunno why lcd_set_drawinfo should be left out of struct screen */
 static void set_drawinfo(struct screen *display, int mode,
@@ -173,19 +187,21 @@
 
     /* Get slider positions and top starting position */
     text_top     = MARGIN_TOP + y + TITLE_MARGIN_BOTTOM + SELECTOR_TB_MARGIN;
-    slider_left  = MARGIN_LEFT + SELECTOR_LR_MARGIN + display->char_width +
+    slider_left  = MARGIN_LEFT + SELECTOR_WIDTH + SELECTOR_LR_MARGIN +
                    max_label_width + SLIDER_MARGIN_LEFT;
     slider_width = display->width - slider_left - SLIDER_MARGIN_RIGHT -
-                   SELECTOR_LR_MARGIN - display->char_width*3 - MARGIN_RIGHT;
+                   display->char_width*2 - SELECTOR_LR_MARGIN - SELECTOR_WIDTH -
+                   MARGIN_RIGHT;
 
     for (i = 0; i < 3; i++)
     {
-        int      mode = DRMODE_SOLID;
-        unsigned fg   = text_color;
-        unsigned bg   = background_color;
+        unsigned sb_flags = HORIZONTAL;
+        int      mode     = DRMODE_SOLID;
+        unsigned fg       = text_color;
+        unsigned bg       = background_color;
 
         if (!display_three_rows)
-            i = row;        
+            i = row;
 
         if (i == row)
         {
@@ -201,39 +217,35 @@
                                   display->char_height +
                                   SELECTOR_TB_MARGIN*2);
 
-                if (display->depth == 1)
+                if (display->depth < 16)
                 {
-                    /* Just invert for low mono display */
-                    mode |= DRMODE_INVERSEVID;
-                }
-                else
-                {
-                    if (display->depth >= 16)
-                    {
-                        /* Backdrops will show through text in
-                           DRMODE_SOLID */
-                        mode = DRMODE_FG;
-                        fg = prim_rgb[i];
-                    }
-                    else
-                    {
-                        fg = background_color;
-                    }
-
-                    bg = text_color;
+                    sb_flags |= FOREGROUND | INNER_FILL;
+                    mode     |= DRMODE_INVERSEVID;
                 }
             }
             else if (display_three_rows)
             {
                 /* Draw ">    <" around sliders */
-                display->putsxy(MARGIN_LEFT,  text_top, ">");
-                display->putsxy(display->width-display->char_width -
-                                MARGIN_RIGHT, text_top, "<");
-                if (display->depth >= 16)
-                    fg = prim_rgb[i];
+                int top = text_top + (display->char_height -
+                                      SELECTOR_HEIGHT) / 2;
+                display->mono_bitmap(bitmap_icons_6x8[Icon_Cursor],
+                                     MARGIN_LEFT, top,
+                                     SELECTOR_WIDTH, SELECTOR_HEIGHT);
+                display->mono_bitmap(bitmap_icons_6x8[Icon_Reverse_Cursor],
+                                     display->width - MARGIN_RIGHT -
+                                     SELECTOR_WIDTH, top, SELECTOR_WIDTH,
+                                     SELECTOR_HEIGHT);
+            }
+
+            if (display->depth >= 16)
+            {
+                sb_flags |= FOREGROUND | INNER_BGFILL;
+                mode      = DRMODE_FG;
+                fg        = prim_rgb[SB_PRIM][i];
+                bg        = prim_rgb[SB_FILL][i];
             }
         }
- 
+
         set_drawinfo(display, mode, fg, bg);
 
         /* Draw label */
@@ -253,17 +265,20 @@
                            text_top + display->char_height / 4,
                            slider_width,
                            display->char_height / 2,
-                           max_val[i],
+                           prim_rgb[SB_MAX][i],
                            0,
                            rgb->rgb_val[i],
-                           HORIZONTAL);
+                           sb_flags);
 
         /* Advance to next line */
         text_top += display->char_height + 2*SELECTOR_TB_MARGIN;
 
         if (!display_three_rows)
             break;
-    }
+    } /* end for */
+
+    /* Draw color value in system font */
+    display->setfont(FONT_SYSFIXED);
 
     /* Format RGB: #rrggbb */
     snprintf(buf, sizeof(buf), str(LANG_COLOR_RGB_VALUE),
@@ -272,13 +287,12 @@
     if (display->depth >= 16)
     {
         /* Display color swatch on color screens only */
-        int left   = slider_left;
+        int left   = MARGIN_LEFT + SELECTOR_WIDTH + SELECTOR_LR_MARGIN;
         int top    = text_top + SWATCH_TOP_MARGIN;
-        int width  = display->width - slider_left - left;
+        int width  = display->width - left - SELECTOR_LR_MARGIN -
+                     SELECTOR_WIDTH - MARGIN_RIGHT;
         int height = display->height - top - MARGIN_BOTTOM;
 
-        display->setfont(FONT_SYSFIXED);
-
         /* Only draw if room */
         if (height >= display->char_height + 2)
         {
@@ -298,10 +312,8 @@
 
             /* Draw border */
             display->set_foreground(text_color);
-            display->drawrect(left - 1, top - 1, width + 2, height + 2);
+            display->drawrect(left, top, width, height);
         }
-
-        display->setfont(FONT_UI);
     }
     else
     {
@@ -318,6 +330,8 @@
         }
     }
 
+    display->setfont(FONT_UI);
+
     display->update();
     /* Be sure screen mode is reset */
     set_drawinfo(display, DRMODE_SOLID, text_color, background_color);
@@ -363,7 +377,7 @@
 
             case ACTION_SETTINGS_INC:
             case ACTION_SETTINGS_INCREPEAT:
-                if (rgb.rgb_val[slider] < max_val[slider])
+                if (rgb.rgb_val[slider] < prim_rgb[SB_MAX][slider])
                     rgb.rgb_val[slider]++;
                 pack_rgb(&rgb);
                 break;
diff --git a/apps/gui/scrollbar.c b/apps/gui/scrollbar.c
index 4cf92f4..f7dead5 100644
--- a/apps/gui/scrollbar.c
+++ b/apps/gui/scrollbar.c
@@ -26,27 +26,14 @@
 void gui_scrollbar_draw(struct screen * screen, int x, int y,
                         int width, int height, int items,
                         int min_shown, int max_shown,
-                        enum orientation orientation)
+                        unsigned flags)
 {
-    int min;
-    int max;
-    int inner_len;
-    int start;
-    int size;
-
-    /* draw box */
-    screen->drawrect(x, y, width, height);
-
-    screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
-
-    /* clear edge pixels */
-    screen->drawpixel(x, y);
-    screen->drawpixel((x + width - 1), y);
-    screen->drawpixel(x, (y + height - 1));
-    screen->drawpixel((x + width - 1), (y + height - 1));
-
-    /* clear pixels in progress bar */
-    screen->fillrect(x + 1, y + 1, width - 2, height - 2);
+    int inner_x, inner_y, inner_wd, inner_ht, inner_len;
+    int min, max, range;
+    int start, size;
+#ifdef HAVE_LCD_COLOR
+    int infill;
+#endif
 
     /* min should be min */
     if(min_shown < max_shown) {
@@ -69,10 +56,17 @@
     if(max > items)
         max = items;
 
-    if (orientation == VERTICAL)
-        inner_len = height - 2;
+    range = max - min;
+
+    inner_x  = x + 1;
+    inner_y  = y + 1;
+    inner_wd = width  - 2;
+    inner_ht = height - 2;
+
+    if (flags & HORIZONTAL)
+        inner_len = inner_wd;
     else
-        inner_len = width - 2;
+        inner_len = inner_ht;
 
     /* avoid overflows */
     while (items > (INT_MAX / inner_len)) {
@@ -82,31 +76,87 @@
     }
 
     /* calc start and end of the knob */
-    if (items > 0 && items > (max - min)) {
-        size = inner_len * (max - min) / items;
+    if (items > 0 && items > range) {
+        size = inner_len * range / items;
         if (size == 0) { /* width of knob is null */
             size = 1;
             start = (inner_len - 1) * min / items;
         } else {
-            start = (inner_len - size) * min / (items - (max - min));
+            start = (inner_len - size) * min / (items - range);
         }
     } else {  /* if null draw full bar */
         size = inner_len;
         start = 0;
     }
 
+    /* draw box */
+#ifdef HAVE_LCD_COLOR
+    /* must avoid corners if case of (flags & FOREGROUND) */
+    screen->hline(inner_x, x + inner_wd, y);
+    screen->hline(inner_x, x + inner_wd, y + height - 1);
+    screen->vline(x, inner_y, y + inner_ht);
+    screen->vline(x + width - 1, inner_y, y + inner_ht);
+#else
+    screen->drawrect(x, y, width, height);
+#endif
+
+    screen->set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
+
+#ifdef HAVE_LCD_COLOR
+    infill = flags & (screen->depth > 1 ? INNER_FILL_MASK : INNER_FILL);
+
+    if (!(flags & FOREGROUND))
+    {
+#endif
+        /* clear corner pixels */
+        screen->drawpixel(x, y);
+        screen->drawpixel(x + width - 1, y);
+        screen->drawpixel(x, y + height - 1);
+        screen->drawpixel(x + width - 1, y + height - 1);
+
+#ifdef HAVE_LCD_COLOR
+        if (infill != INNER_BGFILL)
+            infill = INNER_FILL;
+    }
+
+    if (infill == INNER_FILL)
+#endif
+    {
+        /* clear pixels in progress bar */
+        screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
+    }
+
     screen->set_drawmode(DRMODE_SOLID);
 
-    if(orientation == VERTICAL)
-        screen->fillrect(x + 1, y + start + 1, width - 2, size);
+#ifdef HAVE_LCD_COLOR
+    if (infill == INNER_BGFILL)
+    {
+        /* fill inner area with current background color */
+        unsigned fg = screen->get_foreground();
+        screen->set_foreground(screen->get_background());
+        screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
+        screen->set_foreground(fg);
+    }
+#endif
+
+    if (flags & HORIZONTAL)
+    {
+        inner_x += start;
+        inner_wd = size;
+    }
     else
-        screen->fillrect(x + start + 1, y + 1, size, height - 2);
+    {
+        inner_y += start;
+        inner_ht = size;
+    }
+
+    screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
 }
 
 void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x, int y,
                         int width, int height, int items,
                         int min_shown, int max_shown,
-                        enum orientation orientation)
+                        unsigned flags)
 {
     int min;
     int max;
@@ -140,7 +190,7 @@
     if(max > items)
         max = items;
 
-    if (orientation == VERTICAL)
+    if (flags & VERTICAL)
         inner_len = height;
     else
         inner_len = width;
@@ -168,27 +218,27 @@
 
     screen->set_drawmode(DRMODE_SOLID);
 
-    if(orientation == VERTICAL) {
+    if (flags & HORIZONTAL) {
 #if LCD_DEPTH > 1
       if (bm.format == FORMAT_MONO)
 #endif
-        screen->mono_bitmap_part(bm.data, 0, 0, 
-                                 bm.width, x, y + start, width, size);
+        screen->mono_bitmap_part(bm.data, 0, 0,
+                                 bm.width, x + start, y, size, height);
 #if LCD_DEPTH > 1
-      else 
-        screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0, 
-                                        bm.width, x, y + start, width, size);
-#endif 
+      else
+        screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0,
+                                        bm.width, x + start, y, size, height);
+#endif
     } else {
 #if LCD_DEPTH > 1
       if (bm.format == FORMAT_MONO)
 #endif
-        screen->mono_bitmap_part(bm.data, 0, 0, 
-                                 bm.width, x + start, y, size, height);
+        screen->mono_bitmap_part(bm.data, 0, 0,
+                                 bm.width, x, y + start, width, size);
 #if LCD_DEPTH > 1
       else
-        screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0, 
-                                        bm.width, x + start, y, size, height);
+        screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0,
+                                        bm.width, x, y + start, width, size);
 #endif
     }
 }
diff --git a/apps/gui/scrollbar.h b/apps/gui/scrollbar.h
index 541cc2d..40279a1 100644
--- a/apps/gui/scrollbar.h
+++ b/apps/gui/scrollbar.h
@@ -24,8 +24,15 @@
 #ifdef HAVE_LCD_BITMAP
 
 enum orientation {
-    VERTICAL,
-    HORIZONTAL
+    VERTICAL          = 0x0000,   /* Vertical orientation     */
+    HORIZONTAL        = 0x0001,   /* Horizontal orientation   */
+#ifdef HAVE_LCD_COLOR
+    FOREGROUND        = 0x0002,   /* Do not clear background pixels */
+    INNER_FILL        = 0x0004,   /* Fill inner part even if FOREGROUND */
+    INNER_BGFILL      = 0x0008,   /* Fill inner part with background
+                                     color even if FOREGROUND */
+    INNER_FILL_MASK   = 0x000c,
+#endif
 };
 
 /*
@@ -43,10 +50,10 @@
 extern void gui_scrollbar_draw(struct screen * screen, int x, int y,
                                int width, int height, int items,
                                int min_shown, int max_shown,
-                               enum orientation orientation);
+                               unsigned flags);
 extern void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x, int y,
                             int width, int height, int items,
                             int min_shown, int max_shown,
-                            enum orientation orientation);
+                            unsigned flags);
 #endif /* HAVE_LCD_BITMAP */
 #endif /* _GUI_SCROLLBAR_H_ */
diff --git a/apps/recorder/icons.c b/apps/recorder/icons.c
index 9433694..46d628e 100644
--- a/apps/recorder/icons.c
+++ b/apps/recorder/icons.c
@@ -56,6 +56,7 @@
     { 0x77, 0x55, 0x55, 0x55, 0x55, 0x77 }, /* Queued Item */
     { 0x3e, 0x41, 0x3e, 0x1c, 0x1c, 0x08 }, /* Moving Item */
     { 0x7f, 0x7f, 0x1c, 0x3e, 0x77, 0x63 }, /* Keyboard file */
+    { 0x00, 0x00, 0x00, 0x08, 0x1c, 0x3e }, /* Reverse Cursor / Marker */
 };
 
 const unsigned char bitmap_icons_7x8[][7] =
@@ -85,21 +86,21 @@
 {
     {0x00, 0x00, 0x00, 0x00,0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x3e, 0x2a,
      0x3a, 0x00, 0x0e, 0x08, 0x3e, 0x00}, /* mp3 64kbps */
-    {0x00, 0x00, 0x00, 0x00,0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x0e, 0x0a, 
+    {0x00, 0x00, 0x00, 0x00,0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x0e, 0x0a,
     0x3e, 0x00, 0x3e, 0x2a, 0x3a, 0x00}, /* mp3 96kbps */
-    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x24, 0x3e, 0x20, 0x00, 0x3a, 0x2a, 
+    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x24, 0x3e, 0x20, 0x00, 0x3a, 0x2a,
     0x2e, 0x00, 0x3e, 0x2a, 0x3e, 0x00}, /* mp3 128kbps */
-    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x24, 0x3e, 0x20, 0x00, 0x3e, 0x2a, 
+    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x24, 0x3e, 0x20, 0x00, 0x3e, 0x2a,
     0x3a, 0x00, 0x3e, 0x22, 0x3e, 0x00}, /* mp3 160kbps */
-    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x24, 0x3e, 0x20, 0x00, 0x0e, 0x0a, 
+    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x24, 0x3e, 0x20, 0x00, 0x0e, 0x0a,
     0x3e, 0x00, 0x3a, 0x2a, 0x2e, 0x00}, /* mp3 192kbps */
-    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x3a, 0x2a, 0x2e, 0x00, 0x3a, 0x2a, 
+    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x3a, 0x2a, 0x2e, 0x00, 0x3a, 0x2a,
     0x2e, 0x00, 0x0e, 0x08, 0x3e, 0x00}, /* mp3 224kbps */
-    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x22, 0x2a, 0x36, 0x00, 0x3a, 0x2a, 
+    {0x3e, 0x04, 0x08, 0x04, 0x3e, 0x00, 0x22, 0x2a, 0x36, 0x00, 0x3a, 0x2a,
     0x2e, 0x00, 0x3e, 0x22, 0x3e, 0x00}, /* mp3 320kbps */
-    {0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,0x1e, 0x20, 0x18, 0x20, 0x1e, 
+    {0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00,0x1e, 0x20, 0x18, 0x20, 0x1e,
     0x00, 0x1e, 0x20, 0x18, 0x06, 0x00}, /* wv */
-    {0x00, 0x00, 0x1e, 0x20, 0x18, 0x20, 0x1e, 0x00, 0x3c, 0x12, 0x12, 0x3c, 
+    {0x00, 0x00, 0x1e, 0x20, 0x18, 0x20, 0x1e, 0x00, 0x3c, 0x12, 0x12, 0x3c,
     0x00, 0x1e, 0x20, 0x18, 0x06, 0x00}  /* wav */
 };
 
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h
index 826f18b..75401f6 100644
--- a/apps/recorder/icons.h
+++ b/apps/recorder/icons.h
@@ -63,7 +63,8 @@
     Icon_Queued,
     Icon_Moving,
     Icon_Keyboard,
-    Icon6x8Last
+    Icon_Reverse_Cursor,
+    Icon6x8Last,
 };
 
 enum icons_7x8 {