Commit: 3f80accfb34dd10e70380139941bcaf62702a6f8
Author: Campbell Barton
Date:   Mon Apr 27 18:53:45 2015 +1000
Branches: master
https://developer.blender.org/rB3f80accfb34dd10e70380139941bcaf62702a6f8

Fix T44011: Ruler/Knife/Loop-cut fail in quad-view

This is a kind of sloppy-focus,
resolving long standing bug with loop-cut/knife/ruler /w quad-view.

Where activating a tool would lock onto one of quad-views,
especially problematic when activating from the toolbar or menus.

===================================================================

M       source/blender/blenkernel/BKE_screen.h
M       source/blender/blenkernel/intern/screen.c
M       source/blender/editors/mesh/editmesh_knife.c
M       source/blender/editors/mesh/editmesh_loopcut.c
M       source/blender/editors/space_view3d/view3d_ruler.c
M       source/blender/makesdna/DNA_screen_types.h
M       source/blender/makesdna/DNA_windowmanager_types.h
M       source/blender/makesrna/intern/rna_wm.c
M       source/blender/windowmanager/intern/wm_event_system.c
M       source/blender/windowmanager/wm_event_system.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_screen.h 
b/source/blender/blenkernel/BKE_screen.h
index 4349993..bb76454 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -280,6 +280,7 @@ void            BKE_screen_area_free(struct ScrArea *sa);
 
 struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type);
 struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa);
+struct ARegion *BKE_area_find_region_xy(struct ScrArea *sa, const int 
regiontype, int x, int y);
 struct ScrArea *BKE_screen_find_area_from_space(struct bScreen *sc, struct 
SpaceLink *sl) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
 struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int 
spacetype, const short min);
 struct ScrArea *BKE_screen_find_area_xy(struct bScreen *sc, const int 
spacetype, int x, int y);
diff --git a/source/blender/blenkernel/intern/screen.c 
b/source/blender/blenkernel/intern/screen.c
index 3c43bfa..36fd598 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -405,6 +405,23 @@ ARegion *BKE_area_find_region_active_win(ScrArea *sa)
        return NULL;
 }
 
+ARegion *BKE_area_find_region_xy(ScrArea *sa, const int regiontype, int x, int 
y)
+{
+       ARegion *ar_found = NULL;
+       if (sa) {
+               ARegion *ar;
+               for (ar = sa->regionbase.first; ar; ar = ar->next) {
+                       if ((regiontype == RGN_TYPE_ANY) || (ar->regiontype == 
regiontype)) {
+                               if (BLI_rcti_isect_pt(&ar->winrct, x, y)) {
+                                       ar_found = ar;
+                                       break;
+                               }
+                       }
+               }
+       }
+       return ar_found;
+}
+
 /**
  * \note, ideally we can get the area from the context,
  * there are a few places however where this isn't practical.
diff --git a/source/blender/editors/mesh/editmesh_knife.c 
b/source/blender/editors/mesh/editmesh_knife.c
index df91679..4f88390 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -3051,6 +3051,8 @@ static int knifetool_invoke(bContext *C, wmOperator *op, 
const wmEvent *event)
 
        knifetool_init(C, kcd, only_select, cut_through, true);
 
+       op->flag |= OP_IS_MODAL_CURSOR_REGION;
+
        /* add a modal handler for this operator - handles loop selection */
        WM_cursor_modal_set(CTX_wm_window(C), BC_KNIFECURSOR);
        WM_event_add_modal_handler(C, op);
@@ -3143,6 +3145,9 @@ static int knifetool_modal(bContext *C, wmOperator *op, 
const wmEvent *event)
                return OPERATOR_FINISHED;
        }
 
+       em_setup_viewcontext(C, &kcd->vc);
+       kcd->ar = kcd->vc.ar;
+
        view3d_operator_needs_opengl(C);
        ED_view3d_init_mats_rv3d(obedit, kcd->vc.rv3d);  /* needed to 
initialize clipping */
 
@@ -3302,6 +3307,13 @@ static int knifetool_modal(bContext *C, wmOperator *op, 
const wmEvent *event)
                }
        }
 
