Merge branch 'master' into blender2.8
[blender.git] / source / blender / windowmanager / intern / wm_operators.c
index 77dbecec9f04bc81e0fc6d23508959641bc5985c..a5b64c051562c5fb5292b9572702d04e74b7624b 100644 (file)
 #include "wm_event_system.h"
 #include "wm_event_types.h"
 #include "wm_files.h"
-#include "wm_subwindow.h"
 #include "wm_window.h"
 
 static GHash *global_ops_hash = NULL;
@@ -2298,792 +2297,6 @@ void WM_paint_cursor_end(wmWindowManager *wm, void *handle)
        }
 }
 
-/* ************ window gesture operator-callback definitions ************** */
-/*
- * These are default callbacks for use in operators requiring gesture input
- */
-
-static void gesture_modal_state_to_operator(wmOperator *op, int modal_state)
-{
-       PropertyRNA *prop;
-
-       switch (modal_state) {
-               case GESTURE_MODAL_SELECT:
-               case GESTURE_MODAL_DESELECT:
-                       if ((prop = RNA_struct_find_property(op->ptr, "deselect"))) {
-                               RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_DESELECT));
-                       }
-                       break;
-               case GESTURE_MODAL_IN:
-               case GESTURE_MODAL_OUT:
-                       if ((prop = RNA_struct_find_property(op->ptr, "zoom_out"))) {
-                               RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_OUT));
-                       }
-                       break;
-       }
-}
-
-static int gesture_modal_state_from_operator(wmOperator *op)
-{
-       PropertyRNA *prop;
-
-       if ((prop = RNA_struct_find_property(op->ptr, "deselect"))) {
-               if (RNA_property_is_set(op->ptr, prop)) {
-                       return RNA_property_boolean_get(op->ptr, prop) ? GESTURE_MODAL_DESELECT : GESTURE_MODAL_SELECT;
-               }
-       }
-       if ((prop = RNA_struct_find_property(op->ptr, "zoom_out"))) {
-               if (RNA_property_is_set(op->ptr, prop)) {
-                       return RNA_property_boolean_get(op->ptr, prop) ? GESTURE_MODAL_OUT : GESTURE_MODAL_IN;
-               }
-       }
-       return GESTURE_MODAL_NOP;
-}
-
-/* **************** Border gesture *************** */
-
-/**
- * Border gesture has two types:
- * -# #WM_GESTURE_CROSS_RECT: starts a cross, on mouse click it changes to border.
- * -# #WM_GESTURE_RECT: starts immediate as a border, on mouse click or release it ends.
- *
- * It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
- */
-
-static bool gesture_border_apply_rect(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, "xmin", min_ii(rect->xmin, rect->xmax));
-       RNA_int_set(op->ptr, "ymin", min_ii(rect->ymin, rect->ymax));
-       RNA_int_set(op->ptr, "xmax", max_ii(rect->xmin, rect->xmax));
-       RNA_int_set(op->ptr, "ymax", max_ii(rect->ymin, rect->ymax));
-
-       return 1;
-}
-
-static bool gesture_border_apply(bContext *C, wmOperator *op)
-{
-       wmGesture *gesture = op->customdata;
-
-       int retval;
-
-       if (!gesture_border_apply_rect(op)) {
-               return 0;
-       }
-
-       gesture_modal_state_to_operator(op, gesture->modal_state);
-
-       retval = op->type->exec(C, op);
-       OPERATOR_RETVAL_CHECK(retval);
-
-       return 1;
-}
-
-static void wm_gesture_end(bContext *C, wmOperator *op)
-{
-       wmGesture *gesture = op->customdata;
-       
-       WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
-       op->customdata = NULL;
-
-       ED_area_tag_redraw(CTX_wm_area(C));
-       
-       if (RNA_struct_find_property(op->ptr, "cursor")) {
-               WM_cursor_modal_restore(CTX_wm_window(C));
-       }
-}
-
-int WM_gesture_border_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       int modal_state = gesture_modal_state_from_operator(op);
-
-       if (ISTWEAK(event->type) || (modal_state != GESTURE_MODAL_NOP)) {
-               op->customdata = WM_gesture_new(C, event, WM_GESTURE_RECT);
-       }
-       else {
-               op->customdata = WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
-       }
-
-       /* Starting with the mode starts immediately, like having 'wait_for_input' disabled (some tools use this). */
-       if (modal_state == GESTURE_MODAL_NOP) {
-               wmGesture *gesture = op->customdata;
-               gesture->wait_for_input = true;
-       }
-       else {
-               wmGesture *gesture = op->customdata;
-               gesture->modal_state = modal_state;
-       }
-
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-
-       wm_gesture_tag_redraw(C);
-
-       return OPERATOR_RUNNING_MODAL;
-}
-
-int WM_gesture_border_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       int sx, sy;
-       
-       if (event->type == MOUSEMOVE) {
-               wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-
-               if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
-                       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;
-               }
-               gesture_border_apply_rect(op);
-
-               wm_gesture_tag_redraw(C);
-       }
-       else if (event->type == EVT_MODAL_MAP) {
-               switch (event->val) {
-                       case GESTURE_MODAL_BEGIN:
-                               if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
-                                       gesture->is_active = true;
-                                       wm_gesture_tag_redraw(C);
-                               }
-                               break;
-                       case GESTURE_MODAL_SELECT:
-                       case GESTURE_MODAL_DESELECT:
-                       case GESTURE_MODAL_IN:
-                       case GESTURE_MODAL_OUT:
-                               if (gesture->wait_for_input) {
-                                       gesture->modal_state = event->val;
-                               }
-                               if (gesture_border_apply(C, op)) {
-                                       wm_gesture_end(C, op);
-                                       return OPERATOR_FINISHED;
-                               }
-                               wm_gesture_end(C, op);
-                               return OPERATOR_CANCELLED;
-
-                       case GESTURE_MODAL_CANCEL:
-                               wm_gesture_end(C, op);
-                               return OPERATOR_CANCELLED;
-               }
-
-       }
-#ifdef WITH_INPUT_NDOF
-       else if (event->type == NDOF_MOTION) {
-               return OPERATOR_PASS_THROUGH;
-       }
-#endif
-//     /* Allow view navigation??? */
-//     else {
-//             return OPERATOR_PASS_THROUGH;
-//     }
-
-       return OPERATOR_RUNNING_MODAL;
-}
-
-void WM_gesture_border_cancel(bContext *C, wmOperator *op)
-{
-       wm_gesture_end(C, op);
-}
-
-/* **************** circle gesture *************** */
-/* works now only for selection or modal paint stuff, calls exec while hold mouse, exit on release */
-
-static void gesture_circle_apply(bContext *C, wmOperator *op);
-
-int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       int modal_state = gesture_modal_state_from_operator(op);
-
-       op->customdata = WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       
-       /* Default or previously stored value. */
-       rect->xmax = RNA_int_get(op->ptr, "radius");
-
-       /* Starting with the mode starts immediately, like having 'wait_for_input' disabled (some tools use this). */
-       if (modal_state == GESTURE_MODAL_NOP) {
-               gesture->wait_for_input = true;
-       }
-       else {
-               gesture->is_active = true;
-               gesture->modal_state = modal_state;
-               gesture_circle_apply(C, op);
-       }
-
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       return OPERATOR_RUNNING_MODAL;
-}
-
-static void gesture_circle_apply(bContext *C, wmOperator *op)
-{
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-
-       if (gesture->modal_state == GESTURE_MODAL_NOP) {
-               return;
-       }
-
-       /* operator arguments and storage. */
-       RNA_int_set(op->ptr, "x", rect->xmin);
-       RNA_int_set(op->ptr, "y", rect->ymin);
-       RNA_int_set(op->ptr, "radius", rect->xmax);
-
-       gesture_modal_state_to_operator(op, gesture->modal_state);
-
-       if (op->type->exec) {
-               int retval;
-               retval = op->type->exec(C, op);
-               OPERATOR_RETVAL_CHECK(retval);
-       }
-}
-
-int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       int sx, sy;
-
-       if (event->type == MOUSEMOVE) {
-               wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-
-               rect->xmin = event->x - sx;
-               rect->ymin = event->y - sy;
-
-               wm_gesture_tag_redraw(C);
-
-               if (gesture->is_active) {
-                       gesture_circle_apply(C, op);
-               }
-       }
-       else if (event->type == EVT_MODAL_MAP) {
-               bool is_circle_size = false;
-               bool is_finished = false;
-               float fac;
-               
-               switch (event->val) {
-                       case GESTURE_MODAL_CIRCLE_SIZE:
-                               fac = 0.3f * (event->y - event->prevy);
-                               if (fac > 0)
-                                       rect->xmax += ceil(fac);
-                               else
-                                       rect->xmax += floor(fac);
-                               if (rect->xmax < 1) rect->xmax = 1;
-                               is_circle_size = true;
-                               break;
-                       case GESTURE_MODAL_CIRCLE_ADD:
-                               rect->xmax += 2 + rect->xmax / 10;
-                               is_circle_size = true;
-                               break;
-                       case GESTURE_MODAL_CIRCLE_SUB:
-                               rect->xmax -= 2 + rect->xmax / 10;
-                               if (rect->xmax < 1) rect->xmax = 1;
-                               is_circle_size = true;
-                               break;
-                       case GESTURE_MODAL_SELECT:
-                       case GESTURE_MODAL_DESELECT:
-                       case GESTURE_MODAL_NOP:
-                       {
-                               if (gesture->wait_for_input) {
-                                       gesture->modal_state = event->val;
-                               }
-                               if (event->val == GESTURE_MODAL_NOP) {
-                                       /* Single action, click-drag & release to exit. */
-                                       if (gesture->wait_for_input == false) {
-                                               is_finished = true;
-                                       }
-                               }
-                               else {
-                                       /* apply first click */
-                                       gesture_circle_apply(C, op);
-                                       gesture->is_active = true;
-                                       wm_gesture_tag_redraw(C);
-                               }
-                               break;
-                       }
-                       case GESTURE_MODAL_CANCEL:
-                       case GESTURE_MODAL_CONFIRM:
-                               is_finished = true;
-               }
-
-               if (is_finished) {
-                       wm_gesture_end(C, op);
-                       return OPERATOR_FINISHED; /* use finish or we don't get an undo */
-               }
-
-               if (is_circle_size) {
-                       wm_gesture_tag_redraw(C);
-
-                       /* So next use remembers last seen size, even if we didn't apply it. */
-                       RNA_int_set(op->ptr, "radius", rect->xmax);
-               }
-       }
-#ifdef WITH_INPUT_NDOF
-       else if (event->type == NDOF_MOTION) {
-               return OPERATOR_PASS_THROUGH;
-       }
-#endif
-       /* Allow view navigation??? */
-       /* note, this gives issues: 1) other modal ops run on top (border select), 2) middlemouse is used now 3) tablet/trackpad? */
-//     else {
-//             return OPERATOR_PASS_THROUGH;
-//     }
-
-       return OPERATOR_RUNNING_MODAL;
-}
-
-void WM_gesture_circle_cancel(bContext *C, wmOperator *op)
-{
-       wm_gesture_end(C, op);
-}
-
-#if 0
-/* template to copy from */
-void WM_OT_circle_gesture(wmOperatorType *ot)
-{
-       ot->name = "Circle Gesture";
-       ot->idname = "WM_OT_circle_gesture";
-       ot->description = "Enter rotate mode with a circular gesture";
-       
-       ot->invoke = WM_gesture_circle_invoke;
-       ot->modal = WM_gesture_circle_modal;
-       ot->poll = WM_operator_winactive;
-
-       /* properties */
-       WM_operator_properties_gesture_circle(ot);
-
-}
-#endif
-
-/* **************** Tweak gesture *************** */
-
-static void tweak_gesture_modal(bContext *C, const wmEvent *event)
-{
-       wmWindow *window = CTX_wm_window(C);
-       wmGesture *gesture = window->tweak;
-       rcti *rect = gesture->customdata;
-       int sx, sy, val;
-       
-       switch (event->type) {
-               case MOUSEMOVE:
-               case INBETWEEN_MOUSEMOVE:
-                       
-                       wm_subwindow_origin_get(window, gesture->swinid, &sx, &sy);
-                       
-                       rect->xmax = event->x - sx;
-                       rect->ymax = event->y - sy;
-                       
-                       if ((val = wm_gesture_evaluate(gesture))) {
-                               wmEvent tevent;
-
-                               wm_event_init_from_window(window, &tevent);
-                               /* We want to get coord from start of drag, not from point where it becomes a tweak event, see T40549 */
-                               tevent.x = rect->xmin + sx;
-                               tevent.y = rect->ymin + sy;
-                               if (gesture->event_type == LEFTMOUSE)
-                                       tevent.type = EVT_TWEAK_L;
-                               else if (gesture->event_type == RIGHTMOUSE)
-                                       tevent.type = EVT_TWEAK_R;
-                               else
-                                       tevent.type = EVT_TWEAK_M;
-                               tevent.val = val;
-                               /* mouse coords! */
-
-                               /* important we add immediately after this event, so future mouse releases
-                                * (which may be in the queue already), are handled in order, see T44740 */
-                               wm_event_add_ex(window, &tevent, event);
-                               
-                               WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
-                       }
-                       
-                       break;
-                       
-               case LEFTMOUSE:
-               case RIGHTMOUSE:
-               case MIDDLEMOUSE:
-                       if (gesture->event_type == event->type) {
-                               WM_gesture_end(C, gesture);
-
-                               /* when tweak fails we should give the other keymap entries a chance */
-
-                               /* XXX, assigning to readonly, BAD JUJU! */
-                               ((wmEvent *)event)->val = KM_RELEASE;
-                       }
-                       break;
-               default:
-                       if (!ISTIMER(event->type) && event->type != EVENT_NONE) {
-                               WM_gesture_end(C, gesture);
-                       }
-                       break;
-       }
-}
-
-/* standard tweak, called after window handlers passed on event */
-void wm_tweakevent_test(bContext *C, const wmEvent *event, int action)
-{
-       wmWindow *win = CTX_wm_window(C);
-       
-       if (win->tweak == NULL) {
-               if (CTX_wm_region(C)) {
-                       if (event->val == KM_PRESS) {
-                               if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) {
-                                       win->tweak = WM_gesture_new(C, event, WM_GESTURE_TWEAK);
-                               }
-                       }
-               }
-       }
-       else {
-               /* no tweaks if event was handled */
-               if ((action & WM_HANDLER_BREAK)) {
-                       WM_gesture_end(C, win->tweak);
-               }
-               else
-                       tweak_gesture_modal(C, event);
-       }
-}
-
-/* *********************** lasso gesture ****************** */
-
-int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       PropertyRNA *prop;
-
-       op->customdata = WM_gesture_new(C, event, WM_GESTURE_LASSO);
-       
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
-               WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
-       }
-       
-       return OPERATOR_RUNNING_MODAL;
-}
-
-int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       PropertyRNA *prop;
-
-       op->customdata = WM_gesture_new(C, event, WM_GESTURE_LINES);
-       
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
-               WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
-       }
-       
-       return OPERATOR_RUNNING_MODAL;
-}
-
-
-static void gesture_lasso_apply(bContext *C, wmOperator *op)
-{
-       wmGesture *gesture = op->customdata;
-       PointerRNA itemptr;
-       float loc[2];
-       int i;
-       const short *lasso = gesture->customdata;
-       
-       /* operator storage as path. */
-
-       RNA_collection_clear(op->ptr, "path");
-       for (i = 0; i < gesture->points; i++, lasso += 2) {
-               loc[0] = lasso[0];
-               loc[1] = lasso[1];
-               RNA_collection_add(op->ptr, "path", &itemptr);
-               RNA_float_set_array(&itemptr, "loc", loc);
-       }
-       
-       wm_gesture_end(C, op);
-               
-       if (op->type->exec) {
-               int retval = op->type->exec(C, op);
-               OPERATOR_RETVAL_CHECK(retval);
-       }
-}
-
-int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       wmGesture *gesture = op->customdata;
-       int sx, sy;
-       
-       switch (event->type) {
-               case MOUSEMOVE:
-               case INBETWEEN_MOUSEMOVE:
-
-                       wm_gesture_tag_redraw(C);
-
-                       wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-
-                       if (gesture->points == gesture->points_alloc) {
-                               gesture->points_alloc *= 2;
-                               gesture->customdata = MEM_reallocN(gesture->customdata, sizeof(short[2]) * gesture->points_alloc);
-                       }
-
-                       {
-                               int x, y;
-                               short *lasso = gesture->customdata;
-
-                               lasso += (2 * gesture->points - 2);
-                               x = (event->x - sx - lasso[0]);
-                               y = (event->y - sy - lasso[1]);
-
-                               /* make a simple distance check to get a smoother lasso
-                                * add only when at least 2 pixels between this and previous location */
-                               if ((x * x + y * y) > 4) {
-                                       lasso += 2;
-                                       lasso[0] = event->x - sx;
-                                       lasso[1] = event->y - sy;
-                                       gesture->points++;
-                               }
-                       }
-                       break;
-
-               case LEFTMOUSE:
-               case MIDDLEMOUSE:
-               case RIGHTMOUSE:
-                       if (event->val == KM_RELEASE) {   /* key release */
-                               gesture_lasso_apply(C, op);
-                               return OPERATOR_FINISHED;
-                       }
-                       break;
-               case ESCKEY:
-                       wm_gesture_end(C, op);
-                       return OPERATOR_CANCELLED;
-       }
-       return OPERATOR_RUNNING_MODAL;
-}
-
-int WM_gesture_lines_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       return WM_gesture_lasso_modal(C, op, event);
-}
-
-void WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
-{
-       wm_gesture_end(C, op);
-}
-
-void WM_gesture_lines_cancel(bContext *C, wmOperator *op)
-{
-       wm_gesture_end(C, op);
-}
-
-/**
- * helper function, we may want to add options for conversion to view space
- *
- * caller must free.
- */
-const int (*WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *mcords_tot))[2]
-{
-       PropertyRNA *prop = RNA_struct_find_property(op->ptr, "path");
-       int (*mcords)[2] = NULL;
-       BLI_assert(prop != NULL);
-
-       if (prop) {
-               const int len = RNA_property_collection_length(op->ptr, prop);
-
-               if (len) {
-                       int i = 0;
-                       mcords = MEM_mallocN(sizeof(int) * 2 * len, __func__);
-
-                       RNA_PROP_BEGIN (op->ptr, itemptr, prop)
-                       {
-                               float loc[2];
-
-                               RNA_float_get_array(&itemptr, "loc", loc);
-                               mcords[i][0] = (int)loc[0];
-                               mcords[i][1] = (int)loc[1];
-                               i++;
-                       }
-                       RNA_PROP_END;
-               }
-               *mcords_tot = len;
-       }
-       else {
-               *mcords_tot = 0;
-       }
-
-       /* cast for 'const' */
-       return (const int (*)[2])mcords;
-}
-
-#if 0
-/* template to copy from */
-
-static int gesture_lasso_exec(bContext *C, wmOperator *op)
-{
-       RNA_BEGIN (op->ptr, itemptr, "path")
-       {
-               float loc[2];
-               
-               RNA_float_get_array(&itemptr, "loc", loc);
-               printf("Location: %f %f\n", loc[0], loc[1]);
-       }
-       RNA_END;
-       
-       return OPERATOR_FINISHED;
-}
-
-void WM_OT_lasso_gesture(wmOperatorType *ot)
-{
-       PropertyRNA *prop;
-       
-       ot->name = "Lasso Gesture";
-       ot->idname = "WM_OT_lasso_gesture";
-       ot->description = "Select objects within the lasso as you move the pointer";
-       
-       ot->invoke = WM_gesture_lasso_invoke;
-       ot->modal = WM_gesture_lasso_modal;
-       ot->exec = gesture_lasso_exec;
-       
-       ot->poll = WM_operator_winactive;
-       
-       prop = RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
-       RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
-}
-#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) {
-               int retval = op->type->exec(C, op);
-               OPERATOR_RETVAL_CHECK(retval);
-       }
-       
-       return 1;
-}
-
-
-int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       PropertyRNA *prop;
-
-       op->customdata = WM_gesture_new(C, event, WM_GESTURE_STRAIGHTLINE);
-       
-       if (ISTWEAK(event->type)) {
-               wmGesture *gesture = op->customdata;
-               gesture->is_active = true;
-       }
-
-       /* add modal handler */
-       WM_event_add_modal_handler(C, op);
-       
-       wm_gesture_tag_redraw(C);
-       
-       if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
-               WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
-       }
-               
-       return OPERATOR_RUNNING_MODAL;
-}
-
-int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *event)
-{
-       wmGesture *gesture = op->customdata;
-       rcti *rect = gesture->customdata;
-       int sx, sy;
-       
-       if (event->type == MOUSEMOVE) {
-               wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
-               
-               if (gesture->is_active == false) {
-                       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->is_active == false) {
-                                       gesture->is_active = true;
-                                       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;
-                               
-                       case GESTURE_MODAL_CANCEL:
-                               wm_gesture_end(C, op);
-                               return OPERATOR_CANCELLED;
-               }
-               
-       }
-
-       return OPERATOR_RUNNING_MODAL;
-}
-
-void WM_gesture_straightline_cancel(bContext *C, wmOperator *op)
-{
-       wm_gesture_end(C, op);
-}
-
-#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 ****************** */
 
 #define WM_RADIAL_CONTROL_DISPLAY_SIZE (200 * UI_DPI_FAC)