[Bf-blender-cvs] [16e35ba] temp_widgets_c++_experiment: Port over widget select functions

Julian Eisel noreply at git.blender.org
Mon Dec 21 20:27:16 CET 2015


Commit: 16e35ba2eee3a6b220307670514c714663ce725f
Author: Julian Eisel
Date:   Mon Dec 21 20:26:43 2015 +0100
Branches: temp_widgets_c++_experiment
https://developer.blender.org/rB16e35ba2eee3a6b220307670514c714663ce725f

Port over widget select functions

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

M	source/blender/editors/armature/pose_select.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/widgets/wm_widget.cc
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
M	source/blender/windowmanager/wm_event_system.h

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

diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 1331d77..c99d32b 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -370,7 +370,7 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
 	CTX_DATA_END;
 
 	/* handle widget selection */
-	WM_widgetmap_select_all(C, (wmWidgetMapC *)ar->widgetmaps.first, action);
+	WM_widgetmap_select_all((struct wmWidgetMap *)ar->widgetmaps.first, C, action);
 
 	WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, NULL);
 	
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index dc0d4cc..da87884 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -60,8 +60,6 @@ struct wmOperatorType;
 struct wmOperator;
 struct wmWidget;
 struct wmWidgetGroup;
-struct wmWidgetMapC;
-struct wmWidgetMapType;
 struct rcti;
 struct PointerRNA;
 struct PropertyRNA;
@@ -550,8 +548,6 @@ void WM_widget_set_colors(struct wmWidget *widget, const float col[4], const flo
 
 wmKeyMap *WM_widgetgroup_keymap_common(wmKeyConfig *config, const char *wgroupname);
 
-bool WM_widgetmap_select_all(struct bContext *C, struct wmWidgetMapC *wmap, const int action);
-
 /* wm_generic_widgets.c */
 
 enum {
diff --git a/source/blender/windowmanager/intern/widgets/wm_widget.cc b/source/blender/windowmanager/intern/widgets/wm_widget.cc
index d2db13d..45ccbb2 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widget.cc
+++ b/source/blender/windowmanager/intern/widgets/wm_widget.cc
@@ -36,12 +36,14 @@
 #include "DNA_view3d_types.h"
 #include "DNA_windowmanager_types.h"
 
+#include "ED_screen.h"
 #include "ED_view3d.h"
 
 #include "MEM_guardedalloc.h"
 
 #include "WM_api.h"
 
+#include "wm_widgetmap.h"
 #include "wm_widgetgroup.h"
 #include "wm_widget.h" // own include
 
@@ -93,6 +95,68 @@ void widget_find_active_3D_loop(const bContext *C, ListBase *visible_widgets)
 	}
 }
 
+/**
+ * Add \a widget to selection.
+ * Reallocates memory for selected widgets so better not call for selecting multiple ones.
+ */
+void wm_widget_select(wmWidgetMap *wmap, bContext *C, wmWidget *widget)
+{
+	wmWidget ***sel = &wmap->wmap_context.selected_widgets;
+	int *tot_selected = &wmap->wmap_context.tot_selected;
+
+	if (!widget || (widget->flag & WM_WIDGET_SELECTED))
+		return;
+
+	(*tot_selected)++;
+
+	*sel = (wmWidget **)MEM_reallocN(*sel, sizeof(**sel) * (*tot_selected));
+	(*sel)[(*tot_selected) - 1] = widget;
+
+	widget->flag |= WM_WIDGET_SELECTED;
+	if (widget->select) {
+		widget->select(C, widget, SEL_SELECT);
+	}
+	wmap->set_highlighted_widget(C, widget, widget->highlighted_part);
+
+	ED_region_tag_redraw(CTX_wm_region(C));
+}
+
+/**
+ * Remove \a widget from selection.
+ * Reallocates memory for selected widgets so better not call for selecting multiple ones.
+ */
+void wm_widget_deselect(wmWidgetMap *wmap, const bContext *C, wmWidget *widget)
+{
+	wmWidget ***sel = &wmap->wmap_context.selected_widgets;
+	int *tot_selected = &wmap->wmap_context.tot_selected;
+
+	/* caller should check! */
+	BLI_assert(widget->flag & WM_WIDGET_SELECTED);
+
+	/* remove widget from selected_widgets array */
+	for (int i = 0; i < (*tot_selected); i++) {
+		if (widget_compare((*sel)[i], widget)) {
+			for (int j = i; j < ((*tot_selected) - 1); j++) {
+				(*sel)[j] = (*sel)[j + 1];
+			}
+			break;
+		}
+	}
+
+	/* update array data */
+	if ((*tot_selected) <= 1) {
+		MEM_SAFE_FREE(*sel);
+		*tot_selected = 0;
+	}
+	else {
+		*sel = (wmWidget **)MEM_reallocN(*sel, sizeof(**sel) * (*tot_selected));
+		(*tot_selected)--;
+	}
+
+	widget->flag &= ~WM_WIDGET_SELECTED;
+
+	ED_region_tag_redraw(CTX_wm_region(C));
+}
 
 void widget_calculate_scale(wmWidget *widget, const bContext *C)
 {
diff --git a/source/blender/windowmanager/intern/widgets/wm_widgetmap.cc b/source/blender/windowmanager/intern/widgets/wm_widgetmap.cc
index e30fe91..7c0d663 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widgetmap.cc
+++ b/source/blender/windowmanager/intern/widgets/wm_widgetmap.cc
@@ -674,6 +674,98 @@ void wmWidgetMap::set_active_widget(bContext *C, const wmEvent *event, wmWidget
 	}
 }
 
