diff --git a/src/modules/gfx.c b/src/modules/gfx.c index 32004271d..746158d39 100644 --- a/src/modules/gfx.c +++ b/src/modules/gfx.c @@ -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))); + } } /************************************************************************/ diff --git a/src/modules/gfx.h b/src/modules/gfx.h index 547b5ee9a..4918853bf 100644 --- a/src/modules/gfx.h +++ b/src/modules/gfx.h @@ -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); diff --git a/src/modules/tools.c b/src/modules/tools.c index 79afbaa3d..3e0c78a89 100644 --- a/src/modules/tools.c +++ b/src/modules/tools.c @@ -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<zoom)-1; outy2 += (1<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; } } diff --git a/src/widgets/colbar.c b/src/widgets/colbar.c index 82b239069..ef77aac7b 100644 --- a/src/widgets/colbar.c +++ b/src/widgets/colbar.c @@ -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; @@ -337,7 +353,7 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg) int hot_v2 = 0; colorbar->hot = HOTCOLOR_NONE; - + get_info(widget, &beg, &end); x1 = widget->rc->x1; @@ -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; cncolor-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; cncolor-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 diff --git a/src/widgets/colbut.c b/src/widgets/colbut.c index 9dbb407ad..385e2262c 100644 --- a/src/widgets/colbut.c +++ b/src/widgets/colbut.c @@ -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, diff --git a/src/widgets/editor.h b/src/widgets/editor.h index 4a99352e1..9b213b792 100644 --- a/src/widgets/editor.h +++ b/src/widgets/editor.h @@ -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; diff --git a/src/widgets/editor/editor.c b/src/widgets/editor/editor.c index 598c55ca7..ab82def49 100644 --- a/src/widgets/editor/editor.c +++ b/src/widgets/editor/editor.c @@ -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);