Rigging up do_color_sel() to offer immediate mode
The pick-a-color-from-the-canvas color selection feature (the option in the color palette showing a pipette icon) has been extended to support an immediate mode (return on "mouse-up" event, don't show a "Back" button, and don't animate the appearance of the color dialog at the bottom), which will be used by a forthcoming feature that will offer a keyboard shortcut to bring up this color selection option.
This commit is contained in:
parent
a927f7287b
commit
076b15fd20
2 changed files with 112 additions and 61 deletions
|
|
@ -70,6 +70,10 @@ http://www.tuxpaint.org/
|
||||||
* Show a "pipette"-shaped mouse pointer when selecting a
|
* Show a "pipette"-shaped mouse pointer when selecting a
|
||||||
color from the color palette, or the picture.
|
color from the color palette, or the picture.
|
||||||
|
|
||||||
|
* WIP Provide a keyboard shortcut for picking colors from
|
||||||
|
the canvas more quickly.
|
||||||
|
Closes https://sourceforge.net/p/tuxpaint/feature-requests/209/
|
||||||
|
|
||||||
* Localization Updates:
|
* Localization Updates:
|
||||||
---------------------
|
---------------------
|
||||||
* Albanian translation
|
* Albanian translation
|
||||||
|
|
|
||||||
169
src/tuxpaint.c
169
src/tuxpaint.c
|
|
@ -2179,7 +2179,7 @@ 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,
|
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);
|
char * *d_exts, int *white_in_palette);
|
||||||
static int do_color_picker(void);
|
static int do_color_picker(void);
|
||||||
static int do_color_sel(void);
|
static int do_color_sel(int temp_mode);
|
||||||
|
|
||||||
static int do_slideshow(void);
|
static int do_slideshow(void);
|
||||||
static void play_slideshow(int *selected, int num_selected, char *dirname, char **d_names, char **d_exts, int speed);
|
static void play_slideshow(int *selected, int num_selected, char *dirname, char **d_names, char **d_exts, int speed);
|
||||||
|
|
@ -4718,7 +4718,7 @@ static void mainloop(void)
|
||||||
if (cur_color == (unsigned)(NUM_COLORS - 1))
|
if (cur_color == (unsigned)(NUM_COLORS - 1))
|
||||||
do_color_picker();
|
do_color_picker();
|
||||||
else
|
else
|
||||||
do_color_sel();
|
do_color_sel(0);
|
||||||
|
|
||||||
if (cur_tool == TOOL_TEXT || cur_tool == TOOL_LABEL)
|
if (cur_tool == TOOL_TEXT || cur_tool == TOOL_LABEL)
|
||||||
{
|
{
|
||||||
|
|
@ -21885,9 +21885,17 @@ static Uint8 magic_touched(int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME
|
* Allow the user to select a color from one of the
|
||||||
|
* pixels within their picture.
|
||||||
|
*
|
||||||
|
* @param boolean temp_mode - whether to only appear
|
||||||
|
* while a shortcut key is being held
|
||||||
|
* (if not, the mouse will be positioned at the bottom
|
||||||
|
* center, the UI will show a "Back" button, and wait
|
||||||
|
* for a color to be clicked in the canvas, or the "Back"
|
||||||
|
* button to be clicked)
|
||||||
*/
|
*/
|
||||||
static int do_color_sel(void)
|
static int do_color_sel(int temp_mode)
|
||||||
{
|
{
|
||||||
#ifndef NO_PROMPT_SHADOWS
|
#ifndef NO_PROMPT_SHADOWS
|
||||||
SDL_Surface *alpha_surf;
|
SDL_Surface *alpha_surf;
|
||||||
|
|
@ -21903,9 +21911,18 @@ static int do_color_sel(void)
|
||||||
int done, chose;
|
int done, chose;
|
||||||
int back_left, back_top;
|
int back_left, back_top;
|
||||||
int color_sel_x = 0, color_sel_y = 0;
|
int color_sel_x = 0, color_sel_y = 0;
|
||||||
int want_animated_popups = 1;
|
int want_animated_popups;
|
||||||
SDL_Surface *tmp_btn_up, *tmp_btn_down;
|
SDL_Surface *tmp_btn_up, *tmp_btn_down;
|
||||||
|
|
||||||
|
if (!temp_mode)
|
||||||
|
{
|
||||||
|
want_animated_popups = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
want_animated_popups = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Uint32(*getpixel_tmp_btn_up) (SDL_Surface *, int, int);
|
Uint32(*getpixel_tmp_btn_up) (SDL_Surface *, int, int);
|
||||||
Uint32(*getpixel_tmp_btn_down) (SDL_Surface *, int, int);
|
Uint32(*getpixel_tmp_btn_down) (SDL_Surface *, int, int);
|
||||||
Uint32(*getpixel_img_paintwell) (SDL_Surface *, int, int);
|
Uint32(*getpixel_img_paintwell) (SDL_Surface *, int, int);
|
||||||
|
|
@ -21922,8 +21939,6 @@ static int do_color_sel(void)
|
||||||
val_x = val_y = motioner = 0;
|
val_x = val_y = motioner = 0;
|
||||||
valhat_x = valhat_y = hatmotioner = 0;
|
valhat_x = valhat_y = hatmotioner = 0;
|
||||||
|
|
||||||
/* FIXME this is the first step to make animated popups optional,
|
|
||||||
to be removed from here when implemented in a more general way */
|
|
||||||
|
|
||||||
hide_blinking_cursor();
|
hide_blinking_cursor();
|
||||||
|
|
||||||
|
|
@ -22016,13 +22031,11 @@ static int do_color_sel(void)
|
||||||
|
|
||||||
/* Determine spot for example color: */
|
/* Determine spot for example color: */
|
||||||
|
|
||||||
|
|
||||||
color_example_dest.x = r_color_sel.x + 2;
|
color_example_dest.x = r_color_sel.x + 2;
|
||||||
color_example_dest.y = r_color_sel.y + 2;
|
color_example_dest.y = r_color_sel.y + 2;
|
||||||
color_example_dest.w = r_color_sel.w - button_w - 8;
|
color_example_dest.w = r_color_sel.w - button_w - 8;
|
||||||
color_example_dest.h = r_color_sel.h - 4;
|
color_example_dest.h = r_color_sel.h - 4;
|
||||||
|
|
||||||
|
|
||||||
SDL_FillRect(screen, &color_example_dest, SDL_MapRGB(screen->format, 0, 0, 0));
|
SDL_FillRect(screen, &color_example_dest, SDL_MapRGB(screen->format, 0, 0, 0));
|
||||||
|
|
||||||
color_example_dest.x += 2;
|
color_example_dest.x += 2;
|
||||||
|
|
@ -22039,29 +22052,38 @@ static int do_color_sel(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Draw current color picker color: */
|
if (!temp_mode)
|
||||||
|
{
|
||||||
|
/* Draw current color picker color: */
|
||||||
|
|
||||||
|
SDL_FillRect(screen, &color_example_dest,
|
||||||
|
SDL_MapRGB(screen->format,
|
||||||
|
color_hexes[NUM_COLORS - 2][0],
|
||||||
|
color_hexes[NUM_COLORS - 2][1], color_hexes[NUM_COLORS - 2][2]));
|
||||||
|
|
||||||
SDL_FillRect(screen, &color_example_dest,
|
/* Show "Back" button */
|
||||||
SDL_MapRGB(screen->format,
|
back_left = r_color_sel.x + r_color_sel.w - button_w - 4;
|
||||||
color_hexes[NUM_COLORS - 2][0],
|
back_top = r_color_sel.y;
|
||||||
color_hexes[NUM_COLORS - 2][1], color_hexes[NUM_COLORS - 2][2]));
|
|
||||||
|
dest.x = back_left;
|
||||||
|
dest.y = back_top;
|
||||||
|
|
||||||
/* Show "Back" button */
|
SDL_BlitSurface(img_back, NULL, screen, &dest);
|
||||||
|
|
||||||
back_left = r_color_sel.x + r_color_sel.w - button_w - 4;
|
dest.x = back_left + (img_back->w - img_openlabels_back->w) / 2;
|
||||||
back_top = r_color_sel.y;
|
dest.y = back_top + img_back->h - img_openlabels_back->h;
|
||||||
|
SDL_BlitSurface(img_openlabels_back, NULL, screen, &dest);
|
||||||
dest.x = back_left;
|
}
|
||||||
dest.y = back_top;
|
else
|
||||||
|
{
|
||||||
SDL_BlitSurface(img_back, NULL, screen, &dest);
|
int mx, my;
|
||||||
|
|
||||||
dest.x = back_left + (img_back->w - img_openlabels_back->w) / 2;
|
|
||||||
dest.y = back_top + img_back->h - img_openlabels_back->h;
|
|
||||||
SDL_BlitSurface(img_openlabels_back, NULL, screen, &dest);
|
|
||||||
|
|
||||||
|
/* Temp mode: Grab color from canvas under the mouse immediately
|
||||||
|
(let the motion-handling code in the loop below do it for us!) */
|
||||||
|
SDL_GetMouseState(&mx, &my);
|
||||||
|
SDL_WarpMouse(mx - 1, my); /* Need to move to a different spot, or no events occur */
|
||||||
|
SDL_WarpMouse(mx, my);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Blit canvas on screen */
|
/* Blit canvas on screen */
|
||||||
|
|
@ -22078,8 +22100,11 @@ static int do_color_sel(void)
|
||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
/* FIXME: Strangely, this SDL_WarpMouse makes further event.button.x/y to be 0 on Android, thus making the selector unresponsive.
|
/* FIXME: Strangely, this SDL_WarpMouse makes further event.button.x/y to be 0 on Android, thus making the selector unresponsive.
|
||||||
Needs testing on other operating sistems with touchscreen. */
|
Needs testing on other operating sistems with touchscreen. */
|
||||||
SDL_WarpMouse(r_color_sel.x + r_color_sel.w / 2, r_color_sel.y + r_color_sel.h / 2);
|
|
||||||
|
if (!temp_mode)
|
||||||
|
SDL_WarpMouse(r_color_sel.x + r_color_sel.w / 2, r_color_sel.y + r_color_sel.h / 2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (SDL_PollEvent(&event))
|
while (SDL_PollEvent(&event))
|
||||||
|
|
@ -22107,6 +22132,7 @@ static int do_color_sel(void)
|
||||||
|
|
||||||
if (key == SDLK_ESCAPE)
|
if (key == SDLK_ESCAPE)
|
||||||
{
|
{
|
||||||
|
/* Hit [Escape]; abort (in either full UI or temporary mode) */
|
||||||
chose = 0;
|
chose = 0;
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -22117,7 +22143,7 @@ static int do_color_sel(void)
|
||||||
event.button.x < r_canvas.x + r_canvas.w &&
|
event.button.x < r_canvas.x + r_canvas.w &&
|
||||||
event.button.y >= r_canvas.y && event.button.y < r_canvas.y + r_canvas.h)
|
event.button.y >= r_canvas.y && event.button.y < r_canvas.y + r_canvas.h)
|
||||||
{
|
{
|
||||||
/* Picked a color! */
|
/* Picked a color in the canvas, and released! */
|
||||||
|
|
||||||
chose = 1;
|
chose = 1;
|
||||||
done = 1;
|
done = 1;
|
||||||
|
|
@ -22128,14 +22154,26 @@ static int do_color_sel(void)
|
||||||
color_sel_x = x;
|
color_sel_x = x;
|
||||||
color_sel_y = y;
|
color_sel_y = y;
|
||||||
}
|
}
|
||||||
else if (event.button.x >= back_left &&
|
else
|
||||||
event.button.x < back_left + img_back->w &&
|
|
||||||
event.button.y >= back_top && event.button.y < back_top + img_back->h)
|
|
||||||
{
|
{
|
||||||
/* Decided to go Back */
|
if (!temp_mode)
|
||||||
|
{
|
||||||
chose = 0;
|
if (event.button.x >= back_left &&
|
||||||
done = 1;
|
event.button.x < back_left + img_back->w &&
|
||||||
|
event.button.y >= back_top && event.button.y < back_top + img_back->h)
|
||||||
|
{
|
||||||
|
/* Full UI mode: Decided to go Back; abort */
|
||||||
|
|
||||||
|
chose = 0;
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Temp mode: Released outside of canvas; abort */
|
||||||
|
chose = 0;
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event.type == SDL_MOUSEMOTION)
|
else if (event.type == SDL_MOUSEMOTION)
|
||||||
|
|
@ -22144,7 +22182,7 @@ static int do_color_sel(void)
|
||||||
event.button.x < r_canvas.x + r_canvas.w &&
|
event.button.x < r_canvas.x + r_canvas.w &&
|
||||||
event.button.y >= r_canvas.y && event.button.y < r_canvas.y + r_canvas.h)
|
event.button.y >= r_canvas.y && event.button.y < r_canvas.y + r_canvas.h)
|
||||||
{
|
{
|
||||||
/* Hovering over the colors! */
|
/* Hovering over the canvas! */
|
||||||
|
|
||||||
do_setcursor(cursor_pipette);
|
do_setcursor(cursor_pipette);
|
||||||
|
|
||||||
|
|
@ -22165,27 +22203,32 @@ static int do_color_sel(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Revert to current color picker color, so we know what it was,
|
/* Outside the canvas... */
|
||||||
and what we'll get if we go Back: */
|
|
||||||
|
|
||||||
SDL_FillRect(screen, &color_example_dest,
|
if (!temp_mode)
|
||||||
SDL_MapRGB(screen->format,
|
{
|
||||||
color_hexes[NUM_COLORS - 2][0],
|
/* Revert to current color picker color, so we know what it was,
|
||||||
color_hexes[NUM_COLORS - 2][1], color_hexes[NUM_COLORS - 2][2]));
|
and what we'll get if we go Back: */
|
||||||
|
|
||||||
SDL_UpdateRect(screen,
|
SDL_FillRect(screen, &color_example_dest,
|
||||||
color_example_dest.x,
|
SDL_MapRGB(screen->format,
|
||||||
color_example_dest.y, color_example_dest.w, color_example_dest.h);
|
color_hexes[NUM_COLORS - 2][0],
|
||||||
|
color_hexes[NUM_COLORS - 2][1], color_hexes[NUM_COLORS - 2][2]));
|
||||||
|
|
||||||
/* Change cursor to arrow (or hand, if over Back): */
|
SDL_UpdateRect(screen,
|
||||||
|
color_example_dest.x,
|
||||||
if (event.button.x >= back_left &&
|
color_example_dest.y, color_example_dest.w, color_example_dest.h);
|
||||||
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);
|
/* Change cursor to arrow (or hand, if over Back): */
|
||||||
else
|
|
||||||
do_setcursor(cursor_arrow);
|
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
|
||||||
|
do_setcursor(cursor_arrow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oldpos_x = event.motion.x;
|
oldpos_x = event.motion.x;
|
||||||
|
|
@ -22299,7 +22342,11 @@ static int do_color_sel(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME
|
* Display a large prompt, allowing the user to pick a
|
||||||
|
* color from a large palette.
|
||||||
|
*
|
||||||
|
* FIXME: Various options here would be helpful
|
||||||
|
* (RGB, HSV, color wheel, etc.) -bjk 2022.01.25
|
||||||
*/
|
*/
|
||||||
static int do_color_picker(void)
|
static int do_color_picker(void)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue