Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_operators.c')
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c174
1 files changed, 130 insertions, 44 deletions
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 2daac07b956..012b1e21d9f 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2303,6 +2303,43 @@ void WM_paint_cursor_end(wmWindowManager *wm, void *handle)
* 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 *************** */
/**
@@ -2313,7 +2350,7 @@ void WM_paint_cursor_end(wmWindowManager *wm, void *handle)
* It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
*/
-static int border_apply_rect(wmOperator *op)
+static bool gesture_border_apply_rect(wmOperator *op)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@@ -2331,20 +2368,18 @@ static int border_apply_rect(wmOperator *op)
return 1;
}
-static int border_apply(bContext *C, wmOperator *op, int gesture_mode)
+static bool gesture_border_apply(bContext *C, wmOperator *op)
{
- PropertyRNA *prop;
+ wmGesture *gesture = op->customdata;
int retval;
- if (!border_apply_rect(op))
+ if (!gesture_border_apply_rect(op)) {
return 0;
-
- /* XXX weak; border should be configured for this without reading event types */
- if ((prop = RNA_struct_find_property(op->ptr, "gesture_mode"))) {
- RNA_property_int_set(op->ptr, prop, gesture_mode);
}
+ gesture_modal_state_to_operator(op, gesture->modal_state);
+
retval = op->type->exec(C, op);
OPERATOR_RETVAL_CHECK(retval);
@@ -2365,22 +2400,36 @@ static void wm_gesture_end(bContext *C, wmOperator *op)
}
}
-int WM_border_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+int WM_gesture_border_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (ISTWEAK(event->type))
+ 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
+ }
+ 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_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
+int WM_gesture_border_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@@ -2397,7 +2446,7 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
rect->xmax = event->x - sx;
rect->ymax = event->y - sy;
}
- border_apply_rect(op);
+ gesture_border_apply_rect(op);
wm_gesture_tag_redraw(C);
}
@@ -2413,7 +2462,10 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
case GESTURE_MODAL_DESELECT:
case GESTURE_MODAL_IN:
case GESTURE_MODAL_OUT:
- if (border_apply(C, op, event->val)) {
+ if (gesture->wait_for_input) {
+ gesture->modal_state = event->val;
+ }
+ if (gesture_border_apply(C, op)) {
wm_gesture_end(C, op);
return OPERATOR_FINISHED;
}
@@ -2439,7 +2491,7 @@ int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-void WM_border_select_cancel(bContext *C, wmOperator *op)
+void WM_gesture_border_cancel(bContext *C, wmOperator *op)
{
wm_gesture_end(C, op);
}
@@ -2447,14 +2499,29 @@ void WM_border_select_cancel(bContext *C, wmOperator *op)
/* **************** circle gesture *************** */
/* works now only for selection or modal paint stuff, calls exec while hold mouse, exit on release */
-#ifdef GESTURE_MEMORY
-int circle_select_size = 25; /* XXX - need some operator memory thing! */
-#endif
+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);
@@ -2467,23 +2534,23 @@ static void gesture_circle_apply(bContext *C, wmOperator *op)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
-
- if (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_NOP)
+
+ 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);
}
-#ifdef GESTURE_MEMORY
- circle_select_size = rect->xmax;
-#endif
}
int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
@@ -2505,6 +2572,8 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (event->type == EVT_MODAL_MAP) {
+ bool is_circle_size = false;
+ bool is_finished = false;
float fac;
switch (event->val) {
@@ -2515,35 +2584,53 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
else
rect->xmax += floor(fac);
if (rect->xmax < 1) rect->xmax = 1;
- wm_gesture_tag_redraw(C);
+ is_circle_size = true;
break;
case GESTURE_MODAL_CIRCLE_ADD:
rect->xmax += 2 + rect->xmax / 10;
- wm_gesture_tag_redraw(C);
+ is_circle_size = true;
break;
case GESTURE_MODAL_CIRCLE_SUB:
rect->xmax -= 2 + rect->xmax / 10;
if (rect->xmax < 1) rect->xmax = 1;
- wm_gesture_tag_redraw(C);
+ is_circle_size = true;
break;
case GESTURE_MODAL_SELECT:
case GESTURE_MODAL_DESELECT:
case GESTURE_MODAL_NOP:
- if (RNA_struct_find_property(op->ptr, "gesture_mode"))
- RNA_int_set(op->ptr, "gesture_mode", event->val);
-
- if (event->val != 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:
- wm_gesture_end(C, op);
- return OPERATOR_FINISHED; /* use finish or we don't get an undo */
+ 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
@@ -2575,12 +2662,10 @@ void WM_OT_circle_gesture(wmOperatorType *ot)
ot->invoke = WM_gesture_circle_invoke;
ot->modal = WM_gesture_circle_modal;
-
ot->poll = WM_operator_winactive;
-
- RNA_def_property(ot->srna, "x", PROP_INT, PROP_NONE);
- RNA_def_property(ot->srna, "y", PROP_INT, PROP_NONE);
- RNA_def_property(ot->srna, "radius", PROP_INT, PROP_NONE);
+
+ /* properties */
+ WM_operator_properties_gesture_circle(ot);
}
#endif
@@ -4353,14 +4438,15 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_SELECT);
+ /* Note: use 'KM_ANY' for release, so the circle exits on any mouse release,
+ * this is needed when circle select is activated as a tool. */
+
/* left mouse shift for deselect too */
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_DESELECT);
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_NOP);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_NOP);
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_DESELECT); // default 2.4x
- WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP); // default 2.4x
-
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP);
+ WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_NOP); // default 2.4x
WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_SUB);
WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_SUB);