Commit: 64d3a138351ac3eb8e4e489ee31fbeb78b3542ac
Author: Julian Eisel
Date:   Sat Aug 29 19:29:47 2015 +0200
Branches: wiggly-widgets
https://developer.blender.org/rB64d3a138351ac3eb8e4e489ee31fbeb78b3542ac

Support for aborting widget interaction using RMB/Esc

Would be much better if we could add a modal handler for widgets, so we don't 
need to hardcode the keymap, but supporting this isn't easy (I tried it today 
:/)

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

M       source/blender/editors/space_graph/graph_edit.c
M       source/blender/editors/space_sequencer/sequencer_view.c
M       source/blender/windowmanager/intern/wm_event_system.c
M       source/blender/windowmanager/intern/wm_generic_widgets.c
M       source/blender/windowmanager/wm.h

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

diff --git a/source/blender/editors/space_graph/graph_edit.c 
b/source/blender/editors/space_graph/graph_edit.c
index faf3216..300657a 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -2583,7 +2583,9 @@ static int graph_widget_backdrop_transform_modal(bContext 
*C, wmOperator *op, co
        }
 
        switch (event->type) {
-               case EVT_WIDGET_UPDATE: {
+               case EVT_WIDGET_UPDATE:
+               case EVT_WIDGET_RELEASED:
+               {
                        SpaceIpo *sipo = CTX_wm_space_graph(C);
                        RNA_float_get_array(op->ptr, "offset", 
sipo->backdrop_offset);
                        sipo->backdrop_zoom = RNA_float_get(op->ptr, "scale");
@@ -2613,12 +2615,18 @@ static int 
graph_widget_backdrop_transform_modal(bContext *C, wmOperator *op, co
                case ESCKEY:
                case RIGHTMOUSE:
                {
+                       ARegion *ar = CTX_wm_region(C);
+                       wmWidgetMap *wmap = ar->widgetmaps.first;
                        SpaceIpo *sipo = CTX_wm_space_graph(C);
-                       copy_v2_v2(sipo->backdrop_offset, data->init_offset);
-                       sipo->backdrop_zoom = data->init_zoom;
 
-                       graph_widget_backdrop_transform_finish(C, data);
-                       return OPERATOR_CANCELLED;
+                       /* only end modal if we're not dragging a widget */
+                       if (!wmap->active_widget && event->val == KM_PRESS) {
+                               copy_v2_v2(sipo->backdrop_offset, 
data->init_offset);
+                               sipo->backdrop_zoom = data->init_zoom;
+
+                               graph_widget_backdrop_transform_finish(C, data);
+                               return OPERATOR_CANCELLED;
+                       }
                }
        }
 
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c 
b/source/blender/editors/space_sequencer/sequencer_view.c
index e8a0985..a6fc537 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -337,14 +337,15 @@ static int sequencer_overdrop_transform_modal(bContext 
*C, wmOperator *op, const
        }
        
        switch (event->type) {
-               case EVT_WIDGET_UPDATE: {
+               case EVT_WIDGET_UPDATE:
+               case EVT_WIDGET_RELEASED:
+               {
                        SpaceSeq *sseq = CTX_wm_space_seq(C);
                        RNA_float_get_array(op->ptr, "offset", 
sseq->overdrop_offset);
                        sseq->overdrop_zoom = RNA_float_get(op->ptr, "scale");
                        break;
                }
-                       
-               case RKEY: 
+               case RKEY:
                {
                        SpaceSeq *sseq = CTX_wm_space_seq(C);
                        ARegion *ar = CTX_wm_region(C);
@@ -369,12 +370,18 @@ static int sequencer_overdrop_transform_modal(bContext 
*C, wmOperator *op, const
                case ESCKEY:
                case RIGHTMOUSE:
                {
+                       ARegion *ar = CTX_wm_region(C);
+                       wmWidgetMap *wmap = ar->widgetmaps.first;
                        SpaceSeq *sseq = CTX_wm_space_seq(C);
-                       copy_v2_v2(sseq->overdrop_offset, data->init_offset);
-                       sseq->overdrop_zoom = data->init_zoom;
-                       
-                       sequencer_overdrop_finish(C, data);
-                       return OPERATOR_CANCELLED;
+
+                       /* only end modal if we're not dragging a widget */
+                       if (!wmap->active_widget && event->val == KM_PRESS) {
+                               copy_v2_v2(sseq->overdrop_offset, 
data->init_offset);
+                               sseq->overdrop_zoom = data->init_zoom;
+
+                               sequencer_overdrop_finish(C, data);
+                               return OPERATOR_CANCELLED;
+                       }
                }
        }
        
diff --git a/source/blender/windowmanager/intern/wm_event_system.c 
b/source/blender/windowmanager/intern/wm_event_system.c
index 6334dc7..2554b7a 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2086,7 +2086,6 @@ static int wm_handlers_do_intern(bContext *C, wmEvent 
*event, ListBase *handlers
                                                break;
 
                                        case LEFTMOUSE:
-                                       {
                                                if (widget) {
                                                        if (event->val == 
KM_RELEASE) {
                                                                
wm_widgetmap_set_active_widget(wmap, C, event, NULL, false);
@@ -2106,7 +2105,17 @@ static int wm_handlers_do_intern(bContext *C, wmEvent 
*event, ListBase *handlers
                                                        }
                                                }
                                                break;
-                                       }
+                                       case RIGHTMOUSE:
+                                       case ESCKEY:
+                                               if (widget) {
+                                                       if (widget->cancel) {
+                                                               
widget->cancel(C, widget);
+                                                       }
+                                                       
wm_widgetmap_set_active_widget(wmap, C, event, NULL, false);
+                                                       event_processed = 
EVT_WIDGET_RELEASED;
+                                                       action |= 
WM_HANDLER_BREAK;
+                                               }
+                                               break;
                                }
                                
                                /* restore the area */
diff --git a/source/blender/windowmanager/intern/wm_generic_widgets.c 
b/source/blender/windowmanager/intern/wm_generic_widgets.c
index ce832a0..c13a694 100644
--- a/source/blender/windowmanager/intern/wm_generic_widgets.c
+++ b/source/blender/windowmanager/intern/wm_generic_widgets.c
@@ -174,6 +174,7 @@ typedef struct ArrowWidget {
 } ArrowWidget;
 
 typedef struct ArrowInteraction {
+       float orig_value; /* initial property value */
        float orig_origin[3];
        float orig_mouse[2];
        float orig_offset;
@@ -496,6 +497,12 @@ static int widget_arrow_invoke(bContext *UNUSED(C), const 
wmEvent *event, wmWidg
 {
        ArrowWidget *arrow = (ArrowWidget *) widget;
        ArrowInteraction *data = MEM_callocN(sizeof(ArrowInteraction), 
"arrow_interaction");
+       PointerRNA ptr = widget->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE];
+       PropertyRNA *prop = widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
+
+       if (prop) {
+               data->orig_value = RNA_property_float_get(&ptr, prop);
+       }
 
        data->orig_offset = arrow->offset;
 
@@ -548,6 +555,17 @@ static void widget_arrow_bind_to_prop(wmWidget *widget, 
const int UNUSED(slot))
                arrow->offset = 0.0f;
 }
 
+static void widget_arrow_cancel(bContext *C, wmWidget *widget)
+{
+       PointerRNA ptr = widget->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE];
+       PropertyRNA *prop = widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
+       ArrowInteraction *data = widget->interaction_data;
+
+       /* reset property */
+       RNA_property_float_set(&ptr, prop, data->orig_value);
+       RNA_property_update(C, &ptr, prop);
+}
+
 wmWidget *WIDGET_arrow_new(wmWidgetGroup *wgroup, const char *name, const int 
style)
 {
        ArrowWidget *arrow = MEM_callocN(sizeof(ArrowWidget), name);
@@ -590,6 +608,7 @@ wmWidget *WIDGET_arrow_new(wmWidgetGroup *wgroup, const 
char *name, const int st
        arrow->widget.invoke = widget_arrow_invoke;
        arrow->widget.render_3d_intersection = widget_arrow_render_3d_intersect;
        arrow->widget.bind_to_prop = widget_arrow_bind_to_prop;
+       arrow->widget.cancel = widget_arrow_cancel;
        arrow->widget.flag |= WM_WIDGET_SCALE_3D;
 
        arrow->style = real_style;
@@ -1362,6 +1381,33 @@ static void widget_rect_transform_bind_to_prop(wmWidget 
*widget, const int slot)
                widget_rect_transform_get_property(widget, 
RECT_TRANSFORM_SLOT_SCALE, cage->scale);
 }
 
+static void widget_rect_transform_cancel(bContext *C, wmWidget *widget)
+{
+       RectTransformWidget *cage = (RectTransformWidget *) widget;
+       RectTransformInteraction *data = widget->interaction_data;
+
+       /* reset property */
+       if (widget->props[RECT_TRANSFORM_SLOT_OFFSET]) {
+               PointerRNA ptr = widget->ptr[RECT_TRANSFORM_SLOT_OFFSET];
+               PropertyRNA *prop = widget->props[RECT_TRANSFORM_SLOT_OFFSET];
+
+               RNA_property_float_set_array(&ptr, prop, data->orig_offset);
+               RNA_property_update(C, &ptr, prop);
+       }
+       if (widget->props[RECT_TRANSFORM_SLOT_SCALE]) {
+               PointerRNA ptr = widget->ptr[RECT_TRANSFORM_SLOT_SCALE];
+               PropertyRNA *prop = widget->props[RECT_TRANSFORM_SLOT_SCALE];
+
+               if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM){
+                       RNA_property_float_set(&ptr, prop, data->orig_scale[0]);
+               }
+               else {
+                       RNA_property_float_set_array(&ptr, prop, 
data->orig_scale);
+               }
+               RNA_property_update(C, &ptr, prop);
+       }
+}
+
 wmWidget *WIDGET_rect_transform_new(
         wmWidgetGroup *wgroup, const char *name, const int style,
         const float width, const float height)
@@ -1373,6 +1419,7 @@ wmWidget *WIDGET_rect_transform_new(
        cage->widget.bind_to_prop = widget_rect_transform_bind_to_prop;
        cage->widget.handler = widget_rect_transform_handler;
        cage->widget.intersect = widget_rect_tranfrorm_intersect;
+       cage->widget.cancel = widget_rect_transform_cancel;
        cage->widget.get_cursor = widget_rect_tranfrorm_get_cursor;
        cage->widget.max_prop = 2;
        cage->scale[0] = cage->scale[1] = 1.0f;
diff --git a/source/blender/windowmanager/wm.h 
b/source/blender/windowmanager/wm.h
index e0bf73d..e4c3e4d 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -76,6 +76,9 @@ typedef struct wmWidget {
        /* activate a widget state when the user clicks on it */
        int (*invoke)(struct bContext *C, const struct wmEvent *event, struct 
wmWidget *widget);
 
+       /* called after canceling widget handling - used to reset property */
+       void (*cancel)(struct bContext *C, struct wmWidget *widget);
+
        int (*get_cursor)(struct wmWidget *widget);
        
        int  flag; /* flags set by drawing and interaction, such as 
highlighting */

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

Reply via email to