From 0c858122b5a94cf7b3927521a135caba9b5cde62 Mon Sep 17 00:00:00 2001 From: Bill Kendrick Date: Wed, 2 Mar 2022 01:30:36 -0800 Subject: [PATCH] Color picker now offers full HSV selection Added a slider to choose value, which re-renders the rainbow-colored box on the left (which now only displays hue/saturation). --- data/images/ui/color_picker_val.png | Bin 0 -> 13259 bytes docs/CHANGES.txt | 6 +- src/tuxpaint.c | 305 ++++++++++++++++++++++------ 3 files changed, 247 insertions(+), 64 deletions(-) create mode 100644 data/images/ui/color_picker_val.png diff --git a/data/images/ui/color_picker_val.png b/data/images/ui/color_picker_val.png new file mode 100644 index 0000000000000000000000000000000000000000..f075676f441647beff03eeaf10c47e92e0bda87f GIT binary patch literal 13259 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 literal 0 HcmV?d00001 diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index a7d38156c..45e62dfec 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -7,7 +7,7 @@ Various contributors (see below, and AUTHORS.txt) http://www.tuxpaint.org/ -2022.February.27 (0.9.28) +2022.March.2 (0.9.28) * Improvements to "Paint" and "Lines" tools: ------------------------------------------ * Brush spacing may now be altered within Tux Paint. @@ -106,6 +106,10 @@ http://www.tuxpaint.org/ form a desired color. Undo/Redo is available! Bill Kendrick + * The rainbow palette color picker now acts as a true + Hue/Saturation/Value picker, with the addition of a "value" slider. + Bill Kendrick + * Show a "pipette"-shaped mouse pointer when selecting a color from the color palette, or the picture. Bill Kendrick diff --git a/src/tuxpaint.c b/src/tuxpaint.c index 0276a307f..1866f1b9d 100644 --- a/src/tuxpaint.c +++ b/src/tuxpaint.c @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (See COPYING.txt) - June 14, 2002 - February 23, 2022 + June 14, 2002 - March 2, 2022 */ #include "platform.h" @@ -1523,8 +1523,9 @@ static SDL_Surface *img_magic_paint, *img_magic_fullscreen; static SDL_Surface *img_shapes_corner, *img_shapes_center; static SDL_Surface *img_bold, *img_italic; static SDL_Surface *img_label_select, *img_label_apply; -static SDL_Surface *img_color_picker, *img_color_picker_thumb, *img_paintwell, *img_color_sel, *img_color_mix; -static int color_picker_x, color_picker_y; +static SDL_Surface *img_color_picker, *img_color_picker_thumb, *img_color_picker_val; +static SDL_Surface *img_paintwell, *img_color_sel, *img_color_mix; +static int color_picker_x, color_picker_y, color_picker_v; static int color_mixer_reset; static SDL_Surface *img_title_on, *img_title_off, *img_title_large_on, *img_title_large_off; @@ -2093,6 +2094,9 @@ static int do_new_dialog(void); static int do_new_dialog_add_colors(SDL_Surface * *thumbs, int num_files, int *d_places, char * *d_names, char * *d_exts, int *white_in_palette); static int do_color_picker(void); +static void draw_color_picker_crosshairs(int color_picker_left, int color_picker_top, int color_picker_val_left, int color_picker_val_top); +static void draw_color_picker_values(int l, int t); +static void render_color_picker_palette(void); static int do_color_sel(int temp_mode); static int do_color_mix(void); static void draw_color_mixer_blank_example(void); @@ -21886,7 +21890,8 @@ static int do_color_picker(void) SDL_Event event; SDLKey key; int color_picker_left, color_picker_top; - int back_left, back_top; + int color_picker_val_left, color_picker_val_top; + int back_left, back_top, done_left, done_top; SDL_Rect color_example_dest; SDL_Surface *backup; SDL_Rect r_color_picker; @@ -21895,7 +21900,9 @@ static int do_color_picker(void) valhat_x = valhat_y = hatmotioner = 0; hide_blinking_cursor(); + do_setcursor(cursor_hand); + getpixel_img_color_picker = getpixels[img_color_picker->format->BytesPerPixel]; /* Draw button box: */ @@ -21975,6 +21982,8 @@ static int do_color_picker(void) /* Draw color palette: */ + render_color_picker_palette(); + color_picker_left = r_final.x; color_picker_top = r_final.y; @@ -21989,42 +21998,25 @@ static int do_color_picker(void) r_color_picker.h = dest.h; - /* Draw last color position: */ + /* Draw values: */ - dest.x = color_picker_x + color_picker_left - 3; - dest.y = color_picker_y + color_picker_top - 1; - dest.w = 7; - dest.h = 3; + color_picker_val_left = color_picker_left + img_color_picker->w + 2; + color_picker_val_top = color_picker_top; - SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 0, 0)); + draw_color_picker_values(color_picker_val_left, color_picker_val_top); - dest.x = color_picker_x + color_picker_left - 1; - dest.y = color_picker_y + color_picker_top - 3; - dest.w = 3; - dest.h = 7; - SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 0, 0)); + /* Draw crosshairs */ - dest.x = color_picker_x + color_picker_left - 2; - dest.y = color_picker_y + color_picker_top; - dest.w = 5; - dest.h = 1; + draw_color_picker_crosshairs(color_picker_left, color_picker_top, color_picker_val_left, color_picker_val_top); - SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 255, 255, 255)); - - dest.x = color_picker_x + color_picker_left; - dest.y = color_picker_y + color_picker_top - 2; - dest.w = 1; - dest.h = 5; - - SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 255, 255, 255)); /* Determine spot for example color: */ - color_example_dest.x = color_picker_left + img_color_picker->w + 2; + color_example_dest.x = color_picker_left + img_color_picker->w + 2 + img_back->w + 2; color_example_dest.y = color_picker_top + 2; - color_example_dest.w = r_final.w / 2 - 2; + color_example_dest.w = r_final.w / 2 - 2 - img_back->w - 2; color_example_dest.h = r_final.h / 2 - 4; @@ -22055,8 +22047,7 @@ static int do_color_picker(void) /* Show "Back" button */ - back_left = - (((PROMPT_W - 96 * 2) + w * 2 - img_color_picker->w) - img_back->w) / 2 + color_picker_left + img_color_picker->w; + back_left = r_final.x + r_final.w - img_back->w - 2; back_top = color_picker_top + img_color_picker->h - img_back->h - 2; dest.x = back_left; @@ -22069,6 +22060,15 @@ static int do_color_picker(void) SDL_BlitSurface(img_openlabels_back, NULL, screen, &dest); + /* Show "Done" button */ + done_left = back_left - img_yes->w - 2; + done_top = back_top; + + dest.x = done_left; + dest.y = done_top; + + SDL_BlitSurface(img_yes, NULL, screen, &dest); + SDL_Flip(screen); @@ -22114,18 +22114,87 @@ static int do_color_picker(void) { if (event.button.x >= color_picker_left && event.button.x < color_picker_left + img_color_picker->w && - event.button.y >= color_picker_top && event.button.y < color_picker_top + img_color_picker->h) + event.button.y >= color_picker_top && + event.button.y < color_picker_top + img_color_picker->h) { /* Picked a color! */ - chose = 1; - done = 1; - x = event.button.x - color_picker_left; y = event.button.y - color_picker_top; color_picker_x = x; color_picker_y = y; + + /* Update (entire) color box */ + SDL_GetRGB(getpixel_img_color_picker(img_color_picker, x, y), img_color_picker->format, &r, &g, &b); + + SDL_FillRect(screen, &color_example_dest, SDL_MapRGB(screen->format, r, g, b)); + + SDL_UpdateRect(screen, + color_example_dest.x, color_example_dest.y, + color_example_dest.w, color_example_dest.h); + + + /* Reposition hue/sat crosshair */ + dest.x = color_picker_left; + dest.y = color_picker_top; + SDL_BlitSurface(img_color_picker, NULL, screen, &dest); + draw_color_picker_crosshairs(color_picker_left, color_picker_top, color_picker_val_left, color_picker_val_top); + SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); + } + else if (event.button.x >= color_picker_val_left && + event.button.y >= color_picker_val_top && + event.button.x <= color_picker_val_left + img_back->w && + event.button.y <= color_picker_val_top + img_color_picker_val->h) + { + /* Picked a value from the slider */ + + y = event.button.y - color_picker_val_top; + color_picker_v = y; + + /* Re-render the palette with the new value */ + render_color_picker_palette(); + + /* Update (entire) color box */ + SDL_GetRGB(getpixel_img_color_picker(img_color_picker, color_picker_x, color_picker_y), img_color_picker->format, &r, &g, &b); + + SDL_FillRect(screen, &color_example_dest, SDL_MapRGB(screen->format, r, g, b)); + + SDL_UpdateRect(screen, + color_example_dest.x, color_example_dest.y, + color_example_dest.w, color_example_dest.h); + + + /* Redraw hue/sat palette, and val slider, and redraw crosshairs */ + draw_color_picker_values(color_picker_val_left, color_picker_val_top); + + dest.x = color_picker_left; + dest.y = color_picker_top; + SDL_BlitSurface(img_color_picker, NULL, screen, &dest); + SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); + + draw_color_picker_crosshairs(color_picker_left, color_picker_top, color_picker_val_left, color_picker_val_top); + + dest.x = color_picker_val_left; + dest.y = color_picker_val_top; + dest.w = img_back->w; + dest.h = img_color_picker_val->h; + SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); + + dest.x = color_picker_left; + dest.y = color_picker_top; + dest.w = img_color_picker->w; + dest.h = img_color_picker->h; + SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); + } + else if (event.button.x >= done_left && + event.button.x < done_left + img_yes->w && + event.button.y >= done_top && event.button.y < done_top + img_yes->h) + { + /* Accepting color */ + + chose = 1; + done = 1; } else if (event.button.x >= back_left && event.button.x < back_left + img_back->w && @@ -22153,37 +22222,40 @@ static int do_color_picker(void) x = event.button.x - color_picker_left; y = event.button.y - color_picker_top; - getpixel_img_color_picker = getpixels[img_color_picker->format->BytesPerPixel]; SDL_GetRGB(getpixel_img_color_picker(img_color_picker, x, y), img_color_picker->format, &r, &g, &b); + dest.x = color_example_dest.x + color_example_dest.w / 4; + dest.y = color_example_dest.y + color_example_dest.h / 4; + dest.w = color_example_dest.w / 2; + dest.h = color_example_dest.h / 2; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, r, g, b)); + + SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); + } + else + { + /* Revert to current color picker color */ + + SDL_GetRGB(getpixel_img_color_picker(img_color_picker, color_picker_x, color_picker_y), + img_color_picker->format, &r, &g, &b); + SDL_FillRect(screen, &color_example_dest, SDL_MapRGB(screen->format, r, g, b)); SDL_UpdateRect(screen, - color_example_dest.x, - color_example_dest.y, color_example_dest.w, color_example_dest.h); - } - else - { - /* Revert to current color picker color, so we know what it was, - and what we'll get if we go Back: */ + color_example_dest.x, color_example_dest.y, + color_example_dest.w, color_example_dest.h); - SDL_FillRect(screen, &color_example_dest, - SDL_MapRGB(screen->format, - color_hexes[COLOR_PICKER][0], - color_hexes[COLOR_PICKER][1], - color_hexes[COLOR_PICKER][2])); - - SDL_UpdateRect(screen, - color_example_dest.x, - color_example_dest.y, color_example_dest.w, color_example_dest.h); - - - /* Change cursor to arrow (or hand, if over Back): */ + /* Change cursor to arrow (or hand, if over Back or Done): */ if (event.button.x >= back_left && event.button.x < back_left + img_back->w && event.button.y >= back_top && event.button.y < back_top + img_back->h) do_setcursor(cursor_hand); + else if (event.button.x >= done_left && + event.button.x < done_left + img_yes->w && + event.button.y >= done_top && event.button.y < done_top + img_yes->h) + do_setcursor(cursor_hand); else do_setcursor(cursor_arrow); } @@ -22216,8 +22288,7 @@ static int do_color_picker(void) if (chose) { - getpixel_img_color_picker = getpixels[img_color_picker->format->BytesPerPixel]; - SDL_GetRGB(getpixel_img_color_picker(img_color_picker, x, y), img_color_picker->format, &r, &g, &b); + SDL_GetRGB(getpixel_img_color_picker(img_color_picker, color_picker_x, color_picker_y), img_color_picker->format, &r, &g, &b); color_hexes[COLOR_PICKER][0] = r; color_hexes[COLOR_PICKER][1] = g; @@ -22238,6 +22309,112 @@ static int do_color_picker(void) } +static void render_color_picker_palette(void) +{ + int x, y; + Uint8 r, g, b; + void (*putpixel) (SDL_Surface *, int, int, Uint32); + + putpixel = putpixels[img_color_picker->format->BytesPerPixel]; + for (y = 0; y < img_color_picker->h; y++) + { + for (x = 0; x < img_color_picker->w; x++) + { + hsvtorgb((((float) y * 360.0) / ((float) img_color_picker->h)), + ((float) x / ((float) img_color_picker->w)), + 1.0 - (((float) color_picker_v) / ((float) img_color_picker_val->h)), + &r, &g, &b); + putpixel(img_color_picker, x, y, + SDL_MapRGBA(img_color_picker->format, r, g, b, 255)); + } + } +} + + +static void draw_color_picker_crosshairs(int color_picker_left, int color_picker_top, int color_picker_val_left, int color_picker_val_top) +{ + SDL_Rect dest; + int ctr_x; + + /* Hue/Saturation (the big rectangle) */ + + dest.x = color_picker_x + color_picker_left - 3; + dest.y = color_picker_y + color_picker_top - 1; + dest.w = 7; + dest.h = 3; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 0, 0)); + + dest.x = color_picker_x + color_picker_left - 1; + dest.y = color_picker_y + color_picker_top - 3; + dest.w = 3; + dest.h = 7; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 0, 0)); + + dest.x = color_picker_x + color_picker_left - 2; + dest.y = color_picker_y + color_picker_top; + dest.w = 5; + dest.h = 1; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 255, 255, 255)); + + dest.x = color_picker_x + color_picker_left; + dest.y = color_picker_y + color_picker_top - 2; + dest.w = 1; + dest.h = 5; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 255, 255, 255)); + + + /* Value (the slider) */ + + ctr_x = color_picker_val_left + img_back->w / 2; + + dest.x = ctr_x - 3; + dest.y = color_picker_v + color_picker_val_top - 1; + dest.w = 7; + dest.h = 3; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 0, 0)); + + dest.x = ctr_x - 1; + dest.y = color_picker_v + color_picker_val_top - 3; + dest.w = 3; + dest.h = 7; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 0, 0)); + + dest.x = ctr_x - 2; + dest.y = color_picker_v + color_picker_val_top; + dest.w = 5; + dest.h = 1; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 255, 255, 255)); + + dest.x = ctr_x; + dest.y = color_picker_v + color_picker_val_top - 2; + dest.w = 1; + dest.h = 5; + + SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 255, 255, 255)); +} + + +static void draw_color_picker_values(int l, int t) +{ + SDL_Rect dest; + + dest.x = l; + dest.y = t; + dest.w = img_color_picker_val->w; + dest.h = img_color_picker_val->h; + + SDL_BlitSurface(img_color_picker_val, NULL, screen, &dest); + SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); +} + + enum { COLOR_MIXER_BTN_RED, COLOR_MIXER_BTN_YELLOW, @@ -25954,13 +26131,14 @@ static void setup_colors(void) /* Add "Color Picker" color: */ - color_names[NUM_COLORS] = strdup(gettext("Pick a color.")); + color_names[NUM_COLORS] = strdup(gettext("Pick a color. The square shows all hues at varying levels of saturation. Use the slider to change the value.")); color_hexes[NUM_COLORS] = (Uint8 *) malloc(sizeof(Uint8) * 3); - color_hexes[NUM_COLORS][0] = 0; - color_hexes[NUM_COLORS][1] = 0; - color_hexes[NUM_COLORS][2] = 0; - color_picker_x = 0; - color_picker_y = 0; + color_hexes[NUM_COLORS][0] = 255; + color_hexes[NUM_COLORS][1] = 255; + color_hexes[NUM_COLORS][2] = 255; + color_picker_x = 0; /* Saturation */ + color_picker_y = 0; /* Hue */ + color_picker_v = 0; /* Value */ NUM_COLORS++; /* Add "Color Mixer" color: */ @@ -26926,6 +27104,7 @@ static void setup(void) show_progress_bar(screen); img_color_picker = loadimagerb(DATA_PREFIX "images/ui/color_picker.png"); + img_color_picker_val = loadimagerb(DATA_PREFIX "images/ui/color_picker_val.png"); /* Create toolbox and selector labels: */