[Bf-blender-cvs] [733afd1] wiggly-widgets: Add more (face map) widget selection methods (shift+select, etc)
Julian Eisel
noreply at git.blender.org
Fri Nov 27 22:17:42 CET 2015
Commit: 733afd16d709113fd29c71e8a74c862ae78de682
Author: Julian Eisel
Date: Fri Nov 27 22:11:45 2015 +0100
Branches: wiggly-widgets
https://developer.blender.org/rB733afd16d709113fd29c71e8a74c862ae78de682
Add more (face map) widget selection methods (shift+select, etc)
Adds support for extending, deselecting and toggling widget selection, whereby only toggling has a default shortcut (shift+Selectmouse, just like everywhere).
Also naming cleanup.
===================================================================
M source/blender/windowmanager/intern/wm_operators.c
M source/blender/windowmanager/intern/wm_widgets.c
M source/blender/windowmanager/wm.h
M source/blender/windowmanager/wm_event_system.h
===================================================================
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 08ff5cc..006b570 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -5331,7 +5331,7 @@ void wm_operatortype_init(void)
/* widgets */
WM_operatortype_append(WIDGETGROUP_OT_widget_set_active);
- WM_operatortype_append(WIDGETGROUP_OT_widget_set_select);
+ WM_operatortype_append(WIDGETGROUP_OT_widget_select);
WM_operatortype_append(WIDGETGROUP_OT_widget_tweak);
WM_operatortype_append(WIDGETGROUP_OT_widget_tweak_cancel);
}
diff --git a/source/blender/windowmanager/intern/wm_widgets.c b/source/blender/windowmanager/intern/wm_widgets.c
index a67d4fb..25017c8 100644
--- a/source/blender/windowmanager/intern/wm_widgets.c
+++ b/source/blender/windowmanager/intern/wm_widgets.c
@@ -702,18 +702,193 @@ void WIDGETGROUP_OT_widget_set_active(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "deactivate", 0, "Deactivate", "Deactivate currently active widget");
}
-static int widget_set_select_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
+/**
+ * Deselect all selected widgets in \a wmap.
+ * \return if selection has changed.
+ */
+static bool wm_widgetmap_deselect_all(wmWidgetMap *wmap, wmWidget ***sel)
+{
+ if (*sel == NULL || wmap->wmap_context.tot_selected == 0)
+ return false;
+
+ for (int i = 0; i < wmap->wmap_context.tot_selected; i++) {
+ (*sel)[i]->flag &= ~WM_WIDGET_SELECTED;
+ (*sel)[i] = NULL;
+ }
+ MEM_SAFE_FREE(*sel);
+ wmap->wmap_context.tot_selected = 0;
+
+ /* always return true, we already checked
+ * if there's anything to deselect */
+ return true;
+}
+
+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.
+ */
+static bool wm_widgetmap_select_all_intern(bContext *C, wmWidgetMap *wmap, 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 = wm_widgetmap_widget_hash_new(C, wmap, widget_selectable_poll, NULL, true);
+ GHashIterator gh_iter;
+ int i, *tot_sel = &wmap->wmap_context.tot_selected;
+ bool changed = false;
+
+ *tot_sel = BLI_ghash_size(hash);
+ *sel = MEM_reallocN(*sel, sizeof(**sel) * (*tot_sel));
+
+ GHASH_ITER_INDEX (gh_iter, hash, i) {
+ wmWidget *widget_iter = 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 */
+ wm_widgetmap_set_highlighted_widget(wmap, C, (*sel)[0], (*sel)[0]->highlighted_part);
+
+ BLI_ghash_free(hash, NULL, NULL);
+ return changed;
+}
+
+/**
+ * Select/Deselect all selectable widgets in \a wmap.
+ * \return if selection has changed.
+ *
+ * TODO select all by type
+ */
+bool WM_widgetmap_select_all(bContext *C, wmWidgetMap *wmap, const int action)
+{
+ wmWidget ***sel = &wmap->wmap_context.selected_widgets;
+ bool changed = false;
+
+ switch (action) {
+ case SEL_SELECT:
+ changed = wm_widgetmap_select_all_intern(C, wmap, sel, action);
+ break;
+ case SEL_DESELECT:
+ changed = wm_widgetmap_deselect_all(wmap, sel);
+ break;
+ default:
+ BLI_assert(0);
+ }
+
+ return changed;
+}
+
+/**
+ * Remove \a widget from selection
+ * Re-allocates memory for selected widgets so better not call for selecting multiple ones.
+ */
+static void wm_widget_deselect(const bContext *C, wmWidgetMap *wmap, 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];
+ }
+ }
+ }
+
+ /* update array data */
+ if ((*tot_selected) <= 1) {
+ MEM_SAFE_FREE(*sel);
+ *tot_selected = 0;
+ }
+ else {
+ *sel = MEM_reallocN(*sel, sizeof(**sel) * (*tot_selected));
+ (*tot_selected)--;
+ }
+
+ widget->flag &= ~WM_WIDGET_SELECTED;
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+}
+
+/**
+ * Add \a widget to selection
+ * Reallocate memory for selected widgets so better not call for selecting multiple ones.
+ */
+void wm_widget_select(bContext *C, wmWidgetMap *wmap, 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 = 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);
+ }
+ wm_widgetmap_set_highlighted_widget(wmap, C, widget, widget->highlighted_part);
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+}
+
+static int widget_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
ARegion *ar = CTX_wm_region(C);
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool deselect = RNA_boolean_get(op->ptr, "deselect");
+ bool toggle = RNA_boolean_get(op->ptr, "toggle");
+
+
for (wmWidgetMap *wmap = ar->widgetmaps.first; wmap; wmap = wmap->next) {
- wmWidget *widget = wmap->wmap_context.highlighted_widget;
- if (widget) {
- if (widget->flag & WM_WIDGET_SELECTABLE) {
- wm_widgetmap_select_widget(C, wmap, widget);
- return OPERATOR_FINISHED;
+ wmWidget ***sel = &wmap->wmap_context.selected_widgets;
+ wmWidget *highlighted = wmap->wmap_context.highlighted_widget;
+
+ /* deselect all first */
+ if (extend == false && deselect == false && toggle == false) {
+ wm_widgetmap_deselect_all(wmap, sel);
+ BLI_assert(*sel == NULL && wmap->wmap_context.tot_selected == 0);
+ }
+
+ if (highlighted) {
+ const bool is_selected = (highlighted->flag & WM_WIDGET_SELECTED);
+
+ if (toggle) {
+ /* toggle: deselect if already selected, else select */
+ deselect = is_selected;
}
- break;
+
+ if (deselect) {
+ if (is_selected)
+ wm_widget_deselect(C, wmap, highlighted);
+ }
+ else {
+ wm_widget_select(C, wmap, highlighted);
+ }
+
+ return OPERATOR_FINISHED;
}
else {
BLI_assert(0);
@@ -724,20 +899,19 @@ static int widget_set_select_invoke(bContext *C, wmOperator *UNUSED(op), const w
return OPERATOR_PASS_THROUGH;
}
-void WIDGETGROUP_OT_widget_set_select(wmOperatorType *ot)
+void WIDGETGROUP_OT_widget_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Widget Select";
ot->description = "Select the currently highlighted widget";
- ot->idname = "WIDGETGROUP_OT_widget_set_select";
+ ot->idname = "WIDGETGROUP_OT_widget_select";
/* api callbacks */
- ot->invoke = widget_set_select_invoke;
+ ot->invoke = widget_select_invoke;
ot->flag = OPTYPE_UNDO;
- /* TODO - more fancy selections are not implemented yet */
-// RNA_def_boolean(ot->srna, "deactivate", 0, "Deactivate", "Deactivate currently active widget");
+ WM_operator_properties_mouse_select(ot);
}
static int widget_tweak_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
@@ -1118,120 +1292,6 @@ void wm_widgetmap_set_active_widget(
}
}
-/**
- * Deselect all selected widgets in \a wmap.
- * \return if selection has changed.
- */
-static bool wm_widgetmap_deselect_all(wmWidgetMap *wmap, wmWidget ***sel)
-{
- if (*sel == NULL || wmap->wmap_context.tot_selected == 0)
- return false;
-
- for (int i = 0; i < wmap->wmap_context.tot_selected; i++) {
- (*sel)[i]->flag &= ~WM_WIDGET_SELECTED;
- (*sel)[i] = NULL;
- }
- MEM_SAFE_FREE(*sel);
- wmap->wmap_context.tot_selected = 0;
-
- /* always return true, we already checked
- * if there's anything to deselect */
- return true;
-}
-
-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.
- */
-static bool wm_widgetmap_select_all_intern(bContext *C, wmWidgetMap *wmap, 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 = wm_widgetmap_widget_hash_new(C, wmap, widget_selectable_poll, NULL, true);
- GHashIterator gh_iter;
- int i, *tot_sel = &wmap->wmap_context.tot_selected;
- bool changed = false;
-
- *tot_sel = BLI_ghash_size(hash);
- *sel = MEM_reallocN(*sel, sizeof(**sel) * (*tot_sel));
-
- GHASH_ITER_INDEX (gh_iter, hash, i) {
- wmWidget *widget_iter = 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 */
- wm_widgetmap_set_highlighted_widget(wmap, C, (*sel)[0], (*sel)[0]->highlighted_part);
-
- BLI_ghash_free(hash, NULL, NULL);
- return changed;
-}
-
-/**
- * Select/Deselect all selectable widgets in \a wmap.
- * \return if selection has changed.
- *
- * TODO select all by type
- */
-bool WM_widgetmap_select_all(bContext *C, wmWidgetMap *wmap, const int action)
-{
- wmWidget ***sel = &wmap->wmap_context.selected_widgets;
- bool changed = false;
-
- switch (action) {
- case SEL_SELECT:
- changed = wm_widgetmap_select_all_intern(C, wmap, sel, action);
- break;
- case SEL_DESELECT:
- changed = wm
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list