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_event_system.c')
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c106
1 files changed, 103 insertions, 3 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 15b155c8649..8b4fdfb3021 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1455,6 +1455,40 @@ static void wm_handler_op_context(bContext *C, wmEventHandler *handler, const wm
}
}
+static void wm_handler_widgetmap_context(bContext *C, wmEventHandler *handler)
+{
+ bScreen *screen = CTX_wm_screen(C);
+
+ if (screen) {
+ if (handler->op_area == NULL) {
+ /* do nothing in this context */
+ }
+ else {
+ ScrArea *sa;
+
+ for (sa = screen->areabase.first; sa; sa = sa->next)
+ if (sa == handler->op_area)
+ break;
+ if (sa == NULL) {
+ /* when changing screen layouts with running modal handlers (like render display), this
+ * is not an error to print */
+ if (handler->widgetmap == NULL)
+ printf("internal error: modal widgetmap handler has invalid area\n");
+ }
+ else {
+ ARegion *ar;
+ CTX_wm_area_set(C, sa);
+ for (ar = sa->regionbase.first; ar; ar = ar->next)
+ if (ar == handler->op_region)
+ break;
+ /* XXX no warning print here, after full-area and back regions are remade */
+ if (ar)
+ CTX_wm_region_set(C, ar);
+ }
+ }
+ }
+}
+
/* called on exit or remove area, only here call cancel callback */
void WM_event_remove_handlers(bContext *C, ListBase *handlers)
{
@@ -1478,7 +1512,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
if (handler->op->type->flag & OPTYPE_UNDO)
wm->op_undo_depth--;
-
+
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
}
@@ -1665,8 +1699,8 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
/* warning, after this call all context data and 'event' may be freed. see check below */
retval = ot->modal(C, op, event);
+
OPERATOR_RETVAL_CHECK(retval);
-
/* when this is _not_ the case the modal modifier may have loaded
* a new blend file (demo mode does this), so we have to assume
* the event, operator etc have all been freed. - campbell */
@@ -2060,7 +2094,72 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
}
}
}
+ else if (handler->widgetmap) {
+ struct 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);
+
+ wm_handler_widgetmap_context(C, handler);
+ wm_region_mouse_co(C, event);
+
+ switch (event->type) {
+ case MOUSEMOVE:
+ if (widget) {
+ widget->handler(C, event, widget);
+ event_processed = EVT_WIDGET_UPDATE;
+ action |= WM_HANDLER_BREAK;
+ }
+ else 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);
+ }
+ break;
+
+ case LEFTMOUSE:
+ {
+ if (widget) {
+ if (event->val == KM_RELEASE) {
+ wm_widgetmap_set_active_widget(wmap, C, event, NULL, false);
+ event_processed = EVT_WIDGET_RELEASED;
+ action |= WM_HANDLER_BREAK;
+ }
+ else {
+ action |= WM_HANDLER_BREAK;
+ }
+ }
+ else if (event->val == KM_PRESS) {
+ widget = wm_widgetmap_get_highlighted_widget(wmap);
+
+ if (widget) {
+ wm_widgetmap_set_active_widget(wmap, C, event, widget, handler->op == NULL);
+ action |= WM_HANDLER_BREAK;
+ }
+ }
+ break;
+ }
+ }
+
+ /* restore the area */
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+
+ if (handler->op) {
+ /* if event was processed by an active widget pass the modified event to the operator */
+ if (event_processed) {
+ event->type = event_processed;
+ }
+ action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
+ }
+ }
else {
+ /* handle the widget first, before passing the event down */
/* modal, swallows all */
action |= wm_handler_operator_call(C, handlers, handler, event, NULL);
}
@@ -2613,7 +2712,7 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
{
wmEventHandler *handler = MEM_callocN(sizeof(wmEventHandler), "event modal handler");
wmWindow *win = CTX_wm_window(C);
-
+
/* operator was part of macro */
if (op->opm) {
/* give the mother macro to the handler */
@@ -3578,6 +3677,7 @@ void WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4])
angle = WM_event_ndof_to_axis_angle(ndof, axis);
axis_angle_to_quat(q, axis, angle);
}
+/** \} */
/* if this is a tablet event, return tablet pressure and set *pen_flip
* to 1 if the eraser tool is being used, 0 otherwise */