+       if (kcd->mode == MODE_DRAGGING) {
+               op->flag &= ~OP_IS_MODAL_CURSOR_REGION;
+       }
+       else {
+               op->flag |= OP_IS_MODAL_CURSOR_REGION;
+       }
+
        if (do_refresh) {
                /* we don't really need to update mval,
                 * but this happens to be the best way to refresh at the moment 
*/
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c 
b/source/blender/editors/mesh/editmesh_loopcut.c
index a4ea2ab..c7f9522 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -553,6 +553,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const 
wmEvent *event)
 
        /* add a modal handler for this operator - handles loop selection */
        if (is_interactive) {
+               op->flag |= OP_IS_MODAL_CURSOR_REGION;
                WM_event_add_modal_handler(C, op);
        }
 
@@ -639,6 +640,9 @@ static int loopcut_modal(bContext *C, wmOperator *op, const 
wmEvent *event)
        bool show_cuts = false;
        const bool has_numinput = hasNumInput(&lcd->num);
 
+       em_setup_viewcontext(C, &lcd->vc);
+       lcd->ar = lcd->vc.ar;
+
        view3d_operator_needs_opengl(C);
 
        /* using the keyboard to input the number of cuts */
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c 
b/source/blender/editors/space_view3d/view3d_ruler.c
index eba3186..addda0a 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -187,6 +187,7 @@ typedef struct RulerInfo {
 
        /* wm state */
        wmWindow *win;
+       ScrArea *sa;
        ARegion *ar;
        void *draw_handle_pixel;
 } RulerInfo;
@@ -435,7 +436,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, 
ARegion *ar, void *a
        UnitSettings *unit = &scene->unit;
        RulerItem *ruler_item;
        RulerInfo *ruler_info = arg;
-       RegionView3D *rv3d = ruler_info->ar->regiondata;
+       RegionView3D *rv3d = ar->regiondata;
 //     ARegion *ar = ruler_info->ar;
        const float cap_size = 4.0f;
        const float bg_margin = 4.0f * U.pixelsize;
@@ -798,12 +799,14 @@ static int view3d_ruler_invoke(bContext *C, wmOperator 
*op, const wmEvent *UNUSE
        op->customdata = ruler_info;
 
        ruler_info->win = win;
-       ruler_info->ar = ar;
+       ruler_info->sa = sa;
        ruler_info->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, 
ruler_info_draw_pixel,
                                                                   ruler_info, 
REGION_DRAW_POST_PIXEL);
 
        view3d_ruler_header_update(sa);
 
+       op->flag |= OP_IS_MODAL_CURSOR_REGION;
+
        WM_cursor_modal_set(win, BC_CROSSCURSOR);
        WM_event_add_modal_handler(C, op);
 
@@ -829,11 +832,13 @@ static int view3d_ruler_modal(bContext *C, wmOperator 
*op, const wmEvent *event)
        RegionView3D *rv3d = ar->regiondata;
 
        /* its possible to change spaces while running the operator [#34894] */
