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')
-rw-r--r--source/blender/windowmanager/WM_api.h60
-rw-r--r--source/blender/windowmanager/WM_types.h23
-rw-r--r--source/blender/windowmanager/intern/wm.c1
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c92
-rw-r--r--source/blender/windowmanager/intern/wm_generic_widgets.c550
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c6
-rw-r--r--source/blender/windowmanager/intern/wm_widgets.c566
-rw-r--r--source/blender/windowmanager/wm.h44
-rw-r--r--source/blender/windowmanager/wm_event_system.h17
9 files changed, 974 insertions, 385 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index f0dbc4d4108..15a3a35b00b 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -506,31 +506,48 @@ 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 *));
-void WM_widget_property(struct wmWidget *, int slot, struct PointerRNA *ptr, const char *propname);
-struct PointerRNA *WM_widget_operator(struct wmWidget *, const char *opname);
-void WM_widgets_update(const struct bContext *C, struct wmWidgetMap *wmap);
-void WM_widgets_draw(const struct bContext *C, const struct wmWidgetMap *wmap, const bool in_scene);
-void WM_event_add_area_widgetmap_handlers(struct ARegion *ar);
-void WM_modal_handler_attach_widgetgroup(struct bContext *C, struct wmEventHandler *handler,
- struct wmWidgetGroupType *wgrouptype, struct wmOperator *op);
-void WM_widgetgroup_customdata_set(struct wmWidgetGroup *wgroup, void *data);
+void WM_widgets_update(const struct bContext *C, struct wmWidgetMap *wmap);
+void WM_widgets_draw(const struct bContext *C, const struct wmWidgetMap *wmap, const bool in_scene);
+void WM_event_add_area_widgetmap_handlers(struct ARegion *ar);
+void WM_modal_handler_attach_widgetgroup(struct bContext *C, struct wmEventHandler *handler,
+ struct wmWidgetGroupType *wgrouptype, struct wmOperator *op);
+void WM_widgetgroup_customdata_set(struct wmWidgetGroup *wgroup, void *data);
void *WM_widgetgroup_customdata(const struct wmWidgetGroup *wgroup);
+/* wmWidget->flag */
+enum widgetflags {
+ /* states */
+ WM_WIDGET_HIGHLIGHT = (1 << 0),
+ WM_WIDGET_ACTIVE = (1 << 1),
+ WM_WIDGET_SELECTED = (1 << 2),
+ /* settings */
+ WM_WIDGET_DRAW_HOVER = (1 << 3),
+ WM_WIDGET_DRAW_ACTIVE = (1 << 4), /* draw while dragging */
+ WM_WIDGET_SCALE_3D = (1 << 5),
+ WM_WIDGET_SCENE_DEPTH = (1 << 6), /* widget is depth culled with scene objects*/
+ WM_WIDGET_HIDDEN = (1 << 7),
+ WM_WIDGET_SELECTABLE = (1 << 8),
+};
+
+void WM_widget_set_property(struct wmWidget *, int slot, struct PointerRNA *ptr, const char *propname);
+struct PointerRNA *WM_widget_set_operator(struct wmWidget *, const char *opname);
void WM_widget_set_origin(struct wmWidget *widget, const float origin[3]);
-void WM_widget_set_3d_scale(struct wmWidget *widget, const bool scale);
-void WM_widget_flag_set(struct wmWidget *widget, const int flag, const bool enable);
-void WM_widget_set_draw_on_hover_only(struct wmWidget *widget, const bool draw);
-void WM_widget_set_scene_depth(struct wmWidget *widget, const bool scene);
+void WM_widget_set_offset(struct wmWidget *widget, const float offset[3]);
+void WM_widget_set_flag(struct wmWidget *widget, const int flag, const bool enable);
void WM_widget_set_scale(struct wmWidget *widget, float scale);
void WM_widget_set_line_width(struct wmWidget *widget, const float line_width);
void WM_widget_set_colors(struct wmWidget *widget, const float col[4], const float col_hi[4]);
+wmKeyMap *WM_widgetgroup_keymap_common(wmKeyConfig *config, const char *wgroupname);
+
struct wmWidgetMapType *WM_widgetmaptype_find(const char *idname, const int spaceid, const int regionid,
const bool is_3d, const bool create);
-struct wmWidgetGroupType *WM_widgetgrouptype_new(int (*poll)(const struct bContext *, struct wmWidgetGroupType *),
- void (*create)(const struct bContext *, struct wmWidgetGroup *),
- const struct Main *bmain, const char *mapidname,
- const short spaceid, const short regionid, const bool is_3d);
+struct wmWidgetGroupType *WM_widgetgrouptype_new(
+ int (*poll)(const struct bContext *, struct wmWidgetGroupType *),
+ void (*create)(const struct bContext *, struct wmWidgetGroup *),
+ wmKeyMap *(*keymap_init)(wmKeyConfig *, const char *),
+ const struct Main *bmain, const char *mapidname, const char *name,
+ const short spaceid, const short regionid, const bool is_3d);
void WM_widgetgrouptype_unregister(struct bContext *C, struct Main *bmain, struct wmWidgetGroupType *wgroup);
/* creates a widgetmap with all registered widgets for that type */
@@ -549,6 +566,7 @@ enum {
WIDGET_ARROW_STYLE_INVERTED = (1 << 3), /* inverted offset during interaction - if set it also sets constrained below */
WIDGET_ARROW_STYLE_CONSTRAINED = (1 << 4), /* clamp arrow interaction to property width */
WIDGET_ARROW_STYLE_BOX = (1 << 5), /* use a box for the arrowhead */
+ WIDGET_ARROW_STYLE_CONE = (1 << 6),
};
enum {
@@ -580,21 +598,21 @@ enum {
struct wmWidget *WIDGET_arrow_new(struct wmWidgetGroup *wgroup, const char *name, const int style);
void WIDGET_arrow_set_direction(struct wmWidget *widget, const float direction[3]);
void WIDGET_arrow_set_up_vector(struct wmWidget *widget, const float direction[3]);
-void WIDGET_arrow_set_line_vec(struct wmWidget *widget, const float (*vec)[3], const int tot_points);
-void WIDGET_arrow_set_scale(struct wmWidget *widget, const float scale);
+void WIDGET_arrow_set_line_len(struct wmWidget *widget, const float len);
+void WIDGET_arrow_set_ui_range(struct wmWidget *widget, const float min, const float max);
+void WIDGET_arrow_set_range_fac(struct wmWidget *widget, const float range_fac);
+void WIDGET_arrow_cone_set_aspect(struct wmWidget *widget, const float aspect[2]);
struct wmWidget *WIDGET_dial_new(struct wmWidgetGroup *wgroup, const char *name, const int style);
-void WIDGET_dial_set_direction(struct wmWidget *widget, const float direction[3]);
+void WIDGET_dial_set_up_vector(struct wmWidget *widget, const float direction[3]);
struct wmWidget *WIDGET_plane_new(struct wmWidgetGroup *wgroup, const char *name, const int style);
void WIDGET_plane_set_direction(struct wmWidget *widget, const float direction[3]);
-void WIDGET_plane_set_offset(struct wmWidget *widget, const float offset[3]);
void WIDGET_plane_set_up_vector(struct wmWidget *widget, const float direction[3]);
struct wmWidget *WIDGET_rect_transform_new(
struct wmWidgetGroup *wgroup, const char *name, const int style,
const float width, const float height);
-void WIDGET_rect_transform_set_offset(struct wmWidget *widget, const float offset[2]);
struct wmWidget *WIDGET_facemap_new(
struct wmWidgetGroup *wgroup, const char *name, const int style,
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 248f5760720..3e43047c96c 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -108,6 +108,8 @@ extern "C" {
struct bContext;
struct wmEvent;
+struct wmKeyMap;
+struct wmKeyConfig;
struct wmWindowManager;
struct wmOperator;
struct ImBuf;
@@ -672,18 +674,17 @@ typedef struct wmDropBox {
/* WidgetGroups store and manage groups of widgets.
- * They are responsible for drawing necessary widgets and updating their state and position.
- * Also they */
+ * They are responsible for drawing necessary widgets and updating their state and position. */
typedef struct wmWidget wmWidget;
typedef struct wmWidgetGroup wmWidgetGroup;
typedef struct wmWidgetMapType wmWidgetMapType;
-typedef struct wmWidgetGroupType wmWidgetGroupType;
/* factory class for a widgetgroup type, gets called every time a new area is spawned */
typedef struct wmWidgetGroupType {
struct wmWidgetGroupType *next, *prev;
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 struct bContext *C, struct wmWidgetGroupType *wgrouptype) ATTR_WARN_UNUSED_RESULT;
@@ -691,6 +692,12 @@ typedef struct wmWidgetGroupType {
/* update widgets, called right before drawing */
void (*create)(const struct bContext *C, struct wmWidgetGroup *wgroup);
+ /* keymap init callback for this widgetgroup */
+ struct wmKeyMap *(*keymap_init)(struct wmKeyConfig *, const char *);
+
+ /* keymap created with callback from above */
+ struct wmKeyMap *keymap;
+
/* rna for properties */
struct StructRNA *srna;
@@ -711,16 +718,18 @@ typedef struct wmWidgetGroupType {
typedef struct wmWidgetMap {
struct wmWidgetMap *next, *prev;
-
+
struct wmWidgetMapType *type;
ListBase widgetgroups;
-
+
/* highlighted widget for this map. We redraw the widgetmap when this changes */
struct wmWidget *highlighted_widget;
/* active widget for this map. User has clicked currently this widget and it gets all input */
struct wmWidget *active_widget;
-
- /* active group is overriding all other widgets while active */
+ /* selected widget for this map. */
+ struct wmWidget *selected_widget;
+
+ /* active group - set while widget is highlighted/active */
struct wmWidgetGroup *activegroup;
} wmWidgetMap;
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index fd46d9bd1d0..4b3d66b9e71 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -342,6 +342,7 @@ void WM_keymap_init(bContext *C)
* it's persistent across sessions */
if (!(wm->defaultconf->flag & KEYCONF_INIT_DEFAULT)) {
wm_window_keymap(wm->defaultconf);
+ wm_widgets_keymap(wm->defaultconf);
ED_spacetypes_keymap(wm->defaultconf);
wm->defaultconf->flag |= KEYCONF_INIT_DEFAULT;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 2a9de6f5029..98f88c9a081 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1697,6 +1697,9 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
CTX_wm_region_set(C, NULL);
}
+ /* update widgets during modal handlers */
+ wm_widget_handler_modal_update(C, event, handler);
+
/* remove modal handler, operator itself should have been canceled and freed */
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
WM_cursor_grab_disable(CTX_wm_window(C), NULL);
@@ -1933,6 +1936,9 @@ static int wm_action_not_handled(int action)
return action == WM_HANDLER_CONTINUE || action == (WM_HANDLER_BREAK | WM_HANDLER_MODAL);
}
+/* use old, hardcoded widget map handling - kept in case new one doesn't work out */
+//#define USE_OLD_WIDGETMAP_HANDLING
+
static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers)
{
#ifndef NDEBUG
@@ -2063,16 +2069,59 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
}
else if (handler->widgetmap) {
- wmWidgetMap *wmap = handler->widgetmap;
- unsigned char part;
- short event_processed = 0;
- wmWidget *widget = wm_widgetmap_get_active_widget(wmap);
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
+ wmWidgetMap *wmap = handler->widgetmap;
+ wmWidget *widget = wm_widgetmap_get_highlighted_widget(wmap);
+ short event_processed = 0;
+ unsigned char part;
wm_widgetmap_handler_context(C, handler);
wm_region_mouse_co(C, event);
+#ifndef USE_OLD_WIDGETMAP_HANDLING
+ /* handle widget highlighting */
+ if (event->type == MOUSEMOVE && !wm_widgetmap_get_active_widget(wmap)) {
+ if (wm_widgetmap_is_3d(wmap)) {
+ widget = wm_widget_find_highlighted_3D(wmap, C, event, &part);
+ wm_widgetmap_set_highlighted_widget(wmap, C, widget, part);
+ }
+ else {
+ widget = wm_widget_find_highlighted(wmap, C, event, &part);
+ wm_widgetmap_set_highlighted_widget(wmap, C, widget, part);
+ }
+ }
+ /* handle user configurable widgetmap keymap */
+ else if (widget && wmap->activegroup) {
+ /* get user customized keymap from default one */
+ const wmKeyMap *keymap = WM_keymap_active(wm, wmap->activegroup->type->keymap);
+ wmKeyMapItem *kmi;
+
+ if (!keymap->poll || keymap->poll(C)) {
+ for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ if (wm_eventmatch(event, kmi)) {
+ wmOperator *op = handler->op;
+
+ /* weak, but allows interactive callback to not use rawkey */
+ event->keymap_idname = kmi->idname;
+
+ /* handler->op is called later, we want keymap op to be triggered here */
+ handler->op = NULL;
+ action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr);
+ handler->op = op;
+
+ if (action & WM_HANDLER_BREAK) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ UNUSED_VARS(event_processed);
+#else
+ widget = wm_widgetmap_get_active_widget(wmap);
+
/* handle the widget first, before passing the event down */
switch (event->type) {
case MOUSEMOVE:
@@ -2090,12 +2139,11 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
wm_widgetmap_set_highlighted_widget(wmap, C, widget, part);
}
break;
-
case LEFTMOUSE:
- {
if (widget) {
if (event->val == KM_RELEASE) {
wm_widgetmap_set_active_widget(wmap, C, event, NULL, false);
+ wm_widgetmap_set_selected_widget(C, wmap, NULL);
event_processed = EVT_WIDGET_RELEASED;
action |= WM_HANDLER_BREAK;
}
@@ -2112,27 +2160,51 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
}
break;
+ case RIGHTMOUSE:
+ case ESCKEY:
+ {
+ wmWidget *highlight = wm_widgetmap_get_highlighted_widget(wmap);
+ if (event->type == RIGHTMOUSE && highlight) {
+ if (highlight->flag & WM_WIDGET_SELECTABLE) {
+ if (event->val == KM_RELEASE) {
+ wm_widgetmap_set_selected_widget(C, wmap, highlight);
+ action |= WM_HANDLER_BREAK;
+ }
+ }
+ }
+ else if (widget) {
+ if (widget->cancel) {
+ widget->cancel(C, widget);
+ }
+ wm_widgetmap_set_active_widget(wmap, C, event, NULL, false);
+ event_processed = EVT_WIDGET_RELEASED;
+ action |= WM_HANDLER_BREAK;
+ }
+ else {
+ wm_widgetmap_set_selected_widget(C, wmap, NULL);
+ }
+ break;
}
}
-
+#endif
+
/* restore the area */
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
if (handler->op) {
+#ifdef USE_OLD_WIDGETMAP_HANDLING
/* if event was processed by an active widget pass the modified event to the operator */
if (event_processed) {
event->type = event_processed;
}
+#endif
action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
}
}
else {
/* modal, swallows all */
action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
-
- /* update widgets during modal handlers */
- wm_widget_handler_modal_update(C, event, handler);
}
if (action & WM_HANDLER_BREAK) {
diff --git a/source/blender/windowmanager/intern/wm_generic_widgets.c b/source/blender/windowmanager/intern/wm_generic_widgets.c
index e56d415e700..7e26c086ba0 100644
--- a/source/blender/windowmanager/intern/wm_generic_widgets.c
+++ b/source/blender/windowmanager/intern/wm_generic_widgets.c
@@ -15,7 +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) 2009 Blender Foundation.
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation
@@ -23,8 +23,12 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/editors/interface/interface_generic_widgets.c
- * \ingroup edinterface
+/** \file blender/windowmanager/intern/wm_generic_widgets.c
+ * \ingroup wm
+ *
+ * *****************************************************
+ * GENERIC WIDGET LIBRARY
+ * *****************************************************
*/
#include "RNA_types.h"
@@ -69,17 +73,15 @@
#include "WM_types.h"
-/******************************************************
- * GENERIC WIDGET LIBRARY *
- ******************************************************/
-
-
/* to use custom arrows exported to arrow_widget.c */
//#define WIDGET_USE_CUSTOM_ARROWS
-/* to use custom dials exported to arrow_widget.c */
+/* to use custom dials exported to dial_widget.c */
//#define WIDGET_USE_CUSTOM_DIAS
+/* -------------------------------------------------------------------- */
+/* Widget drawing */
+
typedef struct WidgetDrawInfo {
int nverts;
int ntris;
@@ -151,24 +153,43 @@ static void widget_draw_intern(WidgetDrawInfo *info, const bool select)
}
}
-/********* Arrow widget ************/
-#define ARROW_UP_VECTOR_SET 1
+/* -------------------------------------------------------------------- */
+/* Widget defines */
+
+/** \name Arrow Widget
+ *
+ * 3D Widget
+ *
+ * \brief Simple arrow widget which is dragged into a certain direction.
+ * The arrow head can have have varying shapes, e.g. cone, box, etc.
+ *
+ * \{ */
+
+/* ArrowWidget->flag */
+enum {
+ ARROW_UP_VECTOR_SET = (1 << 0),
+ ARROW_CUSTOM_RANGE_SET = (1 << 1),
+};
typedef struct ArrowWidget {
wmWidget widget;
int style;
int flag;
+
+ float len; /* arrow line length */
float direction[3];
float up[3];
- float (*line)[3]; /* custom coords for arrow line drawing */
- int tot_line_points; /* amount of points for arrow line drawing */
+ float aspect[2]; /* cone style only */
+
+ float range_fac; /* factor for arrow min/max distance */
float offset;
/* property range and minimum for constrained arrows */
float range, min;
} ArrowWidget;
typedef struct ArrowInteraction {
+ float orig_value; /* initial property value */
float orig_origin[3];
float orig_mouse[2];
float orig_offset;
@@ -203,41 +224,80 @@ static void arrow_draw_geom(const ArrowWidget *arrow, const bool select)
glPopAttrib();
}
+ else if (arrow->style & WIDGET_ARROW_STYLE_CONE) {
+ const float unitx = arrow->aspect[0];
+ const float unity = arrow->aspect[1];
+ const float vec[4][3] = {
+ {-unitx, -unity, 0},
+ { unitx, -unity, 0},
+ { unitx, unity, 0},
+ {-unitx, unity, 0},
+ };
+
+ glLineWidth(arrow->widget.line_width);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, vec);
+ glDrawArrays(GL_LINE_LOOP, 0, ARRAY_SIZE(vec));
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glLineWidth(1.0);
+ }
else {
#ifdef WIDGET_USE_CUSTOM_ARROWS
widget_draw_intern(&arrow_head_draw_info, select);
#else
+ const float vec[2][3] = {
+ {0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, arrow->len},
+ };
+
glLineWidth(arrow->widget.line_width);
glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, arrow->line);
- glDrawArrays(GL_LINES, 0, arrow->tot_line_points);
+ glVertexPointer(3, GL_FLOAT, 0, vec);
+ glDrawArrays(GL_LINE_STRIP, 0, ARRAY_SIZE(vec));
glDisableClientState(GL_VERTEX_ARRAY);
glLineWidth(1.0);
- /* draw arrow head */
- glTranslatef(UNPACK3(arrow->line[arrow->tot_line_points - 1]));
+ /* *** draw arrow head *** */
+
+ glPushMatrix();
if (arrow->style & WIDGET_ARROW_STYLE_BOX) {
const float size = 0.05f;
- /* draw cube */
+ /* translate to line end with some extra offset so box starts exactly where line ends */
+ glTranslatef(0.0f, 0.0f, arrow->len + size);
+ /* scale down to box size */
glScalef(size, size, size);
+
+ /* draw cube */
widget_draw_intern(&cube_draw_info, select);
}
else {
GLUquadricObj *qobj = gluNewQuadric();
const float len = 0.25f;
const float width = 0.06f;
+ const bool use_lighting = select == false && ((U.tw_flag & V3D_SHADED_WIDGETS) != 0);
+
+ /* translate to line end */
+ glTranslatef(0.0f, 0.0f, arrow->len);
+
+ if (use_lighting) {
+ glShadeModel(GL_SMOOTH);
+ }
gluQuadricDrawStyle(qobj, GLU_FILL);
- gluCylinder(qobj, width, 0.0, len, 8, 1);
gluQuadricOrientation(qobj, GLU_INSIDE);
gluDisk(qobj, 0.0, width, 8, 1);
gluQuadricOrientation(qobj, GLU_OUTSIDE);
+ gluCylinder(qobj, width, 0.0, len, 8, 1);
+
+ if (use_lighting) {
+ glShadeModel(GL_FLAT);
+ }
}
- (void)select;
+ glPopMatrix();
#endif
}
@@ -276,6 +336,7 @@ static void arrow_draw_intern(ArrowWidget *arrow, const bool select, const bool
}
glEnable(GL_BLEND);
+ glTranslate3fv(arrow->widget.offset);
arrow_draw_geom(arrow, select);
glDisable(GL_BLEND);
@@ -293,8 +354,8 @@ static void arrow_draw_intern(ArrowWidget *arrow, const bool select, const bool
glEnable(GL_BLEND);
glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
+ glTranslate3fv(arrow->widget.offset);
arrow_draw_geom(arrow, select);
-
glDisable(GL_BLEND);
glPopMatrix();
@@ -312,7 +373,11 @@ static void widget_arrow_draw(const bContext *UNUSED(C), wmWidget *widget)
arrow_draw_intern((ArrowWidget *)widget, false, (widget->flag & WM_WIDGET_HIGHLIGHT) != 0);
}
-#define ARROW_RANGE 1.5f
+/**
+ * Calculate arrow offset independent from prop min value,
+ * meaning the range will not be offset by min value first.
+ */
+#define USE_ABS_HANDLE_RANGE
static int widget_arrow_handler(bContext *C, const wmEvent *event, wmWidget *widget)
{
@@ -330,6 +395,7 @@ static int widget_arrow_handler(bContext *C, const wmEvent *event, wmWidget *wid
float facdir = 1.0f;
bool use_vertical = false;
+
copy_v3_v3(orig_origin, data->orig_origin);
orig_origin[3] = 1.0f;
add_v3_v3v3(offset, orig_origin, arrow->direction);
@@ -403,14 +469,24 @@ static int widget_arrow_handler(bContext *C, const wmEvent *event, wmWidget *wid
if (widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE]) {
PointerRNA ptr = widget->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE];
PropertyRNA *prop = widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
+ float max = arrow->min + arrow->range;
float value;
value = data->orig_offset + facdir * len_v3(offset);
if (arrow->style & WIDGET_ARROW_STYLE_CONSTRAINED) {
if (arrow->style & WIDGET_ARROW_STYLE_INVERTED)
- value = arrow->min + arrow->range - (value * arrow->range / ARROW_RANGE);
+ value = max - (value * arrow->range / arrow->range_fac);
else
- value = arrow->min + (value * arrow->range / ARROW_RANGE);
+#ifdef USE_ABS_HANDLE_RANGE
+ value = value * arrow->range / arrow->range_fac;
+#else
+ value = arrow->min + (value * arrow->range / arrow->range_fac);
+#endif
+ }
+
+ /* clamp to custom range */
+ if (arrow->flag & ARROW_CUSTOM_RANGE_SET) {
+ CLAMP(value, arrow->min, max);
}
RNA_property_float_set(&ptr, prop, value);
@@ -421,9 +497,13 @@ static int widget_arrow_handler(bContext *C, const wmEvent *event, wmWidget *wid
/* accounts for clamping properly */
if (arrow->style & WIDGET_ARROW_STYLE_CONSTRAINED) {
if (arrow->style & WIDGET_ARROW_STYLE_INVERTED)
- arrow->offset = ARROW_RANGE * (arrow->min + arrow->range - value) / arrow->range;
+ arrow->offset = arrow->range_fac * (max - value) / arrow->range;
else
- arrow->offset = ARROW_RANGE * ((value - arrow->min) / arrow->range);
+#ifdef USE_ABS_HANDLE_RANGE
+ arrow->offset = arrow->range_fac * (value / arrow->range);
+#else
+ arrow->offset = arrow->range_fac * ((value - arrow->min) / arrow->range);
+#endif
}
else
arrow->offset = value;
@@ -443,6 +523,12 @@ static int widget_arrow_invoke(bContext *UNUSED(C), const wmEvent *event, wmWidg
{
ArrowWidget *arrow = (ArrowWidget *) widget;
ArrowInteraction *data = MEM_callocN(sizeof(ArrowInteraction), "arrow_interaction");
+ PointerRNA ptr = widget->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE];
+ PropertyRNA *prop = widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
+
+ if (prop) {
+ data->orig_value = RNA_property_float_get(&ptr, prop);
+ }
data->orig_offset = arrow->offset;
@@ -465,20 +551,29 @@ static void widget_arrow_bind_to_prop(wmWidget *widget, const int UNUSED(slot))
PropertyRNA *prop = widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
if (prop) {
- const float float_prop = RNA_property_float_get(&ptr, prop);
+ float float_prop = RNA_property_float_get(&ptr, prop);
if (arrow->style & WIDGET_ARROW_STYLE_CONSTRAINED) {
float min, max, step, precision;
- RNA_property_float_ui_range(&ptr, prop, &min, &max, &step, &precision);
- arrow->range = max - min;
- arrow->min = min;
+ if (arrow->flag & ARROW_CUSTOM_RANGE_SET) {
+ max = arrow->min + arrow->range;
+ }
+ else {
+ RNA_property_float_ui_range(&ptr, prop, &min, &max, &step, &precision);
+ arrow->range = max - min;
+ arrow->min = min;
+ }
if (arrow->style & WIDGET_ARROW_STYLE_INVERTED) {
- arrow->offset = ARROW_RANGE * (max - float_prop) / arrow->range;
+ arrow->offset = arrow->range_fac * (max - float_prop) / arrow->range;
}
else {
- arrow->offset = ARROW_RANGE * ((float_prop - arrow->min) / arrow->range);
+#ifdef USE_ABS_HANDLE_RANGE
+ arrow->offset = arrow->range_fac * (float_prop / arrow->range);
+#else
+ arrow->offset = arrow->range_fac * ((float_prop - arrow->min) / arrow->range);
+#endif
}
}
else {
@@ -490,14 +585,25 @@ static void widget_arrow_bind_to_prop(wmWidget *widget, const int UNUSED(slot))
arrow->offset = 0.0f;
}
+static void widget_arrow_cancel(bContext *C, wmWidget *widget)
+{
+ PointerRNA ptr = widget->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE];
+ PropertyRNA *prop = widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
+ ArrowInteraction *data = widget->interaction_data;
+
+ /* reset property */
+ RNA_property_float_set(&ptr, prop, data->orig_value);
+ RNA_property_update(C, &ptr, prop);
+}
+
+/** \name Arrow Widget API
+ *
+ * \{ */
+
wmWidget *WIDGET_arrow_new(wmWidgetGroup *wgroup, const char *name, const int style)
{
ArrowWidget *arrow = MEM_callocN(sizeof(ArrowWidget), name);
const float dir_default[3] = {0.0f, 0.0f, 1.0f};
- const float line_default[2][3] = {
- {0.0f, 0.0f, 0.0f},
- {0.0f, 0.0f, 1.0f}
- };
int real_style = style;
#ifdef WIDGET_USE_CUSTOM_ARROWS
@@ -532,29 +638,33 @@ wmWidget *WIDGET_arrow_new(wmWidgetGroup *wgroup, const char *name, const int st
arrow->widget.invoke = widget_arrow_invoke;
arrow->widget.render_3d_intersection = widget_arrow_render_3d_intersect;
arrow->widget.bind_to_prop = widget_arrow_bind_to_prop;
- arrow->widget.flag |= WM_WIDGET_SCALE_3D;
+ arrow->widget.cancel = widget_arrow_cancel;
+ arrow->widget.flag |= (WM_WIDGET_SCALE_3D | WM_WIDGET_DRAW_ACTIVE);
arrow->style = real_style;
-
- /* defaults */
+ arrow->len = 1.0f;
+ arrow->range_fac = 1.0f;
copy_v3_v3(arrow->direction, dir_default);
- arrow->tot_line_points = ARRAY_SIZE(line_default);
- arrow->line = MEM_mallocN(sizeof(line_default), __func__);
- memcpy(arrow->line, line_default, sizeof(line_default));
wm_widget_register(wgroup, &arrow->widget, name);
return (wmWidget *)arrow;
}
+/**
+ * Define direction the arrow will point towards
+ */
void WIDGET_arrow_set_direction(wmWidget *widget, const float direction[3])
{
ArrowWidget *arrow = (ArrowWidget *)widget;
-
+
copy_v3_v3(arrow->direction, direction);
normalize_v3(arrow->direction);
}
+/**
+ * Define up-direction of the arrow widget
+ */
void WIDGET_arrow_set_up_vector(wmWidget *widget, const float direction[3])
{
ArrowWidget *arrow = (ArrowWidget *)widget;
@@ -570,20 +680,67 @@ void WIDGET_arrow_set_up_vector(wmWidget *widget, const float direction[3])
}
/**
- * Define a custom coord vec for arrow line drawing
+ * Define a custom arrow line length
+ */
+void WIDGET_arrow_set_line_len(wmWidget *widget, const float len)
+{
+ ArrowWidget *arrow = (ArrowWidget *)widget;
+ arrow->len = len;
+}
+
+/**
+ * Define a custom property UI range
+ *
+ * \note Needs to be called before WM_widget_set_property!
+ */
+void WIDGET_arrow_set_ui_range(wmWidget *widget, const float min, const float max)
+{
+ ArrowWidget *arrow = (ArrowWidget *)widget;
+
+ BLI_assert(min < max);
+ BLI_assert(!(arrow->widget.props[0] && "Make sure this function is called before WM_widget_set_property"));
+
+ arrow->range = max - min;
+ arrow->min = min;
+ arrow->flag |= ARROW_CUSTOM_RANGE_SET;
+}
+
+/**
+ * Define a custom factor for arrow min/max distance
+ *
+ * \note Needs to be called before WM_widget_set_property!
+ */
+void WIDGET_arrow_set_range_fac(wmWidget *widget, const float range_fac)
+{
+ ArrowWidget *arrow = (ArrowWidget *)widget;
+
+ BLI_assert(!(arrow->widget.props[0] && "Make sure this function is called before WM_widget_set_property"));
+
+ arrow->range_fac = range_fac;
+}
+
+/**
+ * Define xy-aspect for arrow cone
*/
-void WIDGET_arrow_set_line_vec(wmWidget *widget, const float (*vec)[3], const int tot_points)
+void WIDGET_arrow_cone_set_aspect(wmWidget *widget, const float aspect[2])
{
ArrowWidget *arrow = (ArrowWidget *)widget;
- const size_t vec_size = 3 * tot_points * sizeof(float);
- arrow->tot_line_points = tot_points;
- arrow->line = MEM_reallocN(arrow->line, vec_size);
- memcpy(arrow->line, vec, vec_size);
+ copy_v2_v2(arrow->aspect, aspect);
}
+/** \} */ // Arrow Widget API
+/** \} */ // Arrow Widget
+
-/********* Dial widget ************/
+/** \name Dial Widget
+ *
+ * 3D Widget
+ *
+ * \brief Circle shaped widget for circular interaction.
+ * Currently no own handling, use with operator only.
+ *
+ * \{ */
typedef struct DialWidget {
wmWidget widget;
@@ -593,24 +750,23 @@ typedef struct DialWidget {
static void dial_draw_geom(const DialWidget *dial, const bool select)
{
+#ifdef WIDGET_USE_CUSTOM_DIAS
+ glEnable(GL_MULTISAMPLE_ARB);
+
+ widget_draw_intern(&dial_draw_info, select);
+#else
GLUquadricObj *qobj = gluNewQuadric();
const float width = 1.0f;
const int resol = 32;
glEnable(GL_MULTISAMPLE_ARB);
-#ifdef WIDGET_USE_CUSTOM_DIAS
- widget_draw_intern(&dial_draw_info, select);
-
- (void)qobj; (void)width; (void)resol;
-#else
-
glLineWidth(dial->widget.line_width);
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
gluDisk(qobj, 0.0, width, resol, 1);
glLineWidth(1.0);
- (void)select;
+ UNUSED_VARS(select);
#endif
glDisable(GL_MULTISAMPLE_ARB);
@@ -635,6 +791,7 @@ static void dial_draw_intern(DialWidget *dial, const bool select, const bool hig
else
glColor4fv(dial->widget.col);
+ glTranslate3fv(dial->widget.offset);
dial_draw_geom(dial, select);
glPopMatrix();
@@ -688,6 +845,10 @@ static void widget_dial_draw(const bContext *C, wmWidget *widget)
}
}
+/** \name Dial Widget API
+ *
+ * \{ */
+
wmWidget *WIDGET_dial_new(wmWidgetGroup *wgroup, const char *name, const int style)
{
DialWidget *dial = MEM_callocN(sizeof(DialWidget), name);
@@ -719,7 +880,10 @@ wmWidget *WIDGET_dial_new(wmWidgetGroup *wgroup, const char *name, const int sty
return (wmWidget *)dial;
}
-void WIDGET_dial_set_direction(wmWidget *widget, const float direction[3])
+/**
+ * Define up-direction of the dial widget
+ */
+void WIDGET_dial_set_up_vector(wmWidget *widget, const float direction[3])
{
DialWidget *dial = (DialWidget *)widget;
@@ -727,21 +891,32 @@ void WIDGET_dial_set_direction(wmWidget *widget, const float direction[3])
normalize_v3(dial->direction);
}
-/********* Plane widget ************/
+/** \} */ // Dial Widget API
+/** \} */ // Dial Widget
+
+/** \name Plane Widget
+ *
+ * 3D Widget
+ *
+ * \brief Flat and rectangular shaped widget for planar interaction.
+ * Currently no own handling, use with operator only.
+ *
+ * \{ */
+
+/* PlaneWidget->flag */
#define PLANE_UP_VECTOR_SET 1
typedef struct PlaneWidget {
wmWidget widget;
float direction[3];
- float offset[3];
float up[3];
int flag;
} PlaneWidget;
-static void widget_plane_draw_geom(const float ofs[3], const float col_inner[4], const float col_outer[4])
+static void widget_plane_draw_geom(const float col_inner[4], const float col_outer[4])
{
static float vec[4][3] = {
{-1, -1, 0},
@@ -750,8 +925,6 @@ static void widget_plane_draw_geom(const float ofs[3], const float col_inner[4],
{-1, 1, 0},
};
- glTranslatef(UNPACK3(ofs));
-
glEnable(GL_MULTISAMPLE_ARB);
glEnableClientState(GL_VERTEX_ARRAY);
@@ -799,7 +972,8 @@ static void widget_plane_draw_intern(PlaneWidget *plane, const bool UNUSED(selec
col_inner[3] *= 0.5f;
glEnable(GL_BLEND);
- widget_plane_draw_geom(plane->offset, col_inner, col_outer);
+ glTranslate3fv(plane->widget.offset);
+ widget_plane_draw_geom(col_inner, col_outer);
glDisable(GL_BLEND);
glPopMatrix();
@@ -816,6 +990,10 @@ static void widget_plane_draw(const bContext *UNUSED(C), wmWidget *widget)
widget_plane_draw_intern((PlaneWidget *)widget, false, (widget->flag & WM_WIDGET_HIGHLIGHT));
}
+/** \name Plane Widget API
+ *
+ * \{ */
+
wmWidget *WIDGET_plane_new(wmWidgetGroup *wgroup, const char *name, const int UNUSED(style))
{
PlaneWidget *plane = MEM_callocN(sizeof(PlaneWidget), name);
@@ -828,13 +1006,15 @@ wmWidget *WIDGET_plane_new(wmWidgetGroup *wgroup, const char *name, const int UN
/* defaults */
copy_v3_v3(plane->direction, dir_default);
- zero_v3(plane->offset);
wm_widget_register(wgroup, &plane->widget, name);
return (wmWidget *)plane;
}
+/**
+ * Define direction the plane will point towards
+ */
void WIDGET_plane_set_direction(wmWidget *widget, const float direction[3])
{
PlaneWidget *plane = (PlaneWidget *)widget;
@@ -843,13 +1023,9 @@ void WIDGET_plane_set_direction(wmWidget *widget, const float direction[3])
normalize_v3(plane->direction);
}
-void WIDGET_plane_set_offset(wmWidget *widget, const float offset[3])
-{
- PlaneWidget *plane = (PlaneWidget *)widget;
-
- copy_v3_v3(plane->offset, offset);
-}
-
+/**
+ * Define up-direction of the plane widget
+ */
void WIDGET_plane_set_up_vector(wmWidget *widget, const float direction[3])
{
PlaneWidget *plane = (PlaneWidget *)widget;
@@ -864,8 +1040,20 @@ void WIDGET_plane_set_up_vector(wmWidget *widget, const float direction[3])
}
}
-/********* Cage widget ************/
+/** \} */ // Plane Widget API
+/** \} */ // Plane Widget
+
+
+/** \name Cage Widget
+ *
+ * 2D Widget
+ *
+ * \brief Rectangular widget acting as a 'cage' around its content.
+ * Interacting scales or translates the widget.
+ *
+ * \{ */
+/* wmWidget->highlighted_part */
enum {
WIDGET_RECT_TRANSFORM_INTERSECT_TRANSLATE = 1,
WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT = 2,
@@ -879,7 +1067,6 @@ enum {
typedef struct RectTransformWidget {
wmWidget widget;
- float offset[2]; /* position of widget */
float w, h; /* dimensions of widget */
float rotation; /* rotation of the rectangle */
float scale[2]; /* scaling for the widget for non-destructive editing. */
@@ -918,7 +1105,7 @@ static void rect_transform_draw_interaction(
{
float verts[4][2];
unsigned short elems[4] = {0, 1, 3, 2};
-
+
switch (highlighted) {
case WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT:
verts[0][0] = -half_w + w;
@@ -930,7 +1117,7 @@ static void rect_transform_draw_interaction(
verts[3][0] = -half_w + w;
verts[3][1] = half_h;
break;
-
+
case WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT:
verts[0][0] = half_w - w;
verts[0][1] = -half_h;
@@ -941,7 +1128,7 @@ static void rect_transform_draw_interaction(
verts[3][0] = half_w - w;
verts[3][1] = half_h;
break;
-
+
case WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN:
verts[0][0] = -half_w;
verts[0][1] = -half_h + h;
@@ -952,7 +1139,7 @@ static void rect_transform_draw_interaction(
verts[3][0] = half_w;
verts[3][1] = -half_h + h;
break;
-
+
case WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_UP:
verts[0][0] = -half_w;
verts[0][1] = half_h - h;
@@ -963,11 +1150,11 @@ static void rect_transform_draw_interaction(
verts[3][0] = half_w;
verts[3][1] = half_h - h;
break;
-
+
default:
return;
}
-
+
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, verts);
glLineWidth(line_width + 3.0);
@@ -978,7 +1165,7 @@ static void rect_transform_draw_interaction(
glDrawArrays(GL_LINE_STRIP, 0, 3);
glLineWidth(1.0);
- (void)elems;
+ UNUSED_VARS(elems);
}
static void widget_rect_transform_draw(const bContext *UNUSED(C), wmWidget *widget)
@@ -990,14 +1177,14 @@ static void widget_rect_transform_draw(const bContext *UNUSED(C), wmWidget *widg
float half_w = w / 2.0f;
float half_h = h / 2.0f;
float aspx = 1.0f, aspy = 1.0f;
-
+
r.xmin = -half_w;
r.ymin = -half_h;
r.xmax = half_w;
r.ymax = half_h;
-
+
glPushMatrix();
- glTranslatef(widget->origin[0] + cage->offset[0], widget->origin[1] + cage->offset[1], 0.0f);
+ glTranslatef(widget->origin[0] + widget->offset[0], widget->origin[1] + widget->offset[1], 0.0f);
if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)
glScalef(cage->scale[0], cage->scale[0], 1.0);
else
@@ -1029,7 +1216,7 @@ static void widget_rect_transform_draw(const bContext *UNUSED(C), wmWidget *widg
glPopMatrix();
}
-static int widget_rect_tranfrorm_get_cursor(wmWidget *widget)
+static int widget_rect_transform_get_cursor(wmWidget *widget)
{
switch (widget->highlighted_part) {
case WIDGET_RECT_TRANSFORM_INTERSECT_TRANSLATE:
@@ -1045,7 +1232,7 @@ static int widget_rect_tranfrorm_get_cursor(wmWidget *widget)
}
}
-static int widget_rect_tranfrorm_intersect(bContext *UNUSED(C), const wmEvent *event, wmWidget *widget)
+static int widget_rect_transform_intersect(bContext *UNUSED(C), const wmEvent *event, wmWidget *widget)
{
RectTransformWidget *cage = (RectTransformWidget *)widget;
const float mouse[2] = {event->mval[0], event->mval[1]};
@@ -1058,11 +1245,11 @@ static int widget_rect_tranfrorm_intersect(bContext *UNUSED(C), const wmEvent *e
bool isect;
rctf r;
float aspx = 1.0f, aspy = 1.0f;
-
+
/* rotate mouse in relation to the center and relocate it */
sub_v2_v2v2(point_local, mouse, widget->origin);
- point_local[0] -= cage->offset[0];
- point_local[1] -= cage->offset[1];
+ point_local[0] -= widget->offset[0];
+ point_local[1] -= widget->offset[1];
//rotate_m2(matrot, -cage->transform.rotation);
if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)
@@ -1071,7 +1258,7 @@ static int widget_rect_tranfrorm_intersect(bContext *UNUSED(C), const wmEvent *e
point_local[0] /= cage->scale[0];
point_local[1] /= cage->scale[0];
}
-
+
if (cage->w > cage->h)
aspx = h / w;
else
@@ -1084,9 +1271,9 @@ static int widget_rect_tranfrorm_intersect(bContext *UNUSED(C), const wmEvent *e
r.ymin = -half_h + h;
r.xmax = half_w - w;
r.ymax = half_h - h;
-
+
isect = BLI_rctf_isect_pt_v(&r, point_local);
-
+
if (isect)
return WIDGET_RECT_TRANSFORM_INTERSECT_TRANSLATE;
@@ -1096,43 +1283,43 @@ static int widget_rect_tranfrorm_intersect(bContext *UNUSED(C), const wmEvent *e
r.ymin = -half_h;
r.xmax = -half_w + w;
r.ymax = half_h;
-
+
isect = BLI_rctf_isect_pt_v(&r, point_local);
-
+
if (isect)
return WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT;
-
+
r.xmin = half_w - w;
r.ymin = -half_h;
r.xmax = half_w;
r.ymax = half_h;
-
+
isect = BLI_rctf_isect_pt_v(&r, point_local);
-
+
if (isect)
return WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT;
-
+
r.xmin = -half_w;
r.ymin = -half_h;
r.xmax = half_w;
r.ymax = -half_h + h;
-
+
isect = BLI_rctf_isect_pt_v(&r, point_local);
-
+
if (isect)
return WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN;
-
+
r.xmin = -half_w;
r.ymin = half_h - h;
r.xmax = half_w;
r.ymax = half_h;
-
+
isect = BLI_rctf_isect_pt_v(&r, point_local);
-
+
if (isect)
return WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_UP;
}
-
+
return 0;
}
@@ -1156,13 +1343,13 @@ static bool widget_rect_transform_get_property(wmWidget *widget, const int slot,
fprintf(stderr, "Rect Transform widget offset not only be bound to array float property");
return false;
}
-
RNA_property_float_get_array(&widget->ptr[slot], widget->props[slot], value);
}
else if (slot == RECT_TRANSFORM_SLOT_SCALE) {
RectTransformWidget *cage = (RectTransformWidget *)widget;
- if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM)
+ if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
*value = RNA_property_float_get(&widget->ptr[slot], widget->props[slot]);
+ }
else {
if (RNA_property_array_length(&widget->ptr[slot], widget->props[slot]) != 2) {
fprintf(stderr, "Rect Transform widget scale not only be bound to array float property");
@@ -1172,7 +1359,7 @@ static bool widget_rect_transform_get_property(wmWidget *widget, const int slot,
}
}
}
-
+
return true;
}
@@ -1180,45 +1367,45 @@ static int widget_rect_transform_invoke(bContext *UNUSED(C), const wmEvent *even
{
RectTransformWidget *cage = (RectTransformWidget *) widget;
RectTransformInteraction *data = MEM_callocN(sizeof (RectTransformInteraction), "cage_interaction");
-
- copy_v2_v2(data->orig_offset, cage->offset);
+
+ copy_v2_v2(data->orig_offset, widget->offset);
copy_v2_v2(data->orig_scale, cage->scale);
-
+
data->orig_mouse[0] = event->mval[0];
data->orig_mouse[1] = event->mval[1];
-
+
widget->interaction_data = data;
-
+
return OPERATOR_RUNNING_MODAL;
}
static int widget_rect_transform_handler(bContext *C, const wmEvent *event, wmWidget *widget)
{
- RectTransformWidget *cage = (RectTransformWidget *) widget;
+ RectTransformWidget *cage = (RectTransformWidget *)widget;
RectTransformInteraction *data = widget->interaction_data;
ARegion *ar = CTX_wm_region(C);
float valuex, valuey;
/* needed here as well in case clamping occurs */
- const float orig_ofx = cage->offset[0], orig_ofy = cage->offset[1];
-
+ const float orig_ofx = widget->offset[0], orig_ofy = widget->offset[1];
+
valuex = (event->mval[0] - data->orig_mouse[0]);
valuey = (event->mval[1] - data->orig_mouse[1]);
-
+
if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_TRANSLATE) {
- cage->offset[0] = data->orig_offset[0] + valuex;
- cage->offset[1] = data->orig_offset[1] + valuey;
+ widget->offset[0] = data->orig_offset[0] + valuex;
+ widget->offset[1] = data->orig_offset[1] + valuey;
}
else if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT) {
- cage->offset[0] = data->orig_offset[0] + valuex / 2.0;
+ widget->offset[0] = data->orig_offset[0] + valuex / 2.0;
cage->scale[0] = (cage->w * data->orig_scale[0] - valuex) / cage->w;
}
else if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT) {
- cage->offset[0] = data->orig_offset[0] + valuex / 2.0;
+ widget->offset[0] = data->orig_offset[0] + valuex / 2.0;
cage->scale[0] = (cage->w * data->orig_scale[0] + valuex) / cage->w;
}
else if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN) {
- cage->offset[1] = data->orig_offset[1] + valuey / 2.0;
-
+ widget->offset[1] = data->orig_offset[1] + valuey / 2.0;
+
if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
cage->scale[0] = (cage->h * data->orig_scale[0] - valuey) / cage->h;
}
@@ -1227,8 +1414,8 @@ static int widget_rect_transform_handler(bContext *C, const wmEvent *event, wmWi
}
}
else if (widget->highlighted_part == WIDGET_RECT_TRANSFORM_INTERSECT_SCALEY_UP) {
- cage->offset[1] = data->orig_offset[1] + valuey / 2.0;
-
+ widget->offset[1] = data->orig_offset[1] + valuey / 2.0;
+
if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
cage->scale[0] = (cage->h * data->orig_scale[0] + valuey) / cage->h;
}
@@ -1236,33 +1423,33 @@ static int widget_rect_transform_handler(bContext *C, const wmEvent *event, wmWi
cage->scale[1] = (cage->h * data->orig_scale[1] + valuey) / cage->h;
}
}
-
+
/* clamping - make sure widget is at least 5 pixels wide */
if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM) {
if (cage->scale[0] < WIDGET_RECT_MIN_WIDTH / cage->h ||
cage->scale[0] < WIDGET_RECT_MIN_WIDTH / cage->w)
{
cage->scale[0] = max_ff(WIDGET_RECT_MIN_WIDTH / cage->h, WIDGET_RECT_MIN_WIDTH / cage->w);
- cage->offset[0] = orig_ofx;
- cage->offset[1] = orig_ofy;
+ widget->offset[0] = orig_ofx;
+ widget->offset[1] = orig_ofy;
}
}
else {
if (cage->scale[0] < WIDGET_RECT_MIN_WIDTH / cage->w) {
cage->scale[0] = WIDGET_RECT_MIN_WIDTH / cage->w;
- cage->offset[0] = orig_ofx;
+ widget->offset[0] = orig_ofx;
}
if (cage->scale[1] < WIDGET_RECT_MIN_WIDTH / cage->h) {
cage->scale[1] = WIDGET_RECT_MIN_WIDTH / cage->h;
- cage->offset[1] = orig_ofy;
+ widget->offset[1] = orig_ofy;
}
}
-
+
if (widget->props[RECT_TRANSFORM_SLOT_OFFSET]) {
PointerRNA ptr = widget->ptr[RECT_TRANSFORM_SLOT_OFFSET];
PropertyRNA *prop = widget->props[RECT_TRANSFORM_SLOT_OFFSET];
- RNA_property_float_set_array(&ptr, prop, cage->offset);
+ RNA_property_float_set_array(&ptr, prop, widget->offset);
RNA_property_update(C, &ptr, prop);
}
@@ -1278,23 +1465,54 @@ static int widget_rect_transform_handler(bContext *C, const wmEvent *event, wmWi
}
RNA_property_update(C, &ptr, prop);
}
-
+
/* tag the region for redraw */
ED_region_tag_redraw(ar);
-
+
return OPERATOR_PASS_THROUGH;
}
static void widget_rect_transform_bind_to_prop(wmWidget *widget, const int slot)
{
RectTransformWidget *cage = (RectTransformWidget *) widget;
-
+
if (slot == RECT_TRANSFORM_SLOT_OFFSET)
- widget_rect_transform_get_property(widget, RECT_TRANSFORM_SLOT_OFFSET, cage->offset);
+ widget_rect_transform_get_property(widget, RECT_TRANSFORM_SLOT_OFFSET, widget->offset);
if (slot == RECT_TRANSFORM_SLOT_SCALE)
widget_rect_transform_get_property(widget, RECT_TRANSFORM_SLOT_SCALE, cage->scale);
}
+static void widget_rect_transform_cancel(bContext *C, wmWidget *widget)
+{
+ RectTransformWidget *cage = (RectTransformWidget *) widget;
+ RectTransformInteraction *data = widget->interaction_data;
+
+ /* reset properties */
+ if (widget->props[RECT_TRANSFORM_SLOT_OFFSET]) {
+ PointerRNA ptr = widget->ptr[RECT_TRANSFORM_SLOT_OFFSET];
+ PropertyRNA *prop = widget->props[RECT_TRANSFORM_SLOT_OFFSET];
+
+ RNA_property_float_set_array(&ptr, prop, data->orig_offset);
+ RNA_property_update(C, &ptr, prop);
+ }
+ if (widget->props[RECT_TRANSFORM_SLOT_SCALE]) {
+ PointerRNA ptr = widget->ptr[RECT_TRANSFORM_SLOT_SCALE];
+ PropertyRNA *prop = widget->props[RECT_TRANSFORM_SLOT_SCALE];
+
+ if (cage->style & WIDGET_RECT_TRANSFORM_STYLE_SCALE_UNIFORM){
+ RNA_property_float_set(&ptr, prop, data->orig_scale[0]);
+ }
+ else {
+ RNA_property_float_set_array(&ptr, prop, data->orig_scale);
+ }
+ RNA_property_update(C, &ptr, prop);
+ }
+}
+
+/** \name Cage Widget API
+ *
+ * \{ */
+
wmWidget *WIDGET_rect_transform_new(
wmWidgetGroup *wgroup, const char *name, const int style,
const float width, const float height)
@@ -1305,27 +1523,33 @@ wmWidget *WIDGET_rect_transform_new(
cage->widget.invoke = widget_rect_transform_invoke;
cage->widget.bind_to_prop = widget_rect_transform_bind_to_prop;
cage->widget.handler = widget_rect_transform_handler;
- cage->widget.intersect = widget_rect_tranfrorm_intersect;
- cage->widget.get_cursor = widget_rect_tranfrorm_get_cursor;
+ cage->widget.intersect = widget_rect_transform_intersect;
+ cage->widget.cancel = widget_rect_transform_cancel;
+ cage->widget.get_cursor = widget_rect_transform_get_cursor;
cage->widget.max_prop = 2;
+ cage->widget.flag |= WM_WIDGET_DRAW_ACTIVE;
cage->scale[0] = cage->scale[1] = 1.0f;
cage->style = style;
cage->w = width;
cage->h = height;
-
+
wm_widget_register(wgroup, &cage->widget, name);
-
+
return (wmWidget *)cage;
}
-void WIDGET_rect_transform_set_offset(wmWidget *widget, const float offset[2])
-{
- RectTransformWidget *cage = (RectTransformWidget *)widget;
+/** \} */ // Cage Widget API
+/** \} */ // Cage Widget
- copy_v2_v2(cage->offset, offset);
-}
-/********* Facemap widget ************/
+/** \name Facemap Widget
+ *
+ * 3D Widget
+ *
+ * \brief Widget representing shape of a face map.
+ * Currently no own handling, use with operator only.
+ *
+ * \{ */
typedef struct FacemapWidget {
wmWidget widget;
@@ -1340,7 +1564,10 @@ static void widget_facemap_draw(const bContext *C, wmWidget *widget)
FacemapWidget *fmap_widget = (FacemapWidget *)widget;
glPushMatrix();
glMultMatrixf(fmap_widget->ob->obmat);
+ glTranslate3fv(widget->offset);
+ glEnable(GL_MULTISAMPLE_ARB);
ED_draw_object_facemap(CTX_data_scene(C), fmap_widget->ob, fmap_widget->facemap);
+ glDisable(GL_MULTISAMPLE_ARB);
glPopMatrix();
}
@@ -1350,29 +1577,50 @@ static void widget_facemap_render_3d_intersect(const bContext *C, wmWidget *widg
widget_facemap_draw(C, widget);
}
+#if 0
+static int widget_facemap_invoke(bContext *UNUSED(C), const wmEvent *event, wmWidget *widget)
+{
+ return OPERATOR_PASS_THROUGH;
+}
+
+static int widget_facemap_handler(bContext *C, const wmEvent *event, wmWidget *widget)
+{
+ return OPERATOR_PASS_THROUGH;
+}
+#endif
-struct wmWidget *WIDGET_facemap_new(
+/** \name Facemap Widget API
+ *
+ * \{ */
+
+wmWidget *WIDGET_facemap_new(
wmWidgetGroup *wgroup, const char *name, const int style,
Object *ob, const int facemap)
{
FacemapWidget *fmap_widget = MEM_callocN(sizeof(FacemapWidget), "CageWidget");
fmap_widget->widget.draw = widget_facemap_draw;
-// fmap_widget->widget.invoke = NULL;
+// fmap_widget->widget.invoke = widget_facemap_invoke;
// fmap_widget->widget.bind_to_prop = NULL;
-// fmap_widget->widget.handler = NULL;
+// fmap_widget->widget.handler = widget_facemap_handler;
fmap_widget->widget.render_3d_intersection = widget_facemap_render_3d_intersect;
+ fmap_widget->widget.flag |= WM_WIDGET_SELECTABLE ;
fmap_widget->ob = ob;
fmap_widget->facemap = facemap;
fmap_widget->style = style;
-
+
wm_widget_register(wgroup, &fmap_widget->widget, name);
-
+
return (wmWidget *)fmap_widget;
}
+/** \} */ // Facemap Widget API
+/** \} */ // Facemap Widget
+
+
+/* -------------------------------------------------------------------- */
void fix_linking_widget_lib(void)
{
- (void) 0;
+ (void)0;
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 0f0e6c9b771..b0acc3c0f1e 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -5328,6 +5328,12 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_previews_ensure);
WM_operatortype_append(WM_OT_previews_clear);
WM_operatortype_append(WM_OT_doc_view_manual_ui_context);
+
+ /* widgets */
+ WM_operatortype_append(WIDGETGROUP_OT_widget_set_active);
+ WM_operatortype_append(WIDGETGROUP_OT_widget_set_select);
+ WM_operatortype_append(WIDGETGROUP_OT_widget_tweak);
+ WM_operatortype_append(WIDGETGROUP_OT_widget_tweak_cancel);
}
/* circleselect-like modal operators */
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);
}
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index c5a1d5f7f6d..f2bed99815d 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -49,12 +49,15 @@ typedef struct wmPaintCursor {
void (*draw)(bContext *C, int, int, void *customdata);
} wmPaintCursor;
-/* widgets are set per screen/area/region by registering them on widgetmaps */
+/* widgets are set per region by registering them on widgetmaps */
typedef struct wmWidget {
struct wmWidget *next, *prev;
-
+
char idname[MAX_NAME + 4]; /* + 4 for unique '.001', '.002', etc suffix */
+ /* pointer back to parent widget group */
+ wmWidgetGroup *wgroup;
+
/* draw widget */
void (*draw)(const struct bContext *C, struct wmWidget *widget);
/* determine if the mouse intersects with the widget. The calculation should be done in the callback itself */
@@ -76,14 +79,19 @@ typedef struct wmWidget {
/* activate a widget state when the user clicks on it */
int (*invoke)(struct bContext *C, const struct wmEvent *event, struct wmWidget *widget);
+ /* called after canceling widget handling - used to reset property */
+ void (*cancel)(struct bContext *C, struct wmWidget *widget);
+
int (*get_cursor)(struct wmWidget *widget);
-
- int flag; /* flags set by drawing and interaction, such as highlighting */
+
+ int flag; /* flags set by drawing and interaction, such as highlighting */
unsigned char highlighted_part;
/* center of widget in space, 2d or 3d */
float origin[3];
+ /* custom offset from origin */
+ float offset[3];
/* runtime property, set the scale while drawing on the viewport */
float scale;
@@ -104,26 +112,16 @@ typedef struct wmWidget {
const char *opname;
/* operator properties if widget spawns and controls an operator, or owner pointer if widget spawns and controls a property */
- struct PointerRNA opptr;
+ PointerRNA opptr;
/* maximum number of properties attached to the widget */
int max_prop;
-
+
/* arrays of properties attached to various widget parameters. As the widget is interacted with, those properties get updated */
- struct PointerRNA *ptr;
- struct PropertyRNA **props;
+ PointerRNA *ptr;
+ PropertyRNA **props;
} wmWidget;
-/* wmWidget->flag */
-enum widgetflags {
- /* states */
- WM_WIDGET_HIGHLIGHT = (1 << 0),
- WM_WIDGET_ACTIVE = (1 << 1),
- WM_WIDGET_DRAW_HOVER = (1 << 2),
- WM_WIDGET_SCALE_3D = (1 << 3),
- WM_WIDGET_SCENE_DEPTH = (1 << 4), /* widget is depth culled with scene objects*/
- WM_WIDGET_HIDDEN = (1 << 5),
-};
extern void wm_close_and_free(bContext *C, wmWindowManager *);
extern void wm_close_and_free_all(bContext *C, ListBase *);
@@ -171,8 +169,14 @@ void wm_open_init_load_ui(wmOperator *op, bool use_prefs);
void wm_open_init_use_scripts(wmOperator *op, bool use_prefs);
/* wm_widgets.c */
-bool wm_widgetmap_is_3d(const struct wmWidgetMap *wmap);
-bool wm_widget_register(struct wmWidgetGroup *wgroup, struct wmWidget *widget, const char *name);
+bool wm_widgetmap_is_3d(const wmWidgetMap *wmap);
+bool wm_widget_register(wmWidgetGroup *wgroup, wmWidget *widget, const char *name);
+void wm_widgets_keymap(wmKeyConfig *keyconf);
+
+void WIDGETGROUP_OT_widget_set_active(wmOperatorType *ot);
+void WIDGETGROUP_OT_widget_set_select(wmOperatorType *ot);
+void WIDGETGROUP_OT_widget_tweak(wmOperatorType *ot);
+void WIDGETGROUP_OT_widget_tweak_cancel(wmOperatorType *ot);
/* hack to store circle select size - campbell, must replace with nice operator memory */
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 46ebc15e165..2d9e5dbfc54 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -104,13 +104,18 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect);
void wm_widget_handler_modal_update(bContext *C, wmEvent *event, wmEventHandler *handler);
void wm_widgetmap_handler_context(bContext *C, wmEventHandler *handler);
-struct wmWidget *wm_widget_find_highlighted_3D(struct wmWidgetMap *wmap, struct bContext *C, const struct wmEvent *event, unsigned char *part);
-wmWidget *wm_widget_find_highlighted(struct wmWidgetMap *wmap, bContext *C, const struct wmEvent *event, unsigned char *part);
-void wm_widgetmap_set_highlighted_widget(struct wmWidgetMap *wmap, struct bContext *C, struct wmWidget *widget, unsigned char part);
-struct wmWidget *wm_widgetmap_get_highlighted_widget(struct wmWidgetMap *wmap);
+void wm_widgetgrouptype_keymap_init(wmWidgetGroupType *wgrouptype, wmKeyConfig *keyconf);
-void wm_widgetmap_set_active_widget(struct wmWidgetMap *wmap, struct bContext *C, struct wmEvent *event, struct wmWidget *widget, const bool call_op);
-struct wmWidget *wm_widgetmap_get_active_widget(struct wmWidgetMap *wmap);
+wmWidget *wm_widget_find_highlighted_3D(wmWidgetMap *wmap, bContext *C, const wmEvent *event, unsigned char *part);
+wmWidget *wm_widget_find_highlighted(wmWidgetMap *wmap, bContext *C, const wmEvent *event, unsigned char *part);
+void wm_widgetmap_set_highlighted_widget(wmWidgetMap *wmap, bContext *C, wmWidget *widget, unsigned char part);
+wmWidget *wm_widgetmap_get_highlighted_widget(wmWidgetMap *wmap);
+
+void wm_widgetmap_set_active_widget(wmWidgetMap *wmap, bContext *C, const wmEvent *event, wmWidget *widget);
+wmWidget *wm_widgetmap_get_active_widget(wmWidgetMap *wmap);
+
+void wm_widgetmap_set_selected_widget(bContext *C, wmWidgetMap *wmap, wmWidget *widget);
+wmWidget *wm_widgetmap_get_selected_widget(wmWidgetMap *wmap);
#endif /* __WM_EVENT_SYSTEM_H__ */