From 4021db8af82bb96ecd727e1a3374367f189ce415 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Sun, 4 Apr 2010 00:21:37 +0000 Subject: Added a new 'straight line' gesture type that can be used in any operator. Use this for image editor Line Sample tool, rather than custom modal operator/ custom drawing. --- source/blender/editors/space_image/image_intern.h | 1 - source/blender/editors/space_image/image_ops.c | 103 +++---------- source/blender/windowmanager/WM_api.h | 3 + source/blender/windowmanager/WM_types.h | 2 + source/blender/windowmanager/intern/wm_gesture.c | 4 +- source/blender/windowmanager/intern/wm_operators.c | 162 ++++++++++++++++++++- source/blender/windowmanager/wm_event_types.h | 2 +- 7 files changed, 185 insertions(+), 92 deletions(-) (limited to 'source') diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 8c8a8f76710..c038f58375c 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -55,7 +55,6 @@ void IMAGE_OT_toolbox(struct wmOperatorType *ot); void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene); void draw_image_info(struct ARegion *ar, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf); void draw_image_grease_pencil(struct bContext *C, short onlyv2d); -void draw_image_line(struct ARegion *ar, int x1, int y1, int x2, int y2); /* image_ops.c */ int space_image_main_area_poll(struct bContext *C); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index a223e2481fc..c9daeb09f25 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1634,27 +1634,20 @@ void IMAGE_OT_sample(wmOperatorType *ot) } /******************** sample line operator ********************/ -typedef struct ImageSampleLineInfo { - ARegionType *art; - void *draw_handle; - int started; - int x_start, y_start, x_stop, y_stop; -} ImageSampleLineInfo; - -static void sample_line_draw(const bContext *C, ARegion *ar, void *arg_info) -{ - ImageSampleLineInfo *info= arg_info; - draw_image_line(ar, info->x_start, info->y_start, info->x_stop, info->y_stop); -} - -static void sample_line_apply(bContext *C, wmOperator *op) +static int sample_line_exec(bContext *C, wmOperator *op) { SpaceImage *sima= CTX_wm_space_image(C); - ImageSampleLineInfo *info= op->customdata; ARegion *ar= CTX_wm_region(C); + + int x_start= RNA_int_get(op->ptr, "xstart"); + int y_start= RNA_int_get(op->ptr, "ystart"); + int x_end= RNA_int_get(op->ptr, "xend"); + int y_end= RNA_int_get(op->ptr, "yend"); + void *lock; ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock); Histogram *hist= &sima->sample_line_hist; + float x1f, y1f, x2f, y2f; int x1, y1, x2, y2; int i, x, y; @@ -1663,16 +1656,16 @@ static void sample_line_apply(bContext *C, wmOperator *op) if (ibuf == NULL) { ED_space_image_release_buffer(sima, lock); - return; + return OPERATOR_CANCELLED; } /* hmmmm */ if (ibuf->channels < 3) { ED_space_image_release_buffer(sima, lock); - return; + return OPERATOR_CANCELLED; } - UI_view2d_region_to_view(&ar->v2d, info->x_start, info->y_start, &x1f, &y1f); - UI_view2d_region_to_view(&ar->v2d, info->x_stop, info->y_stop, &x2f, &y2f); + UI_view2d_region_to_view(&ar->v2d, x_start, y_start, &x1f, &y1f); + UI_view2d_region_to_view(&ar->v2d, x_end, y_end, &x2f, &y2f); x1= 0.5f+ x1f*ibuf->x; x2= 0.5f+ x2f*ibuf->x; y1= 0.5f+ y1f*ibuf->y; @@ -1707,74 +1700,20 @@ static void sample_line_apply(bContext *C, wmOperator *op) hist->ok=1; ED_space_image_release_buffer(sima, lock); -} - -static void sample_line_exit(bContext *C, wmOperator *op) -{ - ImageSampleLineInfo *info= op->customdata; - ED_region_draw_cb_exit(info->art, info->draw_handle); ED_area_tag_redraw(CTX_wm_area(C)); - MEM_freeN(info); + + return OPERATOR_FINISHED; } static int sample_line_invoke(bContext *C, wmOperator *op, wmEvent *event) { SpaceImage *sima= CTX_wm_space_image(C); - ImageSampleLineInfo *info; - + if(!ED_space_image_has_buffer(sima)) return OPERATOR_CANCELLED; - info= MEM_callocN(sizeof(ImageSampleLineInfo), "ImageSampleLineInfo"); - info->started= 0; - op->customdata= info; - - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int sample_line_modal(bContext *C, wmOperator *op, wmEvent *event) -{ - ImageSampleLineInfo *info= op->customdata; - ARegion *ar= CTX_wm_region(C); - - switch(event->type) { - case LEFTMOUSE: - if (info->started == 0) { - info->x_start = event->mval[0]; - info->y_start = event->mval[1]; - info->art= ar->type; - info->draw_handle = ED_region_draw_cb_activate(ar->type, sample_line_draw, info, REGION_DRAW_POST_PIXEL); - info->started = 1; - } else { - sample_line_apply(C, op); - sample_line_exit(C, op); - return OPERATOR_FINISHED; - } - break; - case RIGHTMOUSE: // XXX hardcoded - case ESCKEY: - sample_line_exit(C, op); - return OPERATOR_CANCELLED; - case MOUSEMOVE: - if (info->started == 1) { - info->x_stop = event->mval[0]; - info->y_stop = event->mval[1]; - ED_area_tag_redraw(CTX_wm_area(C)); - sample_line_apply(C, op); - } - break; - } - - return OPERATOR_RUNNING_MODAL; -} - -static int sample_line_cancel(bContext *C, wmOperator *op) -{ - sample_line_exit(C, op); - return OPERATOR_CANCELLED; + return WM_gesture_straightline_invoke(C, op, event); } void IMAGE_OT_sample_line(wmOperatorType *ot) @@ -1785,12 +1724,14 @@ void IMAGE_OT_sample_line(wmOperatorType *ot) /* api callbacks */ ot->invoke= sample_line_invoke; - ot->modal= sample_line_modal; - ot->cancel= sample_line_cancel; + ot->modal= WM_gesture_straightline_modal; + ot->exec= sample_line_exec; ot->poll= space_image_main_area_poll; - + /* flags */ - ot->flag= OPTYPE_BLOCKING; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT); } /******************** set curve point operator ********************/ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 343ee737c82..c005fd5828c 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -225,6 +225,7 @@ void WM_operator_properties_create_ptr(struct PointerRNA *ptr, struct wmOperato void WM_operator_properties_free(struct PointerRNA *ptr); void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type, short action); void WM_operator_properties_gesture_border(struct wmOperatorType *ot, int extend); +void WM_operator_properties_gesture_straightline(struct wmOperatorType *ot, int cursor); void WM_operator_properties_select_all(struct wmOperatorType *ot); /* MOVE THIS SOMEWHERE ELSE */ @@ -253,6 +254,8 @@ int WM_gesture_lines_invoke(struct bContext *C, struct wmOperator *op, struct int WM_gesture_lines_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); +int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); +int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); /* default operator for arearegions, generates event */ void WM_OT_tweak_gesture(struct wmOperatorType *ot); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 936b6550b0d..78b19db5fc8 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -287,6 +287,7 @@ typedef struct wmNotifier { #define WM_GESTURE_CROSS_RECT 3 #define WM_GESTURE_LASSO 4 #define WM_GESTURE_CIRCLE 5 +#define WM_GESTURE_STRAIGHTLINE 6 /* wmGesture is registered to window listbase, handled by operator callbacks */ /* tweak gesture is builtin feature */ @@ -303,6 +304,7 @@ typedef struct wmGesture { /* customdata for border is a recti */ /* customdata for circle is recti, (xmin, ymin) is center, xmax radius */ /* customdata for lasso is short array */ + /* customdata for straight line is a recti: (xmin,ymin) is start, (xmax, ymax) is end */ } wmGesture; /* ************** wmEvent ************************ */ diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index fd7ae142cbd..e87d2d79c39 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -70,7 +70,7 @@ wmGesture *WM_gesture_new(bContext *C, wmEvent *event, int type) wm_subwindow_getorigin(window, gesture->swinid, &sx, &sy); - if( ELEM4(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK, WM_GESTURE_CIRCLE)) { + if( ELEM5(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK, WM_GESTURE_CIRCLE, WM_GESTURE_STRAIGHTLINE)) { rcti *rect= MEM_callocN(sizeof(rcti), "gesture rect new"); gesture->customdata= rect; @@ -335,6 +335,8 @@ void wm_gesture_draw(wmWindow *win) wm_gesture_draw_lasso(win, gt); else if(gt->type==WM_GESTURE_LASSO) wm_gesture_draw_lasso(win, gt); + else if(gt->type==WM_GESTURE_STRAIGHTLINE) + wm_gesture_draw_line(win, gt); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 535dd5f1a62..e9a57a431dc 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -848,6 +848,17 @@ void WM_operator_properties_gesture_border(wmOperatorType *ot, int extend) RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); } +void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor) +{ + RNA_def_int(ot->srna, "xstart", 0, INT_MIN, INT_MAX, "X Start", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "xend", 0, INT_MIN, INT_MAX, "X End", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "ystart", 0, INT_MIN, INT_MAX, "Y Start", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "yend", 0, INT_MIN, INT_MAX, "Y End", "", INT_MIN, INT_MAX); + + if(cursor) + RNA_def_int(ot->srna, "cursor", cursor, 0, INT_MAX, "Cursor", "Mouse cursor style to use during the modal operator", 0, INT_MAX); +} + /* op->poll */ int WM_operator_winactive(bContext *C) @@ -2062,7 +2073,7 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event) } else if (event->type==EVT_MODAL_MAP) { switch (event->val) { - case GESTURE_MODAL_BORDER_BEGIN: + case GESTURE_MODAL_BEGIN: if(gesture->type==WM_GESTURE_CROSS_RECT && gesture->mode==0) { gesture->mode= 1; wm_gesture_tag_redraw(C); @@ -2429,6 +2440,112 @@ void WM_OT_lasso_gesture(wmOperatorType *ot) } #endif +/* *********************** straight line gesture ****************** */ + +static int straightline_apply(bContext *C, wmOperator *op) +{ + wmGesture *gesture= op->customdata; + rcti *rect= gesture->customdata; + + if(rect->xmin==rect->xmax && rect->ymin==rect->ymax) + return 0; + + /* operator arguments and storage. */ + RNA_int_set(op->ptr, "xstart", rect->xmin); + RNA_int_set(op->ptr, "ystart", rect->ymin); + RNA_int_set(op->ptr, "xend", rect->xmax); + RNA_int_set(op->ptr, "yend", rect->ymax); + + if(op->type->exec) + op->type->exec(C, op); + + return 1; +} + + +int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + op->customdata= WM_gesture_new(C, event, WM_GESTURE_STRAIGHTLINE); + + /* add modal handler */ + WM_event_add_modal_handler(C, op); + + wm_gesture_tag_redraw(C); + + if( RNA_struct_find_property(op->ptr, "cursor") ) + WM_cursor_modal(CTX_wm_window(C), RNA_int_get(op->ptr, "cursor")); + + return OPERATOR_RUNNING_MODAL; +} + +int WM_gesture_straightline_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + wmGesture *gesture= op->customdata; + rcti *rect= gesture->customdata; + int sx, sy; + + if(event->type== MOUSEMOVE) { + wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy); + + if(gesture->mode==0) { + rect->xmin= rect->xmax= event->x - sx; + rect->ymin= rect->ymax= event->y - sy; + } + else { + rect->xmax= event->x - sx; + rect->ymax= event->y - sy; + straightline_apply(C, op); + } + + wm_gesture_tag_redraw(C); + } + else if (event->type==EVT_MODAL_MAP) { + switch (event->val) { + case GESTURE_MODAL_BEGIN: + if(gesture->mode==0) { + gesture->mode= 1; + wm_gesture_tag_redraw(C); + } + break; + case GESTURE_MODAL_SELECT: + if(straightline_apply(C, op)) { + wm_gesture_end(C, op); + return OPERATOR_FINISHED; + } + wm_gesture_end(C, op); + return OPERATOR_CANCELLED; + break; + + case GESTURE_MODAL_CANCEL: + wm_gesture_end(C, op); + return OPERATOR_CANCELLED; + } + + } + + return OPERATOR_RUNNING_MODAL; +} + +#if 0 +/* template to copy from */ +void WM_OT_straightline_gesture(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name= "Straight Line Gesture"; + ot->idname= "WM_OT_straightline_gesture"; + ot->description="Draw a straight line as you move the pointer"; + + ot->invoke= WM_gesture_straightline_invoke; + ot->modal= WM_gesture_straightline_modal; + ot->exec= gesture_straightline_exec; + + ot->poll= WM_operator_winactive; + + WM_operator_properties_gesture_straightline(ot, 0); +} +#endif + /* *********************** radial control ****************** */ const int WM_RADIAL_CONTROL_DISPLAY_SIZE = 200; @@ -2898,6 +3015,34 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) } +/* straight line modal operators */ +static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf) +{ + static EnumPropertyItem modal_items[] = { + {GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""}, + {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Gesture Straight Line"); + + /* this function is called for each spacetype, only needs to add map once */ + if(keymap) return; + + keymap= WM_modalkeymap_add(keyconf, "Gesture Straight Line", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL); + + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_SELECT); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "IMAGE_OT_sample_line"); +} + + /* borderselect-like modal operators */ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) { @@ -2905,7 +3050,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, {GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""}, {GESTURE_MODAL_DESELECT,"DESELECT", 0, "DeSelect", ""}, - {GESTURE_MODAL_BORDER_BEGIN, "BEGIN", 0, "Begin", ""}, + {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, {0, NULL, 0, NULL, NULL}}; wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Gesture Border"); @@ -2919,14 +3064,14 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL); - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BORDER_BEGIN); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_SELECT); #if 0 // Durian guys like this - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BORDER_BEGIN); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_DESELECT); #else - WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BORDER_BEGIN); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_DESELECT); #endif @@ -2957,7 +3102,7 @@ static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, {GESTURE_MODAL_IN, "IN", 0, "In", ""}, {GESTURE_MODAL_OUT, "OUT", 0, "Out", ""}, - {GESTURE_MODAL_BORDER_BEGIN, "BEGIN", 0, "Begin", ""}, + {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, {0, NULL, 0, NULL, NULL}}; wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Gesture Zoom Border"); @@ -2971,10 +3116,10 @@ static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL); - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BORDER_BEGIN); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_IN); - WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BORDER_BEGIN); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_OUT); /* assign map to operators */ @@ -3070,6 +3215,7 @@ void wm_window_keymap(wmKeyConfig *keyconf) gesture_circle_modal_keymap(keyconf); gesture_border_modal_keymap(keyconf); gesture_zoom_border_modal_keymap(keyconf); + gesture_straightline_modal_keymap(keyconf); } /* Generic itemf's for operators that take library args */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 59dddbaea5b..47bb11f4dd7 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -281,7 +281,7 @@ #define GESTURE_MODAL_CIRCLE_ADD 6 /* circle sel: larger brush */ #define GESTURE_MODAL_CIRCLE_SUB 7 /* circle sel: smaller brush */ -#define GESTURE_MODAL_BORDER_BEGIN 8 /* border select, activate, use release to detect which button */ +#define GESTURE_MODAL_BEGIN 8 /* border select/straight line, activate, use release to detect which button */ #define GESTURE_MODAL_IN 9 #define GESTURE_MODAL_OUT 10 -- cgit v1.2.3