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')
-rw-r--r--source/blender/editors/interface/interface_ops.c23
-rw-r--r--source/blender/editors/screen/screen_ops.c6
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/WM_types.h3
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c51
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c7
6 files changed, 64 insertions, 27 deletions
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 2d515aafc13..aa09a0a7ba7 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -2676,8 +2676,11 @@ static void button_activate_init(bContext *C, ARegion *ar, wmOperator *op, uiBut
if(but->block->auto_open_last+BUTTON_AUTO_OPEN_THRESH < PIL_check_seconds_timer())
but->block->auto_open= 0;
- /* modal handler */
- WM_event_add_modal_handler(C, &C->window->handlers, op);
+ if(but->block->flag & UI_BLOCK_LOOP)
+ WM_event_add_modal_handler(C, &C->window->handlers, op);
+ else
+ /* regular button handler on area, handles mouse-exit in WM */
+ WM_event_add_modal_handler(C, &C->area->handlers, op);
button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
@@ -2791,19 +2794,19 @@ static int button_activate_try_exit(bContext *C, wmOperator *op, wmEvent *event)
ARegion *ar;
uiActivateBut *data;
uiBut *but;
- int state= OPERATOR_FINISHED;
data= op->customdata;
ar= data->region;
but= ui_but_find_activated(data->region, data, NULL);
- /* exit the current button, but try to re-init as well */
+ /* exit the current button */
button_activate_exit(C, op->customdata, op);
- /* XXX re-init has to be done differently... */
- /* XXX state= button_activate_try_init(C, ar, op, event, but); */
+
+ /* adds empty mousemove in queue for re-init operator (if mouse is still over button) */
+ WM_event_add_mousemove(C);
- return (state != OPERATOR_RUNNING_MODAL);
+ return 1;
}
static int button_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
@@ -2837,10 +2840,8 @@ static int button_activate_modal(bContext *C, wmOperator *op, wmEvent *event)
/* check if the button dissappeared somehow */
if(!(but= ui_but_find_activated(data->region, data, &block))) {
data->cancel= 1;
- if(button_activate_try_exit(C, op, event))
- return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
- else
- return OPERATOR_RUNNING_MODAL|OPERATOR_PASS_THROUGH;
+ button_activate_try_exit(C, op, event);
+ return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
}
if(data->state == BUTTON_STATE_HIGHLIGHT) {
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 095f6e1a74b..ef8b47a368f 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -278,13 +278,17 @@ static int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event)
} else {
WM_set_cursor(C, CURSOR_X_MOVE);
}
- } else {
+ return OPERATOR_FINISHED;
+ }
+ else {
ScrArea *sa= NULL;
AZone *az= NULL;
+
for(sa= C->screen->areabase.first; sa; sa= sa->next) {
az= is_in_area_actionzone(sa, event->x, event->y);
if(az!=NULL) break;
}
+
if(az!=NULL) WM_set_cursor(C, CURSOR_EDIT);
else WM_set_cursor(C, CURSOR_STD);
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 4b9c01b3e33..509056bfe71 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -75,6 +75,7 @@ void WM_event_remove_handlers (bContext *C, ListBase *handlers);
void WM_event_add_message(wmWindowManager *wm, void *customdata,
short customdatafree);
+void WM_event_add_mousemove(bContext *C);
void WM_event_add_notifier(wmWindowManager *wm, wmWindow *window,
int swinid, int type,
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 35dad1f0db2..be0fbb4fca6 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -47,7 +47,8 @@ typedef struct wmEvent {
short type; /* event code itself (short, is also in keymap) */
short val; /* press, release, scrollvalue */
- short x, y; /* mouse pointer position */
+ short x, y; /* mouse pointer position */
+ short prevx, prevy; /* previous mouse pointer position */
short unicode; /* future, ghost? */
char ascii; /* from ghost */
char pad1;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 9432036b4bc..85cf0786403 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -326,7 +326,6 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
/* C is zero on freeing database, modal handlers then already were freed */
while((handler=handlers->first)) {
- /* we have to remove the handler first, to prevent op->type->cancel() to remove modal handler too */
BLI_remlink(handlers, handler);
if(C && handler->op) {
@@ -473,18 +472,30 @@ static int wm_event_inside_i(wmEvent *event, rcti *rect)
return BLI_in_rcti(rect, event->x, event->y);
}
+static int wm_event_prev_inside_i(wmEvent *event, rcti *rect)
+{
+ if(BLI_in_rcti(rect, event->x, event->y))
+ return 1;
+ if(event->type==MOUSEMOVE) {
+ if( BLI_in_rcti(rect, event->prevx, event->prevy)) {
+ return 1;
+ }
+ return 0;
+ }
+ return 0;
+}
+
static ScrArea *area_event_inside(bContext *C, wmEvent *event)
{
ScrArea *sa;
if(C->screen)
for(sa= C->screen->areabase.first; sa; sa= sa->next)
- if(wm_event_inside_i(event, &sa->totrct))
+ if(BLI_in_rcti(&sa->totrct, event->x, event->y))
return sa;
return NULL;
}
-
/* called in main loop */
/* goes over entire hierarchy: events -> window -> screen -> area -> region */
void wm_event_do_handlers(bContext *C)
@@ -503,10 +514,10 @@ void wm_event_do_handlers(bContext *C)
C->window= win;
C->screen= win->screen;
C->area= area_event_inside(C, event);
-
+
/* MVC demands to not draw in event handlers... for now we leave it */
wm_window_make_drawable(C, win);
-
+
action= wm_handlers_do(C, event, &win->handlers);
/* modal menus in Blender use (own) regions linked to screen */
@@ -532,9 +543,11 @@ void wm_event_do_handlers(bContext *C)
if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
ScrArea *sa;
ARegion *ar;
+ int doit= 0;
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
- if(wm_event_always_pass(event) || wm_event_inside_i(event, &sa->totrct)) {
+ if(wm_event_always_pass(event) || wm_event_prev_inside_i(event, &sa->totrct)) {
+ doit= 1;
C->area= sa;
action= wm_handlers_do(C, event, &sa->handlers);
@@ -546,24 +559,26 @@ void wm_event_do_handlers(bContext *C)
C->region= NULL;
if(!wm_event_always_pass(event)) {
- action= WM_HANDLER_BREAK;
- break;
+ if(action==WM_HANDLER_BREAK)
+ break;
}
}
}
}
C->area= NULL;
-
- if(!wm_event_always_pass(event)) {
- action= WM_HANDLER_BREAK;
- break;
- }
+ /* NOTE: do not escape on WM_HANDLER_BREAK, mousemove needs handled for previous area */
}
}
+ /* XXX hrmf, this gives reliable previous mouse coord for area change, feels bad?
+ doing it on ghost queue gives errors when mousemoves go over area borders */
+ if(doit) {
+ C->window->eventstate->prevx= event->x;
+ C->window->eventstate->prevy= event->y;
+ }
}
wm_event_free(event);
-
+
C->window= NULL;
C->screen= NULL;
}
@@ -643,6 +658,14 @@ void WM_event_add_message(wmWindowManager *wm, void *customdata, short customdat
}
}
+void WM_event_add_mousemove(bContext *C)
+{
+ wmEvent event= *(C->window->eventstate);
+ event.type= MOUSEMOVE;
+ wm_event_add(C->window, &event);
+
+}
+
/* ********************* ghost stuff *************** */
static int convert_key(GHOST_TKey key)
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index fb8101168e2..3346f0607a9 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -164,6 +164,7 @@ void WM_exit(bContext *C)
/* modal handlers are on window level freed, others too? */
if(C && C->wm) {
for(win= C->wm->windows.first; win; win= win->next) {
+ ScrArea *sa;
ARegion *ar;
C->window= win; /* needed by operator close callbacks */
@@ -171,6 +172,12 @@ void WM_exit(bContext *C)
for(ar= win->screen->regionbase.first; ar; ar= ar->next)
WM_event_remove_handlers(C, &ar->handlers);
+
+ for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+ WM_event_remove_handlers(C, &sa->handlers);
+ for(ar= sa->regionbase.first; ar; ar= ar->next)
+ WM_event_remove_handlers(C, &ar->handlers);
+ }
}
}
wm_operatortype_free();