[Bf-blender-cvs] [553c88d] temp_widgets_c++_experiment: Port over widget draw routine (update and draw functions)

Julian Eisel noreply at git.blender.org
Sun Dec 20 21:30:40 CET 2015


Commit: 553c88dc38776aa4cc8002d1f2c5cf86351d793f
Author: Julian Eisel
Date:   Sun Dec 20 21:30:06 2015 +0100
Branches: temp_widgets_c++_experiment
https://developer.blender.org/rB553c88dc38776aa4cc8002d1f2c5cf86351d793f

Port over widget draw routine (update and draw functions)

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

M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/widgets/wm_widget.cc
M	source/blender/windowmanager/intern/widgets/wm_widget.h
M	source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.cc
M	source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.h
M	source/blender/windowmanager/intern/widgets/wm_widgetmap.cc
M	source/blender/windowmanager/intern/widgets/wm_widgetmap.h
M	source/blender/windowmanager/intern/widgets/wm_widgets_c_api.cc
M	source/blender/windowmanager/intern/widgets/wm_widgets_c_api.h
M	source/blender/windowmanager/intern/wm_widgets.c

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

diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 04a6760..c45a795 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -512,9 +512,6 @@ struct wmWidget *WM_widget_new(void (*draw)(const struct bContext *, struct wmWi
                                int  (*intersect)(struct bContext *, const struct wmEvent *, struct wmWidget *),
                                int  (*handler)(struct bContext *, const struct wmEvent *, struct wmWidget *, const int));
 
-void  WM_widgetmap_widgets_update(const struct bContext *C, struct wmWidgetMapC *wmap);
-void  WM_widgetmap_widgets_draw(const struct bContext *C, const struct wmWidgetMapC *wmap,
-                      const bool in_scene, const bool free_drawwidgets);
 void  WM_event_add_area_widgetmap_handlers(struct ARegion *ar);
 void  WM_modal_handler_attach_widgetgroup(struct bContext *C, struct wmEventHandler *handler,
                                           struct wmWidgetGroupTypeC *wgrouptype, struct wmOperator *op);
diff --git a/source/blender/windowmanager/intern/widgets/wm_widget.cc b/source/blender/windowmanager/intern/widgets/wm_widget.cc
index e546fac..aa88754 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widget.cc
+++ b/source/blender/windowmanager/intern/widgets/wm_widget.cc
@@ -27,12 +27,17 @@
  *  \ingroup wm
  */
 
+#include <string.h>
+
 #include "BKE_context.h"
 
 #include "DNA_defs.h"
 #include "DNA_listBase.h"
+#include "DNA_view3d_types.h"
 #include "DNA_windowmanager_types.h"
 
+#include "ED_view3d.h"
+
 #include "MEM_guardedalloc.h"
 
 #include "WM_api.h"
@@ -52,7 +57,7 @@ wmWidget::wmWidget()
 /**
  * Free widget data, not widget itself.
  */
-static void widget_data_free(wmWidget *widget)
+void widget_data_free(wmWidget *widget)
 {
 	if (widget->opptr.data) {
 		WM_operator_properties_free(&widget->opptr);
@@ -88,3 +93,29 @@ void widget_find_active_3D_loop(const bContext *C, ListBase *visible_widgets)
 	}
 }
 
+
+void widget_calculate_scale(wmWidget *widget, const bContext *C)
+{
+	const RegionView3D *rv3d = CTX_wm_region_view3d(C);
+	float scale = 1.0f;
+
+	if (rv3d && (U.tw_flag & V3D_3D_WIDGETS) == 0 && (widget->flag & WM_WIDGET_SCALE_3D)) {
+		if (widget->get_final_position) {
+			float position[3];
+
+			widget->get_final_position(widget, position);
+			scale = ED_view3d_pixel_size(rv3d, position) * (float)U.tw_size;
+		}
+		else {
+			scale = ED_view3d_pixel_size(rv3d, widget->origin) * (float)U.tw_size;
+		}
+	}
+
+	widget->scale = scale * widget->user_scale;
+}
+
+bool widget_compare(const wmWidget *a, const wmWidget *b)
+{
+	return STREQ(a->idname, b->idname);
+}
+
diff --git a/source/blender/windowmanager/intern/widgets/wm_widget.h b/source/blender/windowmanager/intern/widgets/wm_widget.h
index 2de9315..a873e05 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widget.h
+++ b/source/blender/windowmanager/intern/widgets/wm_widget.h
@@ -61,6 +61,9 @@ public:
 #endif
 
 void widget_delete(ListBase *widgetlist, wmWidget *widget);
+void widget_data_free(wmWidget *widget);
 void widget_find_active_3D_loop(const bContext *C, ListBase *visible_widgets);
+void widget_calculate_scale(wmWidget *widget, const bContext *C);
+bool widget_compare(const wmWidget *a, const wmWidget *b);
 
 #endif // __WM_WIDGET_H__
diff --git a/source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.cc b/source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.cc
index 0b50da2..54eea83 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.cc
+++ b/source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.cc
@@ -169,8 +169,3 @@ size_t wmWidgetGroupType::get_idname(char *r_idname)
 	return sizeof(this->idname);
 }
 
