Added support to drag & drop colors in color-bar (feature request #2109224).

Added "RectTracker".
Renamed "rectsave" function to "rect_tracker_new".
Joined "rectrestore" and "rectdiscard" to "rect_tracker_free".
This commit is contained in:
David Capello 2008-09-27 18:04:55 +00:00
parent 5784cb720e
commit 24ca4562dc
7 changed files with 152 additions and 117 deletions

View File

@ -356,17 +356,16 @@ void backclip(void *_data)
jfree(data);
}
/**********************************************************************/
/* Save/Restore rectangles */
typedef struct RECT_DATA
/* Rectangle Tracker (Save/Restore rectangles from/to the screen) */
struct RectTracker
{
BITMAP *bmp;
int x1, y1, x2, y2;
int npixel;
int *pixel;
} RECT_DATA;
};
static void do_rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int c,
void (*proc)(BITMAP *bmp, int x, int y, int c))
@ -406,31 +405,33 @@ static void do_rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int c,
static void count_rect(BITMAP *bmp, int x, int y, int c)
{
RECT_DATA *data = (RECT_DATA *)c;
RectTracker *data = (RectTracker *)c;
data->npixel++;
}
static void save_rect(BITMAP *bmp, int x, int y, int c)
{
RECT_DATA *data = (RECT_DATA *)c;
RectTracker *data = (RectTracker *)c;
data->pixel[data->npixel++] = getpixel(bmp, x, y);
}
static void restore_rect(BITMAP *bmp, int x, int y, int c)
{
RECT_DATA *data = (RECT_DATA *)c;
RectTracker *data = (RectTracker *)c;
putpixel(bmp, x, y, data->pixel[data->npixel++]);
}
void *rectsave(BITMAP *bmp, int x1, int y1, int x2, int y2)
RectTracker *rect_tracker_new(BITMAP *bmp, int x1, int y1, int x2, int y2)
{
RECT_DATA *data;
RectTracker *data;
int x, y;
jmouse_hide();
if (x1 > x2) { x = x1; x1 = x2; x2 = x; }
if (y1 > y2) { y = y1; y1 = y2; y2 = y; }
data = jnew(RECT_DATA, 1);
data = jnew(RectTracker, 1);
data->bmp = bmp;
data->x1 = x1;
@ -449,30 +450,29 @@ void *rectsave(BITMAP *bmp, int x1, int y1, int x2, int y2)
data->npixel = 0;
do_rect(bmp, x1, y1, x2, y2, (int)data, save_rect);
jmouse_show();
return data;
}
void rectrestore(void *_data)
void rect_tracker_free(RectTracker *data)
{
RECT_DATA *data = _data;
jmouse_hide();
data->npixel = 0;
do_rect(data->bmp, data->x1, data->y1, data->x2, data->y2,
(int)data, restore_rect);
}
void rectdiscard(void *_data)
{
RECT_DATA *data = _data;
if (data->pixel != NULL)
jfree(data->pixel);
jfree(data);
jmouse_show();
}
/**********************************************************************/
/* Rectangles */
void bevel_box(BITMAP *bmp, int x1, int y1, int x2, int y2, int c1, int c2, int bevel)
{
hline(bmp, x1+bevel, y1, x2-bevel, c1); /* top */
@ -612,7 +612,7 @@ void draw_color_button(BITMAP *bmp,
int x1, int y1, int x2, int y2,
int b0, int b1, int b2, int b3,
int imgtype, color_t color,
bool hot)
bool hot, bool drag)
{
int face = ji_color_face();
int fore = ji_color_foreground();
@ -664,6 +664,13 @@ void draw_color_button(BITMAP *bmp,
hline(bmp, x2-1, y2, x2, face);
putpixel(bmp, x2-1, y2-1, fore);
}
if (drag) {
rect(bmp, x1+2, y1+2, x2-2, y2-2,
blackandwhite_neg(color_get_red(imgtype, color),
color_get_green(imgtype, color),
color_get_blue(imgtype, color)));
}
}
/************************************************************************/

View File

@ -93,6 +93,8 @@ enum {
GFX_BITMAP_COUNT,
};
typedef struct RectTracker RectTracker;
int init_module_graphics(void);
void exit_module_graphics(void);
@ -104,9 +106,8 @@ void simple_dotted_mode(struct BITMAP *bmp, int fg, int bg);
void *subclip(struct BITMAP *bmp, int x1, int y1, int x2, int y2);
void backclip(void *data);
void *rectsave(struct BITMAP *bmp, int x1, int y1, int x2, int y2);
void rectrestore(void *data);
void rectdiscard(void *data);
RectTracker *rect_tracker_new(struct BITMAP *bmp, int x1, int y1, int x2, int y2);
void rect_tracker_free(RectTracker *tracker);
void bevel_box(struct BITMAP *bmp, int x1, int y1, int x2, int y2, int c1, int c2, int bevel);
void rectdotted(struct BITMAP *bmp, int x1, int y1, int x2, int y2, int fg, int bg);
@ -119,7 +120,7 @@ void draw_color_button(struct BITMAP *bmp,
int x1, int y1, int x2, int y2,
int b0, int b1, int b2, int b3,
int imgtype, color_t color,
bool hot);
bool hot, bool drag);
int character_length(struct FONT *font, int chr);
void render_character(struct BITMAP *bmp, struct FONT *font, int chr, int x, int y, int fg, int bg);