-       if (UNLIKELY(ar != CTX_wm_region(C))) {
+       if (UNLIKELY(sa != ruler_info->sa)) {
                exit_code = OPERATOR_FINISHED;
                goto exit;
        }
 
+       ruler_info->ar = ar;
+
        switch (event->type) {
                case LEFTMOUSE:
                        if (event->val == KM_RELEASE) {
@@ -1019,6 +1024,13 @@ static int view3d_ruler_modal(bContext *C, wmOperator 
*op, const wmEvent *event)
 
        }
 
+       if (ruler_info->state == RULER_STATE_DRAG) {
+               op->flag &= ~OP_IS_MODAL_CURSOR_REGION;
+       }
+       else {
+               op->flag |= OP_IS_MODAL_CURSOR_REGION;
+       }
+
        if (do_draw) {
                view3d_ruler_header_update(sa);
 
diff --git a/source/blender/makesdna/DNA_screen_types.h 
b/source/blender/makesdna/DNA_screen_types.h
index 13365ad..eb76c90 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -374,6 +374,8 @@ enum {
        RGN_TYPE_TOOL_PROPS = 6,
        RGN_TYPE_PREVIEW = 7
 };
+/* use for function args */
+#define RGN_TYPE_ANY -1
 
 /* region alignment */
 #define RGN_ALIGN_NONE         0
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h 
b/source/blender/makesdna/DNA_windowmanager_types.h
index 4aa49ee..51ed8bb 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -390,10 +390,16 @@ enum {
 
 /* wmOperator flag */
 enum {
-       OP_IS_MODAL_GRAB_CURSOR    = (1 << 0),
        /* low level flag so exec() operators can tell if they were invoked, 
use with care.
         * typically this shouldn't make any difference, but it rare cases its 
needed (see smooth-view) */
-       OP_IS_INVOKE       = (1 << 1),
+       OP_IS_INVOKE = (1 << 0),
+
+       /* When the cursor is grabbed */
+       OP_IS_MODAL_GRAB_CURSOR    = (1 << 1),
+
+       /* allow modal operators to have the region under the cursor for their 
context
+        * (the regiontype is maintained to prevent errors) */
+       OP_IS_MODAL_CURSOR_REGION = (1 << 2),
 };
 
 #endif /* __DNA_WINDOWMANAGER_TYPES_H__ */
diff --git a/source/blender/makesrna/intern/rna_wm.c 
b/source/blender/makesrna/intern/rna_wm.c
index ded4ea0..3b8ddd0 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -1416,6 +1416,10 @@ static void rna_def_operator_options_runtime(BlenderRNA 
*brna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", OP_IS_INVOKE);
        RNA_def_property_ui_text(prop, "Invoke", "True when invoked (even if 
only the execute callbacks available)");
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+       prop = RNA_def_property(srna, "use_cursor_region", PROP_BOOLEAN, 
PROP_BOOLEAN);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", 
OP_IS_MODAL_CURSOR_REGION);
+       RNA_def_property_ui_text(prop, "Focus Region", "Enable to use the 
region under the cursor for modal execution");
 }
 
 static void rna_def_operator(BlenderRNA *brna)
diff --git a/source/blender/windowmanager/intern/wm_event_system.c 
b/source/blender/windowmanager/intern/wm_event_system.c
index 8c97d39..830feed 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1337,7 +1337,7 @@ void wm_event_free_handler(wmEventHandler *handler)
 }
 
 /* only set context when area/region is part of screen */
-static void wm_handler_op_context(bContext *C, wmEventHandler *handler)
+static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const 
wmEvent *event)
 {
        bScreen *screen = CTX_wm_screen(C);
        
@@ -1358,10 +1358,27 @@ static void wm_handler_op_context(bContext *C, 
wmEventHandler *handler)
                        }
                        else {
                                ARegion *ar;
+                               wmOperator *op = handler->op ? 
(handler->op->opm ? handler->op->opm : handler->op) : NULL;
                                CTX_wm_area_set(C, sa);
-                               for (ar = sa->regionbase.first; ar; ar = 
ar->next)
-                                       if (ar == handler->op_region)
-                                               break;
+
+                               if (op && (op->flag & 
OP_IS_MODAL_CURSOR_REGION)) {
+                                       ar = BKE_area_find_region_xy(sa, 
handler->op_region_type, event->x, event->y);
+                                       if (ar) {
+                                               handler->op_region = ar;
+                                       }
+                               }
+                               else {
+                                       ar = NULL;
+                               }
+
+                               if (ar == NULL) {
+                                       for (ar = sa->regionbase.first; ar; ar 
= ar->next) {
+                                               if (ar == handler->op_region) {
+                                                       break;
+                                               }
+                                       }
+                               }
+
                                /* XXX no warning print here, after full-area 
and back regions are remade */
                                if (ar)
                                        CTX_wm_region_set(C, ar);
@@ -1379,11 +1396,12 @@ void WM_event_remove_handlers(bContext *C, ListBase 
*handlers)
        /* C is zero on freeing database, modal handlers then already were 
freed */
        while ((handler = BLI_pophead(handlers))) {
                if (handler->op) {
+                       wmWindow *win = CTX_wm_window(C);
                        if (handler->op->type->cancel) {
                                ScrArea *area = CTX_wm_area(C);
                                ARegion *region = CTX_wm_region(C);
                                
-                               wm_handler_op_context(C, handler);
+                               wm_handler_op_context(C, handler, 
win->eventstate);
 


@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to