forked from bartvdbraak/blender
2.5
- after closing button (having used it), it sends empty mousemove for invoking new modal handler on same button. Don't know better solution for now, at least this way WM handles everything. :) - experiment: moved button handlers to area level, that way it respects handlers on higher hierarchical level, like moving area edges. Als interesting is that you can have a button active (texteditor) and use a similar button in other area. This can also be done on region level even. On todo: proper notifier events for redraw! Don't want all areas to draw on simple refreshes
This commit is contained in:
parent
6a6b386832
commit
d27c9f9d76
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user