View File

@ -820,16 +820,15 @@ Tool *tools_list[] =
/* TOOL CONTROL */
/***********************************************************/
static void *rect_data = NULL;
static void *rect_tracker = NULL;
static void fourchain_line(int x1, int y1, int x2, int y2, ToolData *data);
static void marker_scroll_callback(int before_change)
{
if (before_change && rect_data) {
rectrestore(rect_data);
rectdiscard(rect_data);
rect_data = NULL;
if (before_change && rect_tracker) {
rect_tracker_free(rect_tracker);
rect_tracker = NULL;
}
}
@ -1054,9 +1053,9 @@ void control_tool(JWidget widget, Tool *tool,
y2 = y1 + SGN(dy) * size;
if (tool->flags & TOOL_EIGHT_ANGLES) {
if (ABS (dx) <= ABS (dy)/2)
if (ABS(dx) <= ABS(dy)/2)
x2 = x1;
else if (ABS (dy) <= ABS (dx)/2)
else if (ABS(dy) <= ABS(dx)/2)
y2 = y1;
}
}
@ -1210,11 +1209,9 @@ void control_tool(JWidget widget, Tool *tool,
outx2 += (1<<editor->zoom)-1;
outy2 += (1<<editor->zoom)-1;
if (rect_data) {
rectrestore(rect_data);
rectdiscard(rect_data);
}
rect_data = rectsave(ji_screen, outx1, outy1, outx2, outy2);
if (rect_tracker)
rect_tracker_free(rect_tracker);
rect_tracker = rect_tracker_new(ji_screen, outx1, outy1, outx2, outy2);
dotted_mode(0);
@ -1540,10 +1537,9 @@ void control_tool(JWidget widget, Tool *tool,
if (tool_data.dst_image) image_free(tool_data.dst_image);
/* destroy rect-data used by the marker tool */
if (rect_data) {
rectrestore(rect_data);
rectdiscard(rect_data);
rect_data = NULL;
if (rect_tracker) {
rect_tracker_free(rect_tracker);
rect_tracker = NULL;
}
}

View File

@ -56,6 +56,7 @@ typedef enum {
typedef struct ColorBar
{
JWidget widget;
JWidget tooltip_window;
int ncolor;
int refresh_timer_id;
color_t color[COLORBAR_MAX_COLORS];
@ -63,13 +64,17 @@ typedef struct ColorBar
color_t bgcolor;
hotcolor_t hot;
hotcolor_t hot_editing;
JWidget tooltip_window;
/* drag & drop colors */
hotcolor_t hot_drag;
hotcolor_t hot_drop;
} ColorBar;
static ColorBar *colorbar_data(JWidget colorbar);
static bool colorbar_msg_proc(JWidget widget, JMessage msg);
static color_t colorbar_get_hot_color(JWidget widget);
static color_t colorbar_get_hotcolor(JWidget widget, hotcolor_t hot);
static void colorbar_set_hotcolor(JWidget widget, hotcolor_t hot, color_t color);
static void colorbar_open_tooltip(JWidget widget, int x1, int x2, int y1, int y2,
color_t color, hotcolor_t hot);
static void colorbar_close_tooltip(JWidget widget);
@ -85,13 +90,15 @@ JWidget colorbar_new(int align)
ColorBar *colorbar = jnew0(ColorBar, 1);
colorbar->widget = widget;
colorbar->tooltip_window = NULL;
colorbar->ncolor = 16;
colorbar->refresh_timer_id = jmanager_add_timer(widget, 250);
colorbar->fgcolor = color_mask();
colorbar->bgcolor = color_mask();
colorbar->hot = HOTCOLOR_NONE;
colorbar->hot_editing = HOTCOLOR_NONE;
colorbar->tooltip_window = NULL;
colorbar->hot_drag = HOTCOLOR_NONE;
colorbar->hot_drop = HOTCOLOR_NONE;
jwidget_add_hook(widget, colorbar_type(), colorbar_msg_proc, colorbar);
jwidget_focusrest(widget, TRUE);
@ -297,7 +304,9 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
c == beg, c == beg,
c == end, c == end, imgtype, colorbar->color[c],
(c == colorbar->hot ||
c == colorbar->hot_editing));
c == colorbar->hot_editing),
(colorbar->hot_drag == c &&
colorbar->hot_drag != colorbar->hot_drop));
}
/* draw foreground color */
@ -306,7 +315,9 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
draw_color_button(doublebuffer, x1, v1, x2, v2, 1, 1, 0, 0,
imgtype, colorbar->fgcolor,
(colorbar->hot == HOTCOLOR_FGCOLOR ||
colorbar->hot_editing == HOTCOLOR_FGCOLOR));
colorbar->hot_editing == HOTCOLOR_FGCOLOR),
(colorbar->hot_drag == HOTCOLOR_FGCOLOR &&
colorbar->hot_drag != colorbar->hot_drop));
/* draw background color */
v1 = y2-4-FGBGSIZE+1;
@ -314,7 +325,9 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
draw_color_button(doublebuffer, x1, v1, x2, v2, 0, 0, 1, 1,
imgtype, colorbar->bgcolor,
(colorbar->hot == HOTCOLOR_BGCOLOR ||
colorbar->hot_editing == HOTCOLOR_BGCOLOR));
colorbar->hot_editing == HOTCOLOR_BGCOLOR),
(colorbar->hot_drag == HOTCOLOR_BGCOLOR &&
colorbar->hot_drag != colorbar->hot_drop));
blit(doublebuffer, ji_screen, 0, 0,
msg->draw.rect.x1,
@ -328,6 +341,9 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
case JM_BUTTONPRESSED:
jwidget_capture_mouse(widget);
colorbar->hot_drag = colorbar->hot;
colorbar->hot_drop = colorbar->hot;
case JM_MOUSEENTER:
case JM_MOTION: {
int x1, y1, x2, y2, v1, v2;
@ -381,6 +397,10 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
hot_v2 = v2;
}
/* drop target */
if (colorbar->hot_drag != HOTCOLOR_NONE)
colorbar->hot_drop = colorbar->hot;
/* redraw 'hot' color */
if (colorbar->hot != old_hot) {
jwidget_dirty(widget);
@ -388,8 +408,10 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
/* close the old tooltip window to edit the 'old_hot' color slot */
colorbar_close_tooltip(widget);
if (colorbar->hot != HOTCOLOR_NONE) {
color_t color = colorbar_get_hot_color(widget);
/* open the new hot-color to be edited */
if ((colorbar->hot != HOTCOLOR_NONE) &&
(colorbar->hot_drag == colorbar->hot_drop)) {
color_t color = colorbar_get_hotcolor(widget, colorbar->hot);
update_status_bar(color, 0);
@ -399,20 +421,6 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
}
}
/* if the widget has the capture, we should replace the
selected-color with the hot-color */
if (jwidget_has_capture(widget) &&
colorbar->hot != HOTCOLOR_NONE) {
color_t color = colorbar_get_hot_color(widget);
if (msg->mouse.left) {
colorbar_set_fg_color(widget, color);
}
if (msg->mouse.right) {
colorbar_set_bg_color(widget, color);
}
}
return TRUE;
}
@ -424,12 +432,39 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
break;
case JM_BUTTONRELEASED:
if (jwidget_has_capture(widget))
if (jwidget_has_capture(widget)) {
/* drag and drop a color */
if (colorbar->hot_drag != colorbar->hot_drop) {
color_t color = colorbar_get_hotcolor(widget, colorbar->hot_drag);
colorbar_set_hotcolor(widget, colorbar->hot_drop, color);
jwidget_dirty(widget);
}
/* pick the color */
else if (colorbar->hot != HOTCOLOR_NONE) {
color_t color = colorbar_get_hotcolor(widget, colorbar->hot);
if (msg->mouse.left) {
colorbar_set_fg_color(widget, color);
}
if (msg->mouse.right) {
colorbar_set_bg_color(widget, color);
}
}
colorbar->hot_drag = HOTCOLOR_NONE;
colorbar->hot_drop = HOTCOLOR_NONE;
jwidget_release_mouse(widget);
}
break;
case JM_SETCURSOR:
if (colorbar->hot != HOTCOLOR_NONE) {
if (colorbar->hot_drag != HOTCOLOR_NONE &&
colorbar->hot_drag != colorbar->hot_drop) {
jmouse_set_cursor(JI_CURSOR_MOVE);
return TRUE;
}
else if (colorbar->hot != HOTCOLOR_NONE) {
jmouse_set_cursor(JI_CURSOR_EYEDROPPER);
return TRUE;
}
@ -454,18 +489,58 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
return FALSE;
}
static color_t colorbar_get_hot_color(JWidget widget)
static color_t colorbar_get_hotcolor(JWidget widget, hotcolor_t hot)
{
ColorBar *colorbar = colorbar_data(widget);
switch (colorbar->hot) {
switch (hot) {
case HOTCOLOR_NONE: return color_mask();
case HOTCOLOR_FGCOLOR: return colorbar->fgcolor;
case HOTCOLOR_BGCOLOR: return colorbar->bgcolor;
default:
assert(colorbar->hot >= 0 &&
colorbar->hot < colorbar->ncolor);
return colorbar->color[colorbar->hot];
assert(hot >= 0 && hot < colorbar->ncolor);
return colorbar->color[hot];
}
}
static void colorbar_set_hotcolor(JWidget widget, hotcolor_t hot, color_t color)
{
ColorBar *colorbar = colorbar_data(widget);
switch (hot) {
case HOTCOLOR_NONE:
assert(FALSE);
break;
case HOTCOLOR_FGCOLOR:
colorbar->fgcolor = color;
break;
case HOTCOLOR_BGCOLOR:
colorbar->bgcolor = color;
break;
default:
assert(hot >= 0 && hot < colorbar->ncolor);
colorbar->color[hot] = color;
if (hot == 0 || hot == colorbar->ncolor-1) {
int imgtype = app_get_current_image_type();
color_t c1 = colorbar->color[0];
color_t c2 = colorbar->color[colorbar->ncolor-1];
int r1 = color_get_red(imgtype, c1);
int g1 = color_get_green(imgtype, c1);
int b1 = color_get_blue(imgtype, c1);
int r2 = color_get_red(imgtype, c2);
int g2 = color_get_green(imgtype, c2);
int b2 = color_get_blue(imgtype, c2);
int c, r, g, b;
for (c=1; c<colorbar->ncolor-1; ++c) {
r = r1 + (r2-r1) * c / colorbar->ncolor;
g = g1 + (g2-g1) * c / colorbar->ncolor;
b = b1 + (b2-b1) * c / colorbar->ncolor;
colorbar->color[c] = color_rgb(r, g, b);
}
}
break;
}
}
@ -641,43 +716,7 @@ static bool tooltip_window_msg_proc(JWidget widget, JMessage msg)
colorbar->color[j++] = color_index(i);
}
else {
switch (colorbar->hot_editing) {
case HOTCOLOR_NONE:
/* assert(FALSE); */
break;
case HOTCOLOR_FGCOLOR:
colorbar->fgcolor = color;
break;
case HOTCOLOR_BGCOLOR:
colorbar->bgcolor = color;
break;
default:
assert(colorbar->hot_editing >= 0 &&
colorbar->hot_editing < colorbar->ncolor);
colorbar->color[colorbar->hot_editing] = color;
if (colorbar->hot_editing == 0 ||
colorbar->hot_editing == colorbar->ncolor-1) {
int imgtype = app_get_current_image_type();
color_t c1 = colorbar->color[0];
color_t c2 = colorbar->color[colorbar->ncolor-1];
int r1 = color_get_red(imgtype, c1);
int g1 = color_get_green(imgtype, c1);
int b1 = color_get_blue(imgtype, c1);
int r2 = color_get_red(imgtype, c2);
int g2 = color_get_green(imgtype, c2);
int b2 = color_get_blue(imgtype, c2);
int c, r, g, b;
for (c=1; c<colorbar->ncolor-1; ++c) {
r = r1 + (r2-r1) * c / colorbar->ncolor;
g = g1 + (g2-g1) * c / colorbar->ncolor;
b = b1 + (b2-b1) * c / colorbar->ncolor;
colorbar->color[c] = color_rgb(r, g, b);
}
}
break;
}
colorbar_set_hotcolor(colorbar_widget, colorbar->hot_editing, color);
}
/* ONLY FOR TRUE-COLOR GRAPHICS MODE: if the palette is

View File

@ -226,7 +226,8 @@ static void colorbutton_draw(JWidget widget)
1, 1, 1, 1,
colorbutton->imgtype,
colorbutton->color,
jwidget_has_mouse(widget));
jwidget_has_mouse(widget),
FALSE);
/* draw text */
color_to_formalstring(colorbutton->imgtype,

View File

@ -56,9 +56,6 @@ typedef struct Editor
int mask_timer_id;
int offset_count;
/* to save the area that overlap the layer-bound */
void *rect_data;
/* region that must be updated */
JRegion refresh_region;
} Editor;

View File

@ -963,12 +963,6 @@ static bool editor_msg_proc(JWidget widget, JMessage msg)
/* draw the sprite boundary */
rect(ji_screen, x1-1, y1-1, x2+1, y2+1, makecol(0, 0, 0));
if (editor->rect_data) {
/* destroy the layer-bound information */
rectdiscard(editor->rect_data);
editor->rect_data = NULL;
}
/* draw the grid */
if (get_view_grid())
editor_draw_grid(widget);