[Bf-blender-cvs] [1288342] wiggly-widgets: Get manipulator handling to work!
Julian Eisel
noreply at git.blender.org
Sat Aug 22 16:24:46 CEST 2015
Commit: 12883426a43be3ef6882387967000ceb5d8b4a23
Author: Julian Eisel
Date: Sat Aug 22 15:15:02 2015 +0200
Branches: wiggly-widgets
https://developer.blender.org/rB12883426a43be3ef6882387967000ceb5d8b4a23
Get manipulator handling to work!
Meaning manipulator finally does what it's supposed to do.
There is still a crash when leaving active window while transforming, and drawing of dragged widget is also a bit jiggly, but everything else seems to work :)
===================================================================
M source/blender/editors/transform/manipulator_widget.c
M source/blender/windowmanager/intern/wm_event_system.c
M source/blender/windowmanager/intern/wm_widgets.c
M source/blender/windowmanager/wm_event_system.h
===================================================================
diff --git a/source/blender/editors/transform/manipulator_widget.c b/source/blender/editors/transform/manipulator_widget.c
index 46551a1..f632c90 100644
--- a/source/blender/editors/transform/manipulator_widget.c
+++ b/source/blender/editors/transform/manipulator_widget.c
@@ -288,6 +288,33 @@ static void manipulator_get_axis_color(const RegionView3D *rv3d, const int axis_
}
}
+static void manipulator_get_axis_constraint(const int axis_idx, int r_axis[3])
+{
+ zero_v3_int(r_axis);
+
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_X:
+ case MAN_AXIS_ROT_X:
+ case MAN_AXIS_SCALE_X:
+ r_axis[0] = 1;
+ break;
+ case MAN_AXIS_TRANS_Y:
+ case MAN_AXIS_ROT_Y:
+ case MAN_AXIS_SCALE_Y:
+ r_axis[1] = 1;
+ break;
+ case MAN_AXIS_TRANS_Z:
+ case MAN_AXIS_ROT_Z:
+ case MAN_AXIS_SCALE_Z:
+ r_axis[2] = 1;
+ break;
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ break;
+ }
+}
+
/* **************** Preparation Stuff **************** */
@@ -939,6 +966,26 @@ static ManipulatorGroup *manipulatorgroup_init(
return man;
}
+/**
+ * Custom handler for manipulator widgets
+ */
+static int manipulator_handler(bContext *C, const wmEvent *UNUSED(event), wmWidget *widget)
+{
+ const ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (calc_manipulator_stats(C)) {
+ manipulator_prepare_mat(CTX_data_scene(C), v3d, rv3d);
+ WM_widget_set_origin(widget, rv3d->twmat[3]);
+ }
+
+ ED_region_tag_redraw(ar);
+
+ return OPERATOR_PASS_THROUGH;
+}
+
void WIDGETGROUP_manipulator_draw(const struct bContext *C, struct wmWidgetGroup *wgroup)
{
const ScrArea *sa = CTX_wm_area(C);
@@ -978,6 +1025,9 @@ void WIDGETGROUP_manipulator_draw(const struct bContext *C, struct wmWidgetGroup
{
const short axis_type = manipulator_get_axis_type(man, axis);
const int aidx_norm = manipulator_index_normalize(axis_idx);
+ int constraint_axis[3] = {1, 0, 0};
+
+ PointerRNA *ptr;
float line_vec[2][3];
float col[4];
@@ -987,7 +1037,10 @@ void WIDGETGROUP_manipulator_draw(const struct bContext *C, struct wmWidgetGroup
}
manipulator_get_axis_color(rv3d, axis_idx, col);
+ manipulator_get_axis_constraint(axis_idx, constraint_axis);
WM_widget_set_origin(axis, rv3d->twmat[3]);
+ /* custom handler! */
+ axis->handler = manipulator_handler;
switch(axis_idx) {
case MAN_AXIS_TRANS_X:
@@ -1027,15 +1080,17 @@ void WIDGETGROUP_manipulator_draw(const struct bContext *C, struct wmWidgetGroup
switch (axis_type) {
case MAN_AXES_TRANSLATE:
- WM_widget_operator(axis, "TRANSFORM_OT_translate");
+ ptr = WM_widget_operator(axis, "TRANSFORM_OT_translate");
break;
case MAN_AXES_ROTATE:
- WM_widget_operator(axis, "TRANSFORM_OT_rotate");
+ ptr = WM_widget_operator(axis, "TRANSFORM_OT_rotate");
break;
case MAN_AXES_SCALE:
- WM_widget_operator(axis, "TRANSFORM_OT_resize");
+ ptr = WM_widget_operator(axis, "TRANSFORM_OT_resize");
break;
}
+ RNA_boolean_set_array(ptr, "constraint_axis", constraint_axis);
+ RNA_boolean_set(ptr, "release_confirm", 1);
}
MAN_ITER_AXES_END;
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index d1d2025..b884c00 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1451,40 +1451,6 @@ static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wm
}
}
-static void wm_handler_widgetmap_context(bContext *C, wmEventHandler *handler)
-{
- bScreen *screen = CTX_wm_screen(C);
-
- if (screen) {
- if (handler->op_area == NULL) {
- /* do nothing in this context */
- }
- else {
- ScrArea *sa;
-
- for (sa = screen->areabase.first; sa; sa = sa->next)
- if (sa == handler->op_area)
- break;
- if (sa == NULL) {
- /* when changing screen layouts with running modal handlers (like render display), this
- * is not an error to print */
- if (handler->widgetmap == NULL)
- printf("internal error: modal widgetmap handler has invalid area\n");
- }
- else {
- ARegion *ar;
- CTX_wm_area_set(C, sa);
- 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);
- }
- }
- }
-}
-
/* called on exit or remove area, only here call cancel callback */
void WM_event_remove_handlers(bContext *C, ListBase *handlers)
{
@@ -2091,16 +2057,17 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
}
else if (handler->widgetmap) {
- struct wmWidgetMap *wmap = handler->widgetmap;
+ wmWidgetMap *wmap = handler->widgetmap;
unsigned char part;
short event_processed = 0;
wmWidget *widget = wm_widgetmap_get_active_widget(wmap);
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
-
- wm_handler_widgetmap_context(C, handler);
+
+ wm_widgetmap_handler_context(C, handler);
wm_region_mouse_co(C, event);
-
+
+ /* handle the widget first, before passing the event down */
switch (event->type) {
case MOUSEMOVE:
if (widget) {
@@ -2145,7 +2112,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
/* restore the area */
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
-
+
if (handler->op) {
/* if event was processed by an active widget pass the modified event to the operator */
if (event_processed) {
@@ -2155,9 +2122,14 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
}
else {
- /* handle the widget first, before passing the event down */
+ /* context region may be changed in wm_handler_operator_call */
+ ARegion *ar = CTX_wm_region(C);
+
/* modal, swallows all */
action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
+
+ /* update widgets during modal handlers */
+ wm_widget_handler_modal_update(C, event, handler, ar);
}
if (action & WM_HANDLER_BREAK) {
diff --git a/source/blender/windowmanager/intern/wm_widgets.c b/source/blender/windowmanager/intern/wm_widgets.c
index 3446bb4..dc0f17d 100644
--- a/source/blender/windowmanager/intern/wm_widgets.c
+++ b/source/blender/windowmanager/intern/wm_widgets.c
@@ -766,10 +766,11 @@ void wm_widgetmap_set_active_widget(
if (widget) {
if (call_op) {
wmOperatorType *ot;
- const char *opname = (widget->opname) ? widget->opname : "WM_OT_widget_tweak";
-
+ const bool has_custom_op = widget->opname != NULL;
+ const char *opname = has_custom_op ? widget->opname : "WM_OT_widget_tweak";
+
ot = WM_operatortype_find(opname, 0);
-
+
if (ot) {
/* first activate the widget itself */
if (widget->invoke && widget->handler) {
@@ -783,12 +784,12 @@ void wm_widgetmap_set_active_widget(
if (WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &widget->opptr) == OPERATOR_RUNNING_MODAL) {
/* check if operator added a a modal event handler */
wmEventHandler *handler = CTX_wm_window(C)->modalhandlers.first;
-
- if (handler && handler->op && handler->op->type == ot) {
+
+ if (has_custom_op == false && handler && handler->op && handler->op->type == ot) {
handler->widgetmap = wmap;
}
}
-
+
/* we failed to hook the widget to the operator handler or operator was cancelled, return */
if (!wmap->active_widget) {
widget->flag &= ~WM_WIDGET_ACTIVE;
@@ -836,6 +837,71 @@ void wm_widgetmap_set_active_widget(
}
}
+void wm_widgetmap_handler_context(bContext *C, wmEventHandler *handler)
+{
+ bScreen *screen = CTX_wm_screen(C);
+
+ if (screen) {
+ if (handler->op_area == NULL) {
+ /* do nothing in this context */
+ }
+ else {
+ ScrArea *sa;
+
+ for (sa = screen->areabase.first; sa; sa = sa->next)
+ if (sa == handler->op_area)
+ break;
+ if (sa == NULL) {
+ /* when changing screen layouts with running modal handlers (like render display), this
+ * is not an error to print */
+ if (handler->widgetmap == NULL)
+ printf("internal error: modal widgetmap handler has invalid area\n");
+ }
+ else {
+ ARegion *ar;
+ CTX_wm_area_set(C, sa);
+ 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);
+ }
+ }
+ }
+}
+
+void wm_widget_handler_modal_update(bContext *C, wmEvent *event, wmEventHandler *handler, ARegion *ar)
+{
+ wmWidgetMap *wmap;
+
+ for (wmap = ar->widgetmaps.first; wmap; wmap = wmap->next) {
+ wmWidget *widget = wm_widgetmap_get_active_widget(wmap);
+ ScrArea *area = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+
+ if (!widget)
+ continue;
+
+ wm_widgetmap_handler_context(C, handler);
+
+ /* regular update for running operator */
+ if (handler->op) {
+ if (widget && widget->handler) {
+ widget->handler(C, event, widget);
+ }
+ }
+ /* operator not running anymore */
+ else {
+ wm_widgetmap_set_active_widget(wmap, C, event, NULL, false);
+ }
+
+ /* restore the area */
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+ }
+}
+
wmWidget *wm_widgetmap_get_active_widget(wmWidgetMap *wmap)
{
return wmap->active_widget;
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 38bf430..8c9d3aa 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -101,6 +101,9 @@ void wm_drags_check_ops(bContext *C, wmEvent *event);
void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect);
/* wm_widgets.c */
+void wm_widget_handler_modal_update(bContext *C, wmEvent *event, wmEventHandler *handler, struct ARegion *ar);
+void wm_widgetmap_handler_context(bContext *C, wmEventHandler *handler);
+
struct wmWidget *wm_widget_find_highlig
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list