+BLI_INLINE bool widget_selectable_poll(const wmWidget *widget, void *UNUSED(data))
+{
+	return (widget->flag & WM_WIDGET_SELECTABLE);
+}
+
+/**
+ * Select all selectable widgets in \a wmap.
+ * \return if selection has changed.
+ */
+bool wmWidgetMap::select_all_intern(bContext *C, wmWidget ***sel, const int action)
+{
+	/* GHash is used here to avoid having to loop over all widgets twice (once to
+	 * get tot_sel for allocating, once for actually selecting). Instead we collect
+	 * selectable widgets in hash table and use this to get tot_sel and do selection */
+
+	GHash *hash = widget_hash_new(C, widget_selectable_poll, NULL, true);
+	GHashIterator gh_iter;
+	int i, *tot_sel = &wmap_context.tot_selected;
+	bool changed = false;
+
+	*tot_sel = BLI_ghash_size(hash);
+	*sel = (wmWidget **)MEM_reallocN(*sel, sizeof(**sel) * (*tot_sel));
+
+	GHASH_ITER_INDEX (gh_iter, hash, i) {
+		wmWidget *widget_iter = (wmWidget *)BLI_ghashIterator_getValue(&gh_iter);
+
+		if ((widget_iter->flag & WM_WIDGET_SELECTED) == 0) {
+			changed = true;
+		}
+		widget_iter->flag |= WM_WIDGET_SELECTED;
+		if (widget_iter->select) {
+			widget_iter->select(C, widget_iter, action);
+		}
+		(*sel)[i] = widget_iter;
+		BLI_assert(i < (*tot_sel));
+	}
+	/* highlight first widget */
+	set_highlighted_widget(C, (*sel)[0], (*sel)[0]->highlighted_part);
+
+	BLI_ghash_free(hash, NULL, NULL);
+	return changed;
+}
+
+/**
+ * Deselect all selected widgets in \a wmap.
+ * \return if selection has changed.
+ */
+bool wmWidgetMap::deselect_all(wmWidget ***sel)
+{
+	if (*sel == NULL || wmap_context.tot_selected == 0)
+		return false;
+
+	for (int i = 0; i < wmap_context.tot_selected; i++) {
+		(*sel)[i]->flag &= ~WM_WIDGET_SELECTED;
+		(*sel)[i] = NULL;
+	}
+	MEM_SAFE_FREE(*sel);
+	wmap_context.tot_selected = 0;
+
+	/* always return true, we already checked
+	 * if there's anything to deselect */
+	return true;
+}
+
+/**
+ * Select/Deselect all selectable widgets in \a wmap.
+ * \return if selection has changed.
+ *
+ * TODO select all by type
+ */
+bool wmWidgetMap::select_all(bContext *C, const int action)
+{
+	wmWidget ***sel = &wmap_context.selected_widgets;
+	bool changed = false;
+
+	switch (action) {
+		case SEL_SELECT:
+			changed = select_all_intern(C, sel, action);
+			break;
+		case SEL_DESELECT:
+			changed = deselect_all(sel);
+			break;
+		default:
+			BLI_assert(0);
+	}
+
+	if (changed)
+		WM_event_add_mousemove(C);
+
+	return changed;
+}
+
 wmWidgetGroup *wmWidgetMap::get_active_group()
 {
 	return wmap_context.activegroup;
diff --git a/source/blender/windowmanager/intern/widgets/wm_widgetmap.h b/source/blender/windowmanager/intern/widgets/wm_widgetmap.h
index aace831..d1ce010 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widgetmap.h
+++ b/source/blender/windowmanager/intern/widgets/wm_widgetmap.h
@@ -59,15 +59,11 @@ public:
 	void draw(const bContext *C, const bool in_scene, const bool free_draw_widgets);
 
 	bool cursor_update(wmWindow *win);
-	struct GHash *widget_hash_new(
-	        const bContext *C,
-	        bool (*poll)(const wmWidget *, void *),
-	        void *data,
-	        const bool include_hidden);
 
-	void set_highlighted_widget(bContext *C, wmWidget *widget, unsigned char part);
+	void      set_highlighted_widget(bContext *C, wmWidget *widget, unsigned char part);
 	wmWidget *find_highlighted_widget(bContext *C, const wmEvent *event, unsigned char *part);
-	void set_active_widget(bContext *C, const wmEvent *event, wmWidget *widget);
+	void      set_active_widget(bContext *C, const wmEvent *event, wmWidget *widget);
+	bool      select_all(bContext *C, const int action);
 
 	wmWidgetGroup *get_active_group();
 
@@ -90,6 +86,15 @@ public:
 		/* set while widget is highlighted/active */
 		wmWidgetGroup *activegroup = NULL;
 	} wmap_context;
