[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