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.
This commit is contained in:
Matt Ebb
2010-04-04 00:21:37 +00:00
parent 069e955a1d
commit 4021db8af8
7 changed files with 185 additions and 92 deletions

View File

@@ -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);

View File

@@ -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 ********************/

View File

@@ -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);

View File

@@ -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 ************************ */

View File

@@ -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);
}
}

View File

@@ -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 */

View File

@@ -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