[Bf-blender-cvs] [b089332] wiggly-widgets: WidgetMaps:

Antony Riakiotakis noreply at git.blender.org
Mon Nov 10 15:49:05 CET 2014


Commit: b089332a4d3ba915eac27f6fea13b26740404bd1
Author: Antony Riakiotakis
Date:   Mon Nov 10 15:48:02 2014 +0100
Branches: wiggly-widgets
https://developer.blender.org/rBb089332a4d3ba915eac27f6fea13b26740404bd1

WidgetMaps:

Now widgetmaps get created and destroyed with the area. Not sure if it's
the best design but it avoids too many creations and recreations.

arrow offset now calculated at property binding time - no RNA access
during interaction means no chance of crash during undo.

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

M	source/blender/blenkernel/intern/screen.c
M	source/blender/editors/screen/area.c
M	source/blender/editors/screen/screen_edit.c
M	source/blender/editors/screen/screen_ops.c
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/windowmanager/intern/wm_generic_widgets.c
M	source/blender/windowmanager/intern/wm_init_exit.c
M	source/blender/windowmanager/intern/wm_widgets.c
M	source/blender/windowmanager/wm.h

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

diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 8aab931..c5a5218 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -50,6 +50,8 @@
 #include "BKE_idprop.h"
 #include "BKE_screen.h"
 
+#include "WM_api.h"
+
 /* ************ Spacetype/regiontype handling ************** */
 
 /* keep global; this has to be accessible outside of windowmanager */
@@ -311,6 +313,7 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
 			MEM_freeN(uilst->properties);
 		}
 	}
