[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