-bool wmWidgetGroupType::poll_check(const bContext *C)
-{
-	return (!poll || poll(C, this));
-}
-
diff --git a/source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.h b/source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.h
index b414648..9bbe060 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.h
+++ b/source/blender/windowmanager/intern/widgets/wm_widgetgrouptype.h
@@ -61,18 +61,15 @@ public:
 	void attach_to_handler(bContext *C, struct wmEventHandler *handler, struct wmOperator *op);
 	size_t get_idname(char *r_idname);
 
-	bool poll_check(const bContext *) ATTR_WARN_UNUSED_RESULT;
-
-private:
-	char idname[64]; /* MAX_NAME */
-	char name[64]; /* widget group name - displayed in UI (keymap editor) */
-
 	/* poll if widgetmap should be active */
 	int (*poll)(const bContext *, wmWidgetGroupType *) ATTR_WARN_UNUSED_RESULT;
-
 	/* update widgets, called right before drawing */
 	void (*create)(const bContext *, wmWidgetGroup *);
 
+private:
+	char idname[64]; /* MAX_NAME */
+	char name[64]; /* widget group name - displayed in UI (keymap editor) */
+
 	/* keymap init callback for this widgetgroup */
 	wmKeyMap *(*keymap_init)(wmKeyConfig *, const char *);
 
diff --git a/source/blender/windowmanager/intern/widgets/wm_widgetmap.cc b/source/blender/windowmanager/intern/widgets/wm_widgetmap.cc
index 0c5ae8a..d8e16b0 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widgetmap.cc
+++ b/source/blender/windowmanager/intern/widgets/wm_widgetmap.cc
@@ -29,6 +29,8 @@
 
 #include "BKE_context.h"
 
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
 #include "BLI_math.h"
 
 #include "ED_screen.h"
@@ -52,6 +54,13 @@
 #include "wm_widgetmap.h" // own include
 
 
+/**
+ * Hash table of all visible widgets to avoid unnecessary loops and wmWidgetGroupType->poll checks.
+ * Collected in WM_widgets_update, freed in WM_widgets_draw.
+ */
+static GHash *draw_widgets = NULL;
+
+
 wmWidgetMap::wmWidgetMap(const char *idname, const int spaceid, const int regionid, const bool is_3d)
 {
 	wmWidgetMapType *wmaptype = WM_widgetmaptype_find(idname, spaceid, regionid, is_3d, true);
@@ -71,6 +80,191 @@ wmWidgetMap::wmWidgetMap(const char *idname, const int spaceid, const int region
 	}
 }
 