+	WM_widgetmap_delete(ar->widgetmap);
 	BLI_freelistN(&ar->ui_lists);
 	BLI_freelistN(&ar->ui_previews);
 	BLI_freelistN(&ar->panels_category);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index ed224b2..2254aeb 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1458,8 +1458,9 @@ void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade)
 		region_blend_start(C, sa, ar);
 	}
 	else {
-		if (ar->flag & RGN_FLAG_HIDDEN)
+		if (ar->flag & RGN_FLAG_HIDDEN) {
 			WM_event_remove_handlers(C, &ar->handlers);
+		}
 		
 		ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
 		ED_area_tag_redraw(sa);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index fe9d0bb..9463a70 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1270,7 +1270,6 @@ void ED_region_exit(bContext *C, ARegion *ar)
 
 	CTX_wm_region_set(C, ar);
 	WM_event_remove_handlers(C, &ar->handlers);
-	WM_widgetmap_delete(ar->widgetmap);
 	if (ar->swinid)
 		wm_subwindow_close(CTX_wm_window(C), ar->swinid);
 	ar->swinid = 0;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 76ab627..f7f723c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -3979,7 +3979,6 @@ void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar)
 		ED_area_initialize(wm, win, sa);
 	else {
 		WM_event_remove_handlers(C, &ar->handlers);
-		WM_widgetmap_delete(ar->widgetmap);
 	}
 
 	if (ar->next) {
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 122f2ad..1ddb1d7 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -383,6 +383,7 @@ static SpaceLink *view3d_new(const bContext *C)
 	
 	BLI_addtail(&v3d->regionbase, ar);
 	ar->regiontype = RGN_TYPE_WINDOW;
+	ar->widgetmap = WM_widgetmap_from_type("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW, true);
 	
 	ar->regiondata = MEM_callocN(sizeof(RegionView3D), "region view3d");
 
@@ -550,7 +551,9 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
 	
 	WM_event_add_dropbox_handler(&ar->handlers, lb);
 
-	ar->widgetmap = WM_widgetmap_from_type("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW, true);
+	/* make sure we have a widgetmap - sucks a bit to do it here, but works for now */
+	if (!ar->widgetmap)
+		ar->widgetmap = WM_widgetmap_from_type("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW, true);
 
 	WM_event_add_widget_handler(ar);
 }
diff --git a/source/blender/windowmanager/intern/wm_generic_widgets.c b/source/blender/windowmanager/intern/wm_generic_widgets.c
index b3fc761..19b2e2d 100644
--- a/source/blender/windowmanager/intern/wm_generic_widgets.c
+++ b/source/blender/windowmanager/intern/wm_generic_widgets.c
@@ -141,6 +141,7 @@ typedef struct ArrowWidget {
 	int style;
 	float direction[3];
 	float color[4];
+	float offset;
 } ArrowWidget;
 
 typedef struct ArrowInteraction {
@@ -161,7 +162,7 @@ static void arrow_draw_intern(ArrowWidget *arrow, bool select, bool highlight, f
 
 	if (arrow->widget.prop) {
 		copy_v3_v3(final_pos, arrow->direction);
-		mul_v3_fl(final_pos, scale * RNA_property_float_get(arrow->widget.ptr, arrow->widget.prop));
+		mul_v3_fl(final_pos, scale * arrow->offset);
 		add_v3_v3(final_pos, arrow->widget.origin);
 	}
 	else {
@@ -293,6 +294,9 @@ static int widget_arrow_handler(struct bContext *C, const struct wmEvent *event,
 		value = data->orig_value + facdir * len_v3(orig_origin);
 		RNA_property_float_set(widget->ptr, widget->prop, value);
 		RNA_property_update(C, widget->ptr, widget->prop);
+
+		/* accounts for clamping properly */
+		arrow->offset = RNA_property_float_get(widget->ptr, widget->prop);
 	}
 
 	/* tag the region for redraw */
@@ -305,10 +309,11 @@ static int widget_arrow_handler(struct bContext *C, const struct wmEvent *event,
 static int widget_arrow_activate(struct bContext *UNUSED(C), const struct wmEvent *event, struct wmWidget *widget, int state)
 {
 	if (state == WIDGET_ACTIVATE) {
+		ArrowWidget *arrow = (ArrowWidget *) widget;
 		ArrowInteraction *data = MEM_callocN(sizeof (ArrowInteraction), "arrow_interaction");
 
 		if (widget->prop) {
-			data->orig_value = RNA_property_float_get(widget->ptr, widget->prop);
+			data->orig_value = arrow->offset;
 		}
 
 		data->orig_mouse[0] = event->mval[0];
@@ -325,6 +330,14 @@ static int widget_arrow_activate(struct bContext *UNUSED(C), const struct wmEven
 	return OPERATOR_FINISHED;
 }
 
+static void widget_arrow_bind_to_prop(struct wmWidget *widget)
+{
+	ArrowWidget *arrow = (ArrowWidget *) widget;
+
+	/* we'd need to check the property type here but for now assume always float */
+	arrow->offset = RNA_property_float_get(widget->ptr, widget->prop);
+}
+
 
 wmWidget *WIDGET_arrow_new(int style, void *customdata)
 {
@@ -348,7 +361,7 @@ wmWidget *WIDGET_arrow_new(int style, void *customdata)
 	arrow->widget.activate_state = widget_arrow_activate;
 	arrow->widget.render_3d_intersection = widget_arrow_render_3d_intersect;
 	arrow->widget.customdata = customdata;
-
+	arrow->widget.bind_to_prop = widget_arrow_bind_to_prop;
 	arrow->style = style;
 	copy_v3_v3(arrow->direction, dir_default);
 	
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 0186105..93bbd69 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -440,7 +440,6 @@ void WM_exit_ext(bContext *C, const bool do_python)
 	BKE_addon_pref_type_free();
 	wm_operatortype_free();
 	wm_dropbox_free();
-	WM_widgetmaptypes_free();
 	WM_menutype_free();
 	WM_uilisttype_free();
 	
@@ -482,6 +481,9 @@ void WM_exit_ext(bContext *C, const bool do_python)
 	ED_clipboard_posebuf_free();
 	BKE_node_clipboard_clear();
 
+	/* widgetmaps after freeing blender, so no deleted data get accessed during cleaning up of areas */
+	WM_widgetmaptypes_free();
+
 	BLF_exit();
 
 #ifdef WITH_INTERNATIONAL
diff --git a/source/blender/windowmanager/intern/wm_widgets.c b/source/blender/windowmanager/intern/wm_widgets.c
index ad3edea..e5bb73b 100644
--- a/source/blender/windowmanager/intern/wm_widgets.c
+++ b/source/blender/windowmanager/intern/wm_widgets.c
@@ -194,6 +194,9 @@ void WM_widget_property(struct wmWidget *widget, struct PointerRNA *ptr, const c
 	widget->ptr = ptr;
 	widget->propname = propname;
 	widget->prop = RNA_struct_find_property(ptr, propname);
+
+	if (widget->bind_to_prop)
+		widget->bind_to_prop(widget);
 }
 
 void WM_widget_operator(struct wmWidget *widget,
@@ -220,8 +223,13 @@ void WM_widgets_draw(const struct bContext *C, struct ARegion *ar)
 {
 	RegionView3D *rv3d = ar->regiondata;
 	wmWidgetMap *wmap = ar->widgetmap;
-	wmWidget *widget = wmap->active_widget;
-	bool use_lighting = (U.tw_flag & V3D_SHADED_WIDGETS) != 0;
+	wmWidget *widget;;
+	bool use_lighting;
+
+	if (!wmap)
+		return;
+
+	use_lighting = (U.tw_flag & V3D_SHADED_WIDGETS) != 0;
 
 	if (use_lighting) {
 		float lightpos[4] = {0.0, 0.0, 1.0, 0.0};
@@ -239,6 +247,8 @@ void WM_widgets_draw(const struct bContext *C, struct ARegion *ar)
 		glPopMatrix();
 	}
 
+	widget = wmap->active_widget;
+
 	if (widget) {
 		float scale = 1.0;
 
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 64a6df8..e5c5019 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -69,6 +69,9 @@ typedef struct wmWidget {
 	/* handler used by the widget. Usually handles interaction tied to a widget type */
 	int  (*handler)(struct bContext *C, const struct wmEvent *event, struct wmWidget *widget, struct wmOperator *op);
 
+	/* widget-specific handler to update widget attributes when a property is bound */
+	void (*bind_to_prop)(struct wmWidget *widget);
+
 	int  flag; /* flags set by drawing and interaction, such as highlighting */
 
 	/* activate a widget state when the user clicks on it */




More information about the Bf-blender-cvs mailing list