Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_widgets.c')
-rw-r--r--source/blender/windowmanager/intern/wm_widgets.c566
1 files changed, 396 insertions, 170 deletions
diff --git a/source/blender/windowmanager/intern/wm_widgets.c b/source/blender/windowmanager/intern/wm_widgets.c
index b32fa7b78e0..613d20c14f8 100644
--- a/source/blender/windowmanager/intern/wm_widgets.c
+++ b/source/blender/windowmanager/intern/wm_widgets.c
@@ -15,8 +15,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * The Original Code is Copyright (C) 2007 Blender Foundation but based
- * on ghostwinlay.c (C) 2001-2002 by NaN Holding BV
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation, 2008
@@ -70,6 +69,7 @@
#include "GPU_select.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "BPY_extern.h"
/**
@@ -101,60 +101,73 @@ static ListBase widgetmaptypes = {NULL, NULL};
wmWidgetGroupType *WM_widgetgrouptype_new(
int (*poll)(const bContext *C, wmWidgetGroupType *),
void (*create)(const bContext *, wmWidgetGroup *),
- const Main *bmain, const char *mapidname,
+ wmKeyMap *(*keymap_init)(wmKeyConfig *, const char *),
+ const Main *bmain, const char *mapidname, const char *name,
const short spaceid, const short regionid, const bool is_3d)
{
- bScreen *sc;
wmWidgetMapType *wmaptype = WM_widgetmaptype_find(mapidname, spaceid, regionid, is_3d, false);
wmWidgetGroupType *wgrouptype;
-
+ bScreen *sc;
+
if (!wmaptype) {
fprintf(stderr, "widgetgrouptype creation: widgetmap type does not exist");
return NULL;
}
-
+
wgrouptype = MEM_callocN(sizeof(wmWidgetGroupType), "widgetgroup");
-
+
wgrouptype->poll = poll;
wgrouptype->create = create;
+ wgrouptype->keymap_init = keymap_init;
wgrouptype->spaceid = spaceid;
wgrouptype->regionid = regionid;
wgrouptype->is_3d = is_3d;
- BLI_strncpy(wgrouptype->mapidname, mapidname, 64);
+ BLI_strncpy(wgrouptype->name, name, MAX_NAME);
+ BLI_strncpy(wgrouptype->mapidname, mapidname, MAX_NAME);
/* add the type for future created areas of the same type */
BLI_addtail(&wmaptype->widgetgrouptypes, wgrouptype);
-
- /* now create a widget for all existing areas. (main is missing when we create new areas so not needed) */
- if (bmain) {
- for (sc = bmain->screen.first; sc; sc = sc->id.next) {
- ScrArea *sa;
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
-
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
- ARegion *ar;
- ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
-
- for (ar = lb->first; ar; ar = ar->next) {
- wmWidgetMap *wmap;
- for (wmap = ar->widgetmaps.first; wmap; wmap = wmap->next) {
- if (wmap->type == wmaptype) {
- wmWidgetGroup *wgroup = MEM_callocN(sizeof(wmWidgetGroup), "widgetgroup");
- wgroup->type = wgrouptype;
-
- /* just add here, drawing will occur on next update */
- BLI_addtail(&wmap->widgetgroups, wgroup);
- wm_widgetmap_set_highlighted_widget(wmap, NULL, NULL, 0);
- ED_region_tag_redraw(ar);
- }
+
+ /* Main is missing on startup when we create new areas.
+ * So this is only called for widgets initialized on runtime */
+ if (!bmain)
+ return wgrouptype;
+
+
+ /* init keymap - on startup there's an extra call to init keymaps for 'permanent' widget-groups */
+ wm_widgetgrouptype_keymap_init(wgrouptype, ((wmWindowManager *)bmain->wm.first)->defaultconf);
+
+ /* now create a widget for all existing areas */
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ ARegion *ar;
+ ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
+
+ for (ar = lb->first; ar; ar = ar->next) {
+ wmWidgetMap *wmap;
+
+ for (wmap = ar->widgetmaps.first; wmap; wmap = wmap->next) {
+ if (wmap->type == wmaptype) {
+ wmWidgetGroup *wgroup = MEM_callocN(sizeof(wmWidgetGroup), "widgetgroup");
+
+ wgroup->type = wgrouptype;
+
+ /* just add here, drawing will occur on next update */
+ BLI_addtail(&wmap->widgetgroups, wgroup);
+ wm_widgetmap_set_highlighted_widget(wmap, NULL, NULL, 0);
+ ED_region_tag_redraw(ar);
}
}
}
}
}
}
-
+
return wgrouptype;
}
@@ -164,9 +177,9 @@ wmWidget *WM_widget_new(void (*draw)(const bContext *C, wmWidget *customdata),
int (*handler)(bContext *C, const wmEvent *event, wmWidget *widget))
{
wmWidget *widget;
-
+
widget = MEM_callocN(sizeof(wmWidget), "widget");
-
+
widget->draw = draw;
widget->handler = handler;
widget->intersect = intersect;
@@ -175,50 +188,6 @@ wmWidget *WM_widget_new(void (*draw)(const bContext *C, wmWidget *customdata),
return widget;
}
-void WM_widget_property(wmWidget *widget, const int slot, PointerRNA *ptr, const char *propname)
-{
- if (slot < 0 || slot >= widget->max_prop) {
- fprintf(stderr, "invalid index %d when binding property for widget type %s\n", slot, widget->idname);
- return;
- }
-
- /* if widget evokes an operator we cannot use it for property manipulation */
- widget->opname = NULL;
- widget->ptr[slot] = *ptr;
- widget->props[slot] = RNA_struct_find_property(ptr, propname);
-
- if (widget->bind_to_prop)
- widget->bind_to_prop(widget, slot);
-}
-
-PointerRNA *WM_widget_operator(wmWidget *widget, const char *opname)
-{
- wmOperatorType *ot = WM_operatortype_find(opname, 0);
-
- if (ot) {
- widget->opname = opname;
-
- WM_operator_properties_create_ptr(&widget->opptr, ot);
-
- return &widget->opptr;
- }
- else {
- fprintf(stderr, "Error binding operator to widget: operator %s not found!\n", opname);
- }
-
- return NULL;
-}
-
-void WM_widgetgroup_customdata_set(wmWidgetGroup *wgroup, void *data)
-{
- wgroup->customdata = data;
-}
-
-void *WM_widgetgroup_customdata(const wmWidgetGroup *wgroup)
-{
- return wgroup->customdata;
-}
-
static void wm_widget_delete(ListBase *widgetlist, wmWidget *widget)
{
@@ -228,7 +197,7 @@ static void wm_widget_delete(ListBase *widgetlist, wmWidget *widget)
MEM_freeN(widget->props);
MEM_freeN(widget->ptr);
-
+
BLI_freelinkN(widgetlist, widget);
}
@@ -239,8 +208,6 @@ static void widget_calculate_scale(wmWidget *widget, const bContext *C)
float scale = 1.0f;
if (rv3d && (U.tw_flag & V3D_3D_WIDGETS) == 0 && (widget->flag & WM_WIDGET_SCALE_3D)) {
- ED_view3d_update_viewmat(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), NULL, NULL);
-
if (widget->get_final_position) {
float position[3];
@@ -255,7 +222,22 @@ static void widget_calculate_scale(wmWidget *widget, const bContext *C)
widget->scale = scale * widget->user_scale;
}
-static bool widgets_compare(const wmWidget *a, const wmWidget *b)
+/**
+ * Initialize keymaps for all existing widget-groups
+ */
+void wm_widgets_keymap(wmKeyConfig *keyconf)
+{
+ wmWidgetMapType *wmaptype;
+ wmWidgetGroupType *wgrouptype;
+
+ for (wmaptype = widgetmaptypes.first; wmaptype; wmaptype = wmaptype->next) {
+ for (wgrouptype = wmaptype->widgetgrouptypes.first; wgrouptype; wgrouptype = wgrouptype->next) {
+ wm_widgetgrouptype_keymap_init(wgrouptype, keyconf);
+ }
+ }
+}
+
+BLI_INLINE bool widgets_compare(const wmWidget *a, const wmWidget *b)
{
return STREQ(a->idname, b->idname);
}
@@ -276,16 +258,18 @@ void WM_widgets_update(const bContext *C, wmWidgetMap *wmap)
wmWidgetGroup *wgroup;
for (wgroup = wmap->widgetgroups.first; wgroup; wgroup = wgroup->next) {
- if (!wgroup->type->poll || wgroup->type->poll(C, wgroup->type))
- {
+ if (!wgroup->type->poll || wgroup->type->poll(C, wgroup->type)) {
wmWidget *highlighted = NULL;
/* first delete and recreate the widgets */
for (widget = wgroup->widgets.first; widget;) {
wmWidget *widget_next = widget->next;
+ if (widget == wmap->selected_widget) {
+ /* skip */
+ }
/* do not delete the highlighted widget, instead keep it to compare with the new one */
- if (widget->flag & WM_WIDGET_HIGHLIGHT) {
+ else if (widget->flag & WM_WIDGET_HIGHLIGHT) {
highlighted = widget;
BLI_remlink(&wgroup->widgets, widget);
widget->next = widget->prev = NULL;
@@ -356,17 +340,18 @@ void WM_widgets_draw(const bContext *C, const wmWidgetMap *wmap, const bool in_s
widget = wmap->active_widget;
- if (widget && in_scene == ((widget->flag & WM_WIDGET_SCENE_DEPTH)!= 0)) {
- /* notice that we don't update the widgetgroup, widget is now on its own, it should have all
- * relevant data to update itself */
- widget->draw(C, widget);
+ if (widget && in_scene == ((widget->flag & WM_WIDGET_SCENE_DEPTH) != 0)) {
+ if (widget->flag & WM_WIDGET_DRAW_ACTIVE) {
+ /* notice that we don't update the widgetgroup, widget is now on
+ * its own, it should have all relevant data to update itself */
+ widget->draw(C, widget);
+ }
}
else if (wmap->widgetgroups.first) {
wmWidgetGroup *wgroup;
-
+
for (wgroup = wmap->widgetgroups.first; wgroup; wgroup = wgroup->next) {
- if (!wgroup->type->poll || wgroup->type->poll(C, wgroup->type))
- {
+ if (!wgroup->type->poll || wgroup->type->poll(C, wgroup->type)) {
for (widget = wgroup->widgets.first; widget; widget = widget->next) {
if ((widget->flag & WM_WIDGET_HIDDEN) == 0 &&
(!(widget->flag & WM_WIDGET_DRAW_HOVER) || (widget->flag & WM_WIDGET_HIGHLIGHT)) &&
@@ -379,6 +364,13 @@ void WM_widgets_draw(const bContext *C, const wmWidgetMap *wmap, const bool in_s
}
}
+ /* draw selected widgets last */
+ if ((widget = wmap->selected_widget) && in_scene == ((widget->flag & WM_WIDGET_SCENE_DEPTH) != 0)) {
+ /* notice that we don't update the widgetgroup, widget is now on
+ * its own, it should have all relevant data to update itself */
+ widget->draw(C, widget);
+ }
+
if (use_lighting)
glPopAttrib();
}
@@ -387,10 +379,10 @@ void WM_event_add_area_widgetmap_handlers(ARegion *ar)
{
wmWidgetMap *wmap;
wmEventHandler *handler;
-
+
for (wmap = ar->widgetmaps.first; wmap; wmap = wmap->next) {
handler = MEM_callocN(sizeof(wmEventHandler), "widget handler");
-
+
handler->widgetmap = wmap;
BLI_addtail(&ar->handlers, handler);
}
@@ -411,7 +403,7 @@ void WM_modal_handler_attach_widgetgroup(
wmWidgetMap *wmap;
for (wmap = handler->op_region->widgetmaps.first; wmap; wmap = wmap->next) {
wmWidgetMapType *wmaptype = wmap->type;
-
+
if (wmaptype->spaceid == wgrouptype->spaceid && wmaptype->regionid == wgrouptype->regionid) {
handler->widgetmap = wmap;
}
@@ -435,6 +427,21 @@ static void widget_unique_idname_set(wmWidgetGroup *wgroup, wmWidget *widget, co
}
/**
+ * Search for an active widget in region \a ar
+ */
+static wmWidget *widget_find_active_in_region(const ARegion *ar, wmWidgetMap **r_wmap)
+{
+ for (*r_wmap = ar->widgetmaps.first; *r_wmap; *r_wmap = (*r_wmap)->next) {
+ if ((*r_wmap)->active_widget) {
+ return (*r_wmap)->active_widget;
+ }
+ }
+
+ *r_wmap = NULL;
+ return NULL;
+}
+
+/**
* Register \a widget
*
* \param name name used to create a unique idname for \a widget in \a wgroup
@@ -456,60 +463,70 @@ bool wm_widget_register(wmWidgetGroup *wgroup, wmWidget *widget, const char *nam
if (widget->max_prop == 0) {
widget->max_prop = 1;
}
-
+
widget->props = MEM_callocN(sizeof(PropertyRNA *) * widget->max_prop, "widget->props");
widget->ptr = MEM_callocN(sizeof(PointerRNA) * widget->max_prop, "widget->ptr");
-
+
+ widget->wgroup = wgroup;
+
BLI_addtail(&wgroup->widgets, widget);
return true;
}
-void WM_widget_set_origin(wmWidget *widget, const float origin[3])
+void WM_widget_set_property(wmWidget *widget, const int slot, PointerRNA *ptr, const char *propname)
{
- copy_v3_v3(widget->origin, origin);
+ if (slot < 0 || slot >= widget->max_prop) {
+ fprintf(stderr, "invalid index %d when binding property for widget type %s\n", slot, widget->idname);
+ return;
+ }
+
+ /* if widget evokes an operator we cannot use it for property manipulation */
+ widget->opname = NULL;
+ widget->ptr[slot] = *ptr;
+ widget->props[slot] = RNA_struct_find_property(ptr, propname);
+
+ if (widget->bind_to_prop)
+ widget->bind_to_prop(widget, slot);
}
-void WM_widget_set_3d_scale(wmWidget *widget, const bool scale)
+PointerRNA *WM_widget_set_operator(wmWidget *widget, const char *opname)
{
- if (scale) {
- widget->flag |= WM_WIDGET_SCALE_3D;
+ wmOperatorType *ot = WM_operatortype_find(opname, 0);
+
+ if (ot) {
+ widget->opname = opname;
+
+ WM_operator_properties_create_ptr(&widget->opptr, ot);
+
+ return &widget->opptr;
}
else {
- widget->flag &= ~WM_WIDGET_SCALE_3D;
+ fprintf(stderr, "Error binding operator to widget: operator %s not found!\n", opname);
}
+
+ return NULL;
}
-void WM_widget_flag_set(wmWidget *widget, const int flag, const bool enable)
+void WM_widget_set_origin(wmWidget *widget, const float origin[3])
{
- if (enable) {
- widget->flag |= flag;
- }
- else {
- widget->flag &= ~flag;
- }
+ copy_v3_v3(widget->origin, origin);
}
-void WM_widget_set_draw_on_hover_only(wmWidget *widget, const bool draw)
+void WM_widget_set_offset(wmWidget *widget, const float offset[3])
{
- if (draw) {
- widget->flag |= WM_WIDGET_DRAW_HOVER;
- }
- else {
- widget->flag &= ~WM_WIDGET_DRAW_HOVER;
- }
+ copy_v3_v3(widget->offset, offset);
}
-void WM_widget_set_scene_depth(wmWidget *widget, const bool scene)
+void WM_widget_set_flag(wmWidget *widget, const int flag, const bool enable)
{
- if (scene) {
- widget->flag |= WM_WIDGET_SCENE_DEPTH;
+ if (enable) {
+ widget->flag |= flag;
}
else {
- widget->flag &= ~WM_WIDGET_SCENE_DEPTH;
+ widget->flag &= ~flag;
}
}
-
void WM_widget_set_scale(wmWidget *widget, const float scale)
{
widget->user_scale = scale;
@@ -524,7 +541,7 @@ void WM_widget_set_line_width(wmWidget *widget, const float line_width)
* Set widget rgba colors
*
* \param col Normal state color
- * \param col_hi Highlighted state color
+ * \param col_hi Highlighted state color
*/
void WM_widget_set_colors(wmWidget *widget, const float col[4], const float col_hi[4])
{
@@ -533,14 +550,173 @@ void WM_widget_set_colors(wmWidget *widget, const float col[4], const float col_
}
+/** \name Widget operators
+ *
+ * Basic operators for widget interaction with user configurable keymaps.
+ *
+ * \{ */
+
+static int widget_set_active_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ wmWidgetMap *wmap;
+ const bool deactivate = RNA_boolean_get(op->ptr, "deactivate");
+
+ for (wmap = ar->widgetmaps.first; wmap; wmap = wmap->next) {
+ if (deactivate) {
+ wm_widgetmap_set_active_widget(wmap, C, event, NULL);
+
+ /* ugly hack - send widget release event */
+ ((wmEvent *)event)->type = EVT_WIDGET_RELEASED;
+ }
+ else {
+ wmWidget *widget = wmap->highlighted_widget;
+ if (widget) {
+ wm_widgetmap_set_active_widget(wmap, C, event, widget);
+ break;
+ }
+ else {
+ BLI_assert(0);
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void WIDGETGROUP_OT_widget_set_active(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Widget Activate";
+ ot->description = "Activate the currently highlighted widget";
+ ot->idname = "WIDGETGROUP_OT_widget_set_active";
+
+ /* api callbacks */
+ ot->invoke = widget_set_active_invoke;
+
+ ot->flag = OPTYPE_UNDO;
+
+ 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))
+{
+ ARegion *ar = CTX_wm_region(C);
+ wmWidgetMap *wmap;
+
+ for (wmap = ar->widgetmaps.first; wmap; wmap = wmap->next) {
+ wmWidget *widget = wmap->highlighted_widget;
+ if (widget) {
+ if (widget->flag & WM_WIDGET_SELECTABLE) {
+ wm_widgetmap_set_selected_widget(C, wmap, widget);
+ }
+ break;
+ }
+ else {
+ BLI_assert(0);
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void WIDGETGROUP_OT_widget_set_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Widget Select";
+ ot->description = "Select the currently highlighted widget";
+ ot->idname = "WIDGETGROUP_OT_widget_set_select";
+
+ /* api callbacks */
+ ot->invoke = widget_set_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");
+}
+
+static int widget_tweak_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ wmWidgetMap *wmap;
+ wmWidget *widget = widget_find_active_in_region(ar, &wmap);
+
+ if (!widget) {
+ BLI_assert(0);
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ /* handle widget */
+ widget->handler(C, event, widget);
+
+ /* ugly hack - send widget update event */
+ ((wmEvent *)event)->type = EVT_WIDGET_UPDATE;
+
+ return OPERATOR_FINISHED;
+}
+
+void WIDGETGROUP_OT_widget_tweak(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Widget Tweak";
+ ot->description = "Tweak the active widget";
+ ot->idname = "WIDGETGROUP_OT_widget_tweak";
+
+ /* api callbacks */
+ ot->invoke = widget_tweak_invoke;
+}
+
+static int widget_cancel_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ wmWidgetMap *wmap;
+ wmWidget *widget = widget_find_active_in_region(ar, &wmap);
+
+ if (!widget) {
+ /* don't assert(0) here, this might be called if modal handler
+ * which has widget attached uses same shortcut as widget-cancel */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ if (widget->cancel) {
+ widget->cancel(C, widget);
+ }
+ wm_widgetmap_set_active_widget(wmap, C, event, NULL);
+
+ /* ugly hack - send widget release event */
+ ((wmEvent *)event)->type = EVT_WIDGET_RELEASED;
+
+ return OPERATOR_FINISHED;
+}
+
+void WIDGETGROUP_OT_widget_tweak_cancel(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Widget Tweak Cancel";
+ ot->description = "Cancel tweaking of active widget";
+ ot->idname = "WIDGETGROUP_OT_widget_tweak_cancel";
+
+ /* api callbacks */
+ ot->invoke = widget_cancel_invoke;
+}
+
+/** \} */ // Widget operators
+
+
wmWidgetMapType *WM_widgetmaptype_find(
const char *idname, const int spaceid, const int regionid, const bool is_3d, const bool create)
{
wmWidgetMapType *wmaptype;
for (wmaptype = widgetmaptypes.first; wmaptype; wmaptype = wmaptype->next) {
- if (wmaptype->spaceid == spaceid && wmaptype->regionid == regionid && wmaptype->is_3d == is_3d
- && strcmp(wmaptype->idname, idname) == 0) {
+ if (wmaptype->spaceid == spaceid &&
+ wmaptype->regionid == regionid &&
+ wmaptype->is_3d == is_3d &&
+ STREQ(wmaptype->idname, idname))
+ {
return wmaptype;
}
}
@@ -553,14 +729,14 @@ wmWidgetMapType *WM_widgetmaptype_find(
wmaptype->is_3d = is_3d;
BLI_strncpy(wmaptype->idname, idname, 64);
BLI_addhead(&widgetmaptypes, wmaptype);
-
+
return wmaptype;
}
void WM_widgetmaptypes_free(void)
{
wmWidgetMapType *wmaptype;
-
+
for (wmaptype = widgetmaptypes.first; wmaptype; wmaptype = wmaptype->next) {
BLI_freelistN(&wmaptype->widgetgrouptypes);
}
@@ -602,38 +778,38 @@ static int wm_widget_find_highlighted_3D_intern(
const bool do_passes = GPU_select_query_check_active();
extern void view3d_winmatrix_set(ARegion *ar, View3D *v3d, rctf *rect);
-
+
+
rect.xmin = event->mval[0] - hotspot;
rect.xmax = event->mval[0] + hotspot;
rect.ymin = event->mval[1] - hotspot;
rect.ymax = event->mval[1] + hotspot;
-
+
selrect = rect;
-
+
view3d_winmatrix_set(ar, v3d, &rect);
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
-
+
if (do_passes)
GPU_select_begin(buffer, 64, &selrect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
else
GPU_select_begin(buffer, 64, &selrect, GPU_SELECT_ALL, 0);
/* do the drawing */
widget_find_active_3D_loop(C, visible_widgets);
-
+
hits = GPU_select_end();
-
+
if (do_passes) {
GPU_select_begin(buffer, 64, &selrect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
widget_find_active_3D_loop(C, visible_widgets);
GPU_select_end();
}
-
+
view3d_winmatrix_set(ar, v3d, NULL);
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
if (hits == 1) {
return buffer[3];
-
}
/* find the widget the value belongs to */
else if (hits > 1) {
@@ -655,6 +831,7 @@ static int wm_widget_find_highlighted_3D_intern(
return minval;
}
+
return -1;
}
@@ -686,24 +863,24 @@ wmWidget *wm_widget_find_highlighted_3D(wmWidgetMap *wmap, bContext *C, const wm
*part = 0;
/* set up view matrices */
view3d_operator_needs_opengl(C);
-
+
ret = wm_widget_find_highlighted_3D_intern(&visible_widgets, C, event, 0.5f * hotspot);
-
+
if (ret != -1) {
LinkData *link;
int retsec;
retsec = wm_widget_find_highlighted_3D_intern(&visible_widgets, C, event, 0.2f * hotspot);
-
+
if (retsec != -1)
ret = retsec;
-
+
link = BLI_findlink(&visible_widgets, ret >> 8);
*part = ret & 255;
result = link->data;
}
BLI_freelistN(&visible_widgets);
-
+
return result;
}
@@ -735,7 +912,7 @@ bool WM_widgetmap_cursor_set(const wmWidgetMap *wmap, wmWindow *win)
return true;
}
}
-
+
return false;
}
@@ -746,23 +923,27 @@ void wm_widgetmap_set_highlighted_widget(wmWidgetMap *wmap, bContext *C, wmWidge
wmap->highlighted_widget->flag &= ~WM_WIDGET_HIGHLIGHT;
wmap->highlighted_widget->highlighted_part = 0;
}
-
+
wmap->highlighted_widget = widget;
-
+
if (widget) {
widget->flag |= WM_WIDGET_HIGHLIGHT;
widget->highlighted_part = part;
-
+ wmap->activegroup = widget->wgroup;
+
if (C && widget->get_cursor) {
wmWindow *win = CTX_wm_window(C);
WM_cursor_set(win, widget->get_cursor(widget));
}
}
- else if (C) {
- wmWindow *win = CTX_wm_window(C);
- WM_cursor_set(win, CURSOR_STD);
+ else {
+ wmap->activegroup = NULL;
+ if (C) {
+ wmWindow *win = CTX_wm_window(C);
+ WM_cursor_set(win, CURSOR_STD);
+ }
}
-
+
/* tag the region for redraw */
if (C) {
ARegion *ar = CTX_wm_region(C);
@@ -778,35 +959,23 @@ wmWidget *wm_widgetmap_get_highlighted_widget(wmWidgetMap *wmap)
void wm_widgetmap_set_active_widget(
wmWidgetMap *wmap, bContext *C,
- wmEvent *event, wmWidget *widget,
- const bool call_op)
+ const wmEvent *event, wmWidget *widget)
{
if (widget) {
- if (call_op) {
+ if (widget->opname) {
wmOperatorType *ot;
- const bool has_custom_op = widget->opname != NULL;
- const char *opname = has_custom_op ? widget->opname : "WM_OT_widget_tweak";
- ot = WM_operatortype_find(opname, 0);
+ ot = WM_operatortype_find(widget->opname, 0);
if (ot) {
/* first activate the widget itself */
if (widget->invoke && widget->handler) {
widget->flag |= WM_WIDGET_ACTIVE;
widget->invoke(C, event, widget);
- wmap->active_widget = widget;
}
+ wmap->active_widget = widget;
- /* if operator runs modal, we will need to activate the current widgetmap on the operator handler,
- * so it can process events first, then pass them on to the operator */
- if (WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &widget->opptr) == OPERATOR_RUNNING_MODAL) {
- /* check if operator added a a modal event handler */
- wmEventHandler *handler = CTX_wm_window(C)->modalhandlers.first;
-
- if (has_custom_op == false && handler && handler->op && handler->op->type == ot) {
- handler->widgetmap = wmap;
- }
- }
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &widget->opptr);
/* we failed to hook the widget to the operator handler or operator was cancelled, return */
if (!wmap->active_widget) {
@@ -846,7 +1015,7 @@ void wm_widgetmap_set_active_widget(
}
}
wmap->active_widget = NULL;
-
+
if (C) {
ARegion *ar = CTX_wm_region(C);
ED_region_tag_redraw(ar);
@@ -855,6 +1024,33 @@ void wm_widgetmap_set_active_widget(
}
}
+wmWidget *wm_widgetmap_get_selected_widget(wmWidgetMap *wmap)
+{
+ return wmap->selected_widget;
+}
+
+void wm_widgetmap_set_selected_widget(bContext *C, wmWidgetMap *wmap, wmWidget *widget)
+{
+ if (widget) {
+ wmap->selected_widget = widget;
+ widget->flag |= WM_WIDGET_SELECTED;
+ wm_widgetmap_set_highlighted_widget(wmap, C, NULL, wmap->highlighted_widget->highlighted_part);
+ }
+ else {
+ widget = wmap->selected_widget;
+ if (widget) {
+ wmap->selected_widget = NULL;
+ widget->flag &= ~WM_WIDGET_SELECTED;
+ }
+ }
+
+ /* tag the region for redraw */
+ if (C) {
+ ARegion *ar = CTX_wm_region(C);
+ ED_region_tag_redraw(ar);
+ }
+}
+
void wm_widgetmap_handler_context(bContext *C, wmEventHandler *handler)
{
bScreen *screen = CTX_wm_screen(C);
@@ -915,7 +1111,7 @@ void wm_widget_handler_modal_update(bContext *C, wmEvent *event, wmEventHandler
}
/* operator not running anymore */
else {
- wm_widgetmap_set_active_widget(wmap, C, event, NULL, false);
+ wm_widgetmap_set_active_widget(wmap, C, event, NULL);
}
/* restore the area */
@@ -959,7 +1155,7 @@ void WM_widgetmap_delete(wmWidgetMap *wmap)
for (wgroup = wmap->widgetgroups.first; wgroup; wgroup = wgroup->next) {
wmWidget *widget;
-
+
for (widget = wgroup->widgets.first; widget;) {
wmWidget *widget_next = widget->next;
wm_widget_delete(&wgroup->widgets, widget);
@@ -981,7 +1177,7 @@ static void wm_widgetgroup_free(bContext *C, wmWidgetMap *wmap, wmWidgetGroup *w
wm_widgetmap_set_highlighted_widget(wmap, C, NULL, 0);
}
if (widget->flag & WM_WIDGET_ACTIVE) {
- wm_widgetmap_set_active_widget(wmap, C, NULL, NULL, false);
+ wm_widgetmap_set_active_widget(wmap, C, NULL, NULL);
}
wm_widget_delete(&wgroup->widgets, widget);
widget = widget_next;
@@ -1004,6 +1200,34 @@ static void wm_widgetgroup_free(bContext *C, wmWidgetMap *wmap, wmWidgetGroup *w
MEM_freeN(wgroup);
}
+/**
+ * Common default keymap for widget groups
+ */
+wmKeyMap *WM_widgetgroup_keymap_common(wmKeyConfig *config, const char *wgroupname)
+{
+ wmKeyMap *km = WM_keymap_find(config, wgroupname, 0, 0);
+ wmKeyMapItem *kmi;
+
+ kmi = WM_keymap_add_item(km, "WIDGETGROUP_OT_widget_set_active", ACTIONMOUSE, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "deactivate", false);
+ kmi = WM_keymap_add_item(km, "WIDGETGROUP_OT_widget_set_active", ACTIONMOUSE, KM_RELEASE, 0, 0);
+ RNA_boolean_set(kmi->ptr, "deactivate", true);
+
+ WM_keymap_add_item(km, "WIDGETGROUP_OT_widget_tweak", MOUSEMOVE, KM_ANY, KM_ANY, 0);
+
+ WM_keymap_add_item(km, "WIDGETGROUP_OT_widget_tweak_cancel", RIGHTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(km, "WIDGETGROUP_OT_widget_tweak_cancel", ESCKEY, KM_PRESS, 0, 0);
+
+ WM_keymap_add_item(km, "WIDGETGROUP_OT_widget_set_select", SELECTMOUSE, KM_PRESS, 0, 0);
+
+ return km;
+}
+
+void wm_widgetgrouptype_keymap_init(wmWidgetGroupType *wgrouptype, wmKeyConfig *keyconf)
+{
+ wgrouptype->keymap = wgrouptype->keymap_init(keyconf, wgrouptype->name);
+}
+
void WM_widgetgrouptype_unregister(bContext *C, Main *bmain, wmWidgetGroupType *wgrouptype)
{
bScreen *sc;
@@ -1036,8 +1260,10 @@ void WM_widgetgrouptype_unregister(bContext *C, Main *bmain, wmWidgetGroupType *
}
wmaptype = WM_widgetmaptype_find(wgrouptype->mapidname, wgrouptype->spaceid, wgrouptype->regionid, wgrouptype->is_3d, false);
+
BLI_remlink(&wmaptype->widgetgrouptypes, wgrouptype);
wgrouptype->prev = wgrouptype->next = NULL;
+
MEM_freeN(wgrouptype);
}