+
+private:
+	struct GHash *widget_hash_new(
+	        const bContext *C,
+	        bool (*poll)(const wmWidget *, void *),
+	        void *data,
+	        const bool include_hidden);
+	bool select_all_intern(bContext *C, wmWidget ***sel, const int action);
+	bool deselect_all(wmWidget ***sel);
 };
 
 #endif // __WM_WIDGETMAP_H__
diff --git a/source/blender/windowmanager/intern/widgets/wm_widgets_c_api.cc b/source/blender/windowmanager/intern/widgets/wm_widgets_c_api.cc
index 4c734b7..c5b506a 100644
--- a/source/blender/windowmanager/intern/widgets/wm_widgets_c_api.cc
+++ b/source/blender/windowmanager/intern/widgets/wm_widgets_c_api.cc
@@ -65,14 +65,6 @@ bool WM_widgetmap_cursor_set(wmWidgetMap *wmap, wmWindow *win)
 	return wmap->cursor_update(win);
 }
 
-GHash *wm_widgetmap_widget_hash_new(
-        const bContext *C, wmWidgetMap *wmap,
-        bool (*poll)(const wmWidget *, void *),
-        void *data, const bool include_hidden)
-{
-	return wmap->widget_hash_new(C, poll, data, include_hidden);
-}
-
 void wm_widgetmap_highlighted_widget_set(bContext *C, wmWidgetMap *wmap, wmWidget *widget, unsigned char part)
 {
 	wmap->set_highlighted_widget(C, widget, part);
@@ -81,6 +73,12 @@ wmWidget *wm_widgetmap_highlighted_widget_get(wmWidgetMap *wmap)
 {
 	return wmap->wmap_context.highlighted_widget;
 }
+wmWidget *wm_widgetmap_highlighted_widget_find(
+        wmWidgetMap *wmap, bContext *C, const wmEvent *event,
+        unsigned char *part)
+{
+	return wmap->find_highlighted_widget(C, event, part);
+}
 
 void wm_widgetmap_active_widget_set(wmWidgetMap *wmap, bContext *C, const wmEvent *event, wmWidget *widget)
 {
@@ -91,12 +89,9 @@ wmWidget *wm_widgetmap_active_widget_get(wmWidgetMap *wmap)
 	return wmap->wmap_context.active_widget;
 }
 
-
-wmWidget *wm_widgetmap_highlighted_widget_find(
-        wmWidgetMap *wmap, bContext *C, const wmEvent *event,
-        unsigned char *part)
+bool WM_widgetmap_select_all(wmWidgetMap *wmap, bContext *C, const int action)
 {
-	return wmap->find_highlighted_widget(C, event, part);
+	return wmap->select_all(C, action);
 }
 
 wmWidgetGroup *wm_widgetmap_active_group_get(wmWidgetMap *wmap)
diff --git a/source/blender/wi

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list