Foreground/Background colour settings. Based on patch #3050 by Jonathan Gordon, extended my me. The principle of the patch is that the three sliders contain the native ranges (currently 0..31, 0..63, 0..31), and the equivalent RGB888 colour is displayed underneath. The config block (and global_settings struct) contain the native value for the fg/bg colours (either RGB565 or RGB565SWAPPED), but the text .cfg files contain the RGB888 value written as 6 hex digits.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8840 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dave Chapman 2006-02-26 02:48:05 +00:00
parent dd2a5294d6
commit 603f87fe3c
10 changed files with 436 additions and 2 deletions

View file

@ -58,6 +58,7 @@ recorder/peakmeter.c
recorder/widgets.c
#ifdef HAVE_LCD_COLOR
recorder/backdrop.c
gui/color_picker.c
#endif
#endif
#ifdef CONFIG_TUNER

261
apps/gui/color_picker.c Normal file
View file

@ -0,0 +1,261 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id:
*
* Copyright (C) Jonathan Gordon (2006)
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "stdarg.h"
#include "string.h"
#include "stdio.h"
#include "kernel.h"
#include "system.h"
#include "screen_access.h"
#include "debug.h"
#include "misc.h"
#include "settings.h"
#include "scrollbar.h"
#include "lang.h"
#define TEXT_MARGIN display->char_width+2
#define SLIDER_START 20
#if (CONFIG_KEYPAD == IRIVER_H300_PAD)
#define SLIDER_UP BUTTON_UP
#define SLIDER_DOWN BUTTON_DOWN
#define SLIDER_LEFT BUTTON_LEFT
#define SLIDER_RIGHT BUTTON_RIGHT
#define SLIDER_OK BUTTON_ON
#define SLIDER_CANCEL BUTTON_OFF
#define SLIDER_RC_UP BUTTON_RC_REW
#define SLIDER_RC_DOWN BUTTON_RC_FF
#define SLIDER_RC_LEFT BUTTON_RC_SOURCE
#define SLIDER_RC_RIGHT BUTTON_RC_BITRATE
#define SLIDER_RC_OK BUTTON_RC_ON
#define SLIDER_RC_CANCEL BUTTON_RC_STOP
#elif (CONFIG_KEYPAD == IPOD_4G_PAD)
#define SLIDER_UP BUTTON_LEFT
#define SLIDER_DOWN BUTTON_RIGHT
#define SLIDER_LEFT BUTTON_SCROLL_BACK
#define SLIDER_RIGHT BUTTON_SCROLL_FWD
#define SLIDER_OK BUTTON_SELECT
#define SLIDER_CANCEL BUTTON_MENU
#endif
static const int max_val[3] = {LCD_MAX_RED,LCD_MAX_GREEN,LCD_MAX_BLUE};
static void draw_screen(struct screen *display, char *title,
int *rgb_val, int color, int row)
{
int i;
char *textrgb = str(LANG_COLOR_RGB_LABELS), rgb_dummy[2] = {0,0};
int text_top;
int text_centre, bg_col;
char buf[32];
int slider_width = (display->width-SLIDER_START-(display->char_width*5));
int background_color = global_settings.bg_color;
int text_color = global_settings.fg_color;
display->clear_display();
if (display->depth > 1) {
display->set_foreground(text_color);
}
i = display->getstringsize(title,0,0);
display->putsxy((display->width-i)/2,6,title );
for (i=0;i<3;i++)
{
text_top =display->char_height*((i*2)+2);
if (i==row)
{
if (global_settings.invert_cursor)
{
display->fillrect(0,text_top-1,display->width,display->char_height+2);
bg_col = text_color;
}
else
{
display->putsxy(0,text_top,">");
display->putsxy(display->width-TEXT_MARGIN,text_top,"<");
bg_col = background_color;
}
if (display->depth > 1)
{
if (i==0)
display->set_foreground(LCD_RGBPACK(255, 0, 0));
else if (i==1)
display->set_foreground(LCD_RGBPACK(0, 255, 0));
else if (i==2)
display->set_foreground(LCD_RGBPACK(0 ,0 ,255));
}
}
else
{
if (display->depth > 1)
display->set_foreground(text_color);
bg_col = background_color;
}
if (display->depth > 1)
display->set_background(bg_col);
text_centre = text_top+(display->char_height/2);
rgb_dummy[0] = textrgb[i];
display->putsxy(TEXT_MARGIN,text_top,rgb_dummy);
snprintf(buf,3,"%02d",rgb_val[i]);
display->putsxy(display->width-(display->char_width*4),text_top,buf);
text_top += display->char_height/4;
gui_scrollbar_draw(display,SLIDER_START,text_top,slider_width,
display->char_height/2,
max_val[i],0,rgb_val[i],HORIZONTAL);
}
if (display->depth > 1) {
display->set_background(background_color);
display->set_foreground(text_color);
}
if (text_top + (display->char_height*2) < (LCD_HEIGHT-40-display->char_height))
text_top += (display->char_height*2);
else text_top += (display->char_height);
/* Display RGB: #rrggbb */
snprintf(buf,sizeof(buf),str(LANG_COLOR_RGB_VALUE),
RGB_UNPACK_RED(color),
RGB_UNPACK_GREEN(color),
RGB_UNPACK_BLUE(color));
display->putsxy((LCD_WIDTH-(display->char_width*21))/2,text_top,buf);
if (display->depth > 1) {
display->set_foreground(color);
display->fillrect(SLIDER_START,LCD_HEIGHT-40,slider_width,35);
display->set_foreground(LCD_BLACK);
display->drawrect(SLIDER_START-1,LCD_HEIGHT-41,slider_width+2,37);
}
display->update();
}
/***********
set_color
returns true if USB was inserted, false otherwise
color is a pointer to the colour (in native format) to modify
***********/
bool set_color(struct screen *display,char *title, int* color)
{
int exit = 0, button, slider=0;
int rgb_val[3]; /* native depth r,g,b*/;
int fgcolor = display->get_foreground();
int newcolor = *color;
int i;
#if LCD_PIXELFORMAT == RGB565
rgb_val[0] = ((*color)&0xf800) >> 11;
rgb_val[1] = ((*color)&0x07e0) >> 5;
rgb_val[2] = ((*color)&0x001f);
#elif LCD_PIXELFORMAT == RGB565SWAPPED
rgb_val[0] = ((swap16(*color))&0xf800) >> 11;
rgb_val[1] = ((swap16(*color))&0x07e0) >> 5;
rgb_val[2] = ((swap16(*color))&0x001f);
#endif
while (!exit)
{
/* We need to maintain three versions of the colour:
rgb_val[3] - the native depth RGB values
newcolor - the native format packed colour
*/
#if LCD_PIXELFORMAT == RGB565
newcolor = (rgb_val[0] << 11) | (rgb_val[1] << 5) | (rgb_val[2]);
#elif LCD_PIXELFORMAT == RGB565SWAPPED
newcolor = swap16((rgb_val[0] << 11) | (rgb_val[1] << 5) | (rgb_val[2]));
#endif
FOR_NB_SCREENS(i)
draw_screen(&screens[i], title, rgb_val, newcolor, slider);
button = button_get(true);
switch (button)
{
case SLIDER_UP:
#ifdef HAVE_LCD_REMOTE
case SLIDER_RC_UP:
#endif
slider = (slider+2)%3;
break;
case SLIDER_DOWN:
#ifdef HAVE_LCD_REMOTE
case SLIDER_RC_DOWN:
#endif
slider = (slider+1)%3;
break;
case SLIDER_RIGHT:
case SLIDER_RIGHT|BUTTON_REPEAT:
#ifdef HAVE_LCD_REMOTE
case SLIDER_RC_RIGHT:
case SLIDER_RC_RIGHT|BUTTON_REPEAT:
#endif
if (rgb_val[slider] < max_val[slider])
rgb_val[slider]++;
break;
case SLIDER_LEFT:
case SLIDER_LEFT|BUTTON_REPEAT:
#ifdef HAVE_LCD_REMOTE
case SLIDER_RC_LEFT:
case SLIDER_RC_LEFT|BUTTON_REPEAT:
#endif
if (rgb_val[slider] > 0)
rgb_val[slider]--;
break;
case SLIDER_OK:
#ifdef HAVE_LCD_REMOTE
case SLIDER_RC_OK:
#endif
*color = newcolor;
exit = 1;
break;
case SLIDER_CANCEL:
#ifdef HAVE_LCD_REMOTE
case SLIDER_RC_CANCEL:
#endif
exit = 1;
break;
default:
if(default_event_handler(button) == SYS_USB_CONNECTED) {
display->set_foreground(fgcolor);
return true;
}
break;
}
}
display->set_foreground(fgcolor);
return false;
}