+static void widget_highlight_update(wmWidgetMap *wmap, const wmWidget *old_, wmWidget *new_)
+{
+	new_->flag |= WM_WIDGET_HIGHLIGHT;
+	wmap->wmap_context.highlighted_widget = new_;
+	new_->highlighted_part = old_->highlighted_part;
+}
+
+void wmWidgetMap::update(const bContext *C)
+{
+	wmWidget *widget = wmap_context.active_widget;
+
+	if (!draw_widgets) {
+		draw_widgets = BLI_ghash_str_new(__func__);
+	}
+
+	if (widget) {
+		if ((widget->flag & WM_WIDGET_HIDDEN) == 0) {
+			widget_calculate_scale(widget, C);
+			BLI_ghash_reinsert(draw_widgets, widget->idname, widget, NULL, NULL);
+		}
+	}
+	else if (!BLI_listbase_is_empty(&widgetgroups)) {
+		wmWidget *highlighted = NULL;
+
+		for (wmWidgetGroup *wgroup = (wmWidgetGroup *)widgetgroups.first; wgroup; wgroup = wgroup->next) {
+			if (!wgroup->type_cxx->poll || wgroup->type_cxx->poll(C, wgroup->type_cxx)) {
+				/* first delete and recreate the widgets */
+				for (widget = (wmWidget *)wgroup->widgets.first; widget;) {
+					wmWidget *widget_next = widget->next;
+
+					/* do not delete selected and highlighted widgets,
+					 * keep them to compare with new ones */
+					if (widget->flag & WM_WIDGET_SELECTED) {
+						BLI_remlink(&wgroup->widgets, widget);
+						widget->next = widget->prev = NULL;
+					}
+					else if (widget->flag & WM_WIDGET_HIGHLIGHT) {
+						highlighted = widget;
+						BLI_remlink(&wgroup->widgets, widget);
+						widget->next = widget->prev = NULL;
+					}
+					else {
+						widget_delete(&wgroup->widgets, widget);
+					}
+					widget = widget_next;
+				}
+
+				if (wgroup->type_cxx->create) {
+					wgroup->type_cxx->create(C, wgroup);
+				}
+
+				for (widget = (wmWidget *)wgroup->widgets.first; widget; widget = widget->next) {
+					if (widget->flag & WM_WIDGET_HIDDEN)
+						continue;
+
+					widget_calculate_scale(widget, C);
+					/* insert newly created widget into hash table */
+					BLI_ghash_reinsert(draw_widgets, widget->idname, widget, NULL, NULL);
+				}
+
+				/* *** From now on, draw_widgets hash table can be used! *** */
+
+			}
+		}
+
+		if (highlighted) {
+			wmWidget *highlighted_new = (wmWidget *)BLI_ghash_lookup(draw_widgets, highlighted->idname);
+			if (highlighted_new) {
+				BLI_assert(widget_compare(highlighted, highlighted_new));
+				widget_highlight_update(this, highlighted, highlighted_new);
+				widget_delete(NULL, highlighted);
+			}
+			/* if we didn't find a highlighted widget, delete the old one here */
+			else {
+				MEM_SAFE_FREE(highlighted);
+				wmap_context.highlighted_widget = NULL;
+			}
+		}
+
+		if (wmap_context.selected_widgets) {
+			for (int i = 0; i < wmap_context.tot_selected; i++) {
+				wmWidget *sel_old = wmap_context.selected_widgets[i];
+				wmWidget *sel_new = (wmWidget *)BLI_ghash_lookup(draw_widgets, sel_old->idname);
+
+				/* fails if wgtype->poll state changed */
+				if (!sel_new)
+					continue;
+
+				BLI_assert(widget_compare(sel_old, sel_new));
+
+				/* widget was selected and highlighted */
+				if (sel_old->flag & WM_WIDGET_HIGHLIGHT) {
+					widget_highlight_update(this, sel_old, sel_new);
+				}
+				widget_data_free(sel_old);
+				/* XXX freeing sel_old leads to crashes, hrmpf */
+
+				sel_new->flag |= WM_WIDGET_SELECTED;
+				wmap_context.selected_widgets[i] = sel_new;
+			}
+		}
+	}
+}
+
+/**
+ * Draw all visible widgets in \a wmap.
+ * Uses global draw_widgets hash table.
+ *
+ * \param in_scene  draw depth-culled widgets (wmWidget->flag WM_WIDGET_SCENE_DEPTH) - TODO
+ * \param free_drawwidgets  free global draw_widgets hash table (always enable for last draw call in region!).
+ */
+void wmWidgetMap::draw(const bContext *C, const bool in_scene, const bool free_draw_widgets)
+{
+	const bool draw_multisample = (U.ogl_multisamples != USER_MULTISAMPLE_NONE);
+	const bool use_lighting = (U.tw_flag & V3D_SHADED_WIDGETS) != 0;
+
+	/* enable multisampling */
+	if (draw_multisample) {
+		glEnable(GL_MULTISAMPLE);
+	}
+
+	if (use_lighting) {
+		const float lightpos[4] = {0.0, 0.0, 1.0, 0.0};
+		const float diffuse[4] = {1.0, 1.0, 1.0, 0.0};
+
+		glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT);
+
+		glEnable(GL_LIGHTING);
+		glEnable(GL_LIGHT0);
+		glEnable(GL_COLOR_MATERIAL);
+		glColor

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list