[Bf-blender-cvs] [64d3a13] wiggly-widgets: Support for aborting widget interaction using RMB/Esc

Julian Eisel noreply at git.blender.org
Sat Aug 29 19:32:39 CEST 2015


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




More information about the Bf-blender-cvs mailing list