25
apps/gui/color_picker.h Normal file
View file

@ -0,0 +1,25 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) Jonathan Gordon (2006)
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "screen_access.h"
#ifdef HAVE_LCD_COLOR /* this file is a bit useless on non color lcds.. */
bool set_color(struct screen *display,char *title, int* color);
#endif

View file

@ -20,6 +20,7 @@
#ifndef _GUI_SPLASH_H_
#define _GUI_SPLASH_H_
#include "screen_access.h"
/*
* Puts a splash message on the given screen for a given period
* - screen : the screen to put the splash on

View file

@ -3748,3 +3748,33 @@ desc: in record settings menu.
eng: "Main and remote unit"
voice: "Main and remote unit"
new:
id: LANG_COLOR_RGB_LABELS
desc: what to show for the 'R' 'G' 'B' ONE LETTER EACH
eng: "RGB"
voice:
new:
id: LANG_COLOR_RGB_VALUE
desc: in color screen
eng: "RGB: %02X%02X%02X"
voice:
new:
id: LANG_BACKGROUND_COLOR
desc: menu entry to set the background color
eng: "Background Colour"
voice:
new:
id: LANG_FOREGROUND_COLOR
desc: menu entry to set the foreground color
eng: "Foreground Colour"
voice:
new:
id: LANG_RESET_COLORS
desc: menu
eng: "Reset Colours"
voice:
new:

View file

@ -515,7 +515,12 @@ int plugin_load(const char* plugin, void* parameter)
#ifdef HAVE_LCD_BITMAP
#if LCD_DEPTH > 1
#ifdef HAVE_LCD_COLOR
lcd_set_drawinfo(DRMODE_SOLID, global_settings.fg_color,
global_settings.bg_color);
#else
lcd_set_drawinfo(DRMODE_SOLID, LCD_DEFAULT_FG, LCD_DEFAULT_BG);
#endif
#else /* LCD_DEPTH == 1 */
lcd_set_drawmode(DRMODE_SOLID);
#endif /* LCD_DEPTH */

View file

@ -89,7 +89,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
#include "dsp.h"
#endif
#define CONFIG_BLOCK_VERSION 36
#define CONFIG_BLOCK_VERSION 37
#define CONFIG_BLOCK_SIZE 512
#define RTC_BLOCK_SIZE 44
@ -122,7 +122,7 @@ struct bit_entry
int default_val; /* min 15 bit */
/* variable name in a .cfg file, NULL if not to be saved */
const char* cfg_name;
/* set of values, or NULL for a numerical value */
/* set of values, "rgb" for a color, or NULL for a numerical value */
const char* cfg_val;
};
@ -545,6 +545,10 @@ static const struct bit_entry hd_bits[] =
{2, S_O(cliplight), 0, "cliplight", "off,main,both,remote" },
#endif /* CONFIG_BACKLIGHT */
#endif /*HAVE_RECORDING*/
#ifdef HAVE_LCD_COLOR
{LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"},
{LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"},
#endif
/* If values are just added to the end, no need to bump the version. */
/* new stuff to be added at the end */
@ -596,6 +600,39 @@ static void set_bits(
p[long_index] = (p[long_index] & ~mask) | (value << bit_index);
}
#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
/*
* Calculates the checksum for the config block and returns it
*/
@ -1013,6 +1050,8 @@ void settings_apply(void)
} else {
lcd_set_backdrop(NULL);
}
screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
screens[SCREEN_MAIN].set_background(global_settings.bg_color);
#endif
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
@ -1225,6 +1264,12 @@ static int load_cfg_table(
{ /* numerical value, just convert the string */
val = atoi(value);
}
#if HAVE_LCD_COLOR
else if (!strncasecmp(p_table[i].cfg_val,"rgb",4))
{
val = hex_to_rgb(value);
}
#endif
else
{ /* set of string values, find the index */
const char* item;
@ -1410,6 +1455,15 @@ static void save_cfg_table(const struct bit_entry* p_table, int count, int fd)
{
fdprintf(fd, "%s: %ld\r\n", p_run->cfg_name, value);
}
#ifdef HAVE_LCD_COLOR
else if (!strcasecmp(p_run->cfg_val, "rgb"))
{
fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name,
(int)RGB_UNPACK_RED(value),
(int)RGB_UNPACK_GREEN(value),
(int)RGB_UNPACK_BLUE(value));
}
#endif
else /* write as item */
{
const char* p = p_run->cfg_val;
@ -1566,6 +1620,9 @@ void settings_reset(void) {
global_settings.lang_file[0] = '\0';
#ifdef HAVE_LCD_COLOR
global_settings.backdrop_file[0] = '\0';
global_settings.fg_color = LCD_DEFAULT_FG;
global_settings.bg_color = LCD_DEFAULT_BG;
#endif
}

View file

@ -465,6 +465,10 @@ struct user_settings
bool warnon_erase_dynplaylist; /* warn when erasing dynamic playlist */
bool scroll_paginated; /* 0=dont 1=do */
#ifdef HAVE_LCD_COLOR
int bg_color; /* background color native format */
int fg_color; /* foreground color native format */
#endif
};
enum optiontype { INT, BOOL };

View file

@ -54,6 +54,7 @@
#include "splash.h"
#include "yesno.h"
#include "list.h"
#include "color_picker.h"
#ifdef HAVE_LCD_BITMAP
#include "peakmeter.h"
@ -319,6 +320,43 @@ static bool clear_main_backdrop(void)
lcd_set_backdrop(NULL);
return true;
}
/**
* Menu for fore/back colors
*/
static bool set_fg_color(void)
{
bool res;
res = set_color(&screens[SCREEN_MAIN],str(LANG_FOREGROUND_COLOR),
&global_settings.fg_color);
screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
return res;
}
static bool set_bg_color(void)
{
bool res;
res = set_color(&screens[SCREEN_MAIN],str(LANG_BACKGROUND_COLOR),
&global_settings.bg_color);
screens[SCREEN_MAIN].set_background(global_settings.bg_color);
return res;
}
static bool reset_color(void)
{
global_settings.fg_color = LCD_DEFAULT_FG;
global_settings.bg_color = LCD_DEFAULT_BG;
screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
screens[SCREEN_MAIN].set_background(global_settings.bg_color);
return false;
}
#endif
/**
@ -1586,6 +1624,9 @@ static bool lcd_settings_menu(void)
#endif
#ifdef HAVE_LCD_COLOR
{ ID2P(LANG_CLEAR_BACKDROP), clear_main_backdrop },
{ ID2P(LANG_BACKGROUND_COLOR), set_bg_color },
{ ID2P(LANG_FOREGROUND_COLOR), set_fg_color },
{ ID2P(LANG_RESET_COLORS), reset_color },
#endif
};

View file

@ -150,6 +150,9 @@ typedef void lcd_fastpixelfunc_type(fb_data *address);
#define LCD_MAX_RED 31
#define LCD_MAX_GREEN 63
#define LCD_MAX_BLUE 31
#define _RGB_UNPACK_RED(x) ((((x) >> 8) & 0xf8) | ((x) >> 13))
#define _RGB_UNPACK_GREEN(x) ((((x) >> 3) & 0xfc) | (((x) >> 9) & 0x03))
#define _RGB_UNPACK_BLUE(x) ((((x) << 3) & 0xf8) | (((x) >> 2) & 0x07))
#define _RGBPACK(r, g, b) ( ((((r) * (31*257) + (127*257)) >> 16) << 11) \
|((((g) * (63*257) + (127*257)) >> 16) << 5) \
| (((b) * (31*257) + (127*257)) >> 16))
@ -158,8 +161,14 @@ typedef void lcd_fastpixelfunc_type(fb_data *address);
#if (LCD_PIXELFORMAT == RGB565SWAPPED)
#define LCD_RGBPACK(r, g, b) ( ((_RGBPACK((r), (g), (b)) & 0xff00) >> 8) \
|((_RGBPACK((r), (g), (b)) & 0x00ff) << 8))
#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(swap16(x))
#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(swap16(x))
#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(swap16(x))
#else
#define LCD_RGBPACK(r, g, b) _RGBPACK((r), (g), (b))
#define RGB_UNPACK_RED(x) _RGB_UNPACK_RED(x)
#define RGB_UNPACK_GREEN(x) _RGB_UNPACK_GREEN(x)
#define RGB_UNPACK_BLUE(x) _RGB_UNPACK_BLUE(x)
#endif
#elif LCD_DEPTH == 18
#define LCD_MAX_RED 63