diff options
author | Diego Borghetti <bdiego@gmail.com> | 2008-01-19 20:54:05 +0300 |
---|---|---|
committer | Diego Borghetti <bdiego@gmail.com> | 2008-01-19 20:54:05 +0300 |
commit | b80049a139752fc9074d4d8a74019ccdef36936d (patch) | |
tree | 7bb5195ded66d61e210b3fac1b2e9c531f57cf03 /source/blender/windowmanager | |
parent | d7223cb3aaaa87a9afb0b84874997d57dc9323ae (diff) |
New "Gesture Manager" system.
This is a first implementation of the "gesture manager" system,
the idea is put the WM in a automatic draw mode so we can
implement different "Gesture types" to draw different class
of data (lasso, bound box, etc).
The gesture data is passed through the data field of the notifiers,
i think that we can change this to something like:
WM_gesture_init(C, data); /* put the data in the context. */
while() {
/* send WM_NOTE_GESTURE_CHANGED to update screen */
}
/* send event and free the data in the context. */
WM_gesture_end(C);
Also i add a new operator and event to test the gesture manager.
The new operator is the "border select" function, just press BKEY
in the window and LMB or ESCKEY to exit.
In the case of LMB you can see a print in the console about the
BORDERSELECT event.
All this still need a lot of work, comment are welcome.
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 11 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 17 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm.c | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 31 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_gesture.c | 95 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 106 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_types.h | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_gesture_types.h | 38 |
10 files changed, 295 insertions, 15 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index ae79492fd49..93bd3081f42 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -34,6 +34,7 @@ struct bContext; struct wmEvent; struct wmEventHandler; +struct wmGesture; /* general API */ void WM_setprefsize (int stax, int stay, int sizx, int sizy); @@ -67,8 +68,9 @@ struct wmEventHandler *WM_event_add_keymap_handler(ListBase *keymap, ListBase *h struct wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op); void WM_event_remove_modal_handler(ListBase *handlers, wmOperator *op); -void WM_event_add_notifier(wmWindowManager *wm, wmWindow *window, int swinid, int type, - int value); +void WM_event_add_notifier(wmWindowManager *wm, wmWindow *window, + int swinid, int type, + int value, void *data); /* operator api, default callbacks */ @@ -132,6 +134,11 @@ int OP_get_float_array(wmOperator *op, char *name, float *array, short *len); **/ void OP_free_property(wmOperator *op); + /* Gesture manager API */ +struct wmGesture *WM_gesture_new(int type); +struct wmGesture *WM_gesture_dup(struct wmGesture *from); +void WM_gesture_send(wmWindow *win, struct wmGesture *gesture); + /* OpenGL wrappers, mimicing opengl syntax */ void wmLoadMatrix (wmWindow *win, float mat[][4]); void wmGetMatrix (wmWindow *win, float mat[][4]); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 195fa3a0063..a0d1bc58ecb 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -32,6 +32,7 @@ #include "wm_cursors.h" #include "wm_event_types.h" +#include "wm_gesture_types.h" /* ************** wmOperatorType ************************ */ @@ -105,9 +106,21 @@ enum { WM_NOTE_OBJECT_CHANGED, WM_NOTE_AREA_SPLIT, WM_NOTE_AREA_DRAG, + WM_NOTE_GESTURE_CHANGED, WM_NOTE_LAST }; +/* ************** Gesture Manager data ************** */ +typedef struct wmGestureRect { + /* always this first!! */ + wmGesture gesture; + + short x1, x2; + short y1, y2; +} wmGestureRect; + +#define GESTURE_RECT 0 + /* ************** custom wmEvent data ************** */ #define DEV_STYLUS 1 @@ -120,6 +133,10 @@ typedef struct wmTabletData { float Ytilt; /* as above */ } wmTabletData; +typedef struct wmBorderSelect { + short x1, y1; + short x2, y2; +} wmBorderSelect; /* *************** migrated stuff, clean later? ******************************** */ diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index fb8d0f7503f..bc24895874e 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -79,6 +79,7 @@ static void wm_window_keymap(wmWindowManager *wm) WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0); WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_border_select", BKEY, KM_PRESS, 0, 0); } /* ****************************************** */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 4e5388257a6..bb0ad54d967 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -55,7 +55,7 @@ /* ************ event management ************** */ -static void wm_event_add(wmWindow *win, wmEvent *event_to_add) +void wm_event_add(wmWindow *win, wmEvent *event_to_add) { wmEvent *event= MEM_callocN(sizeof(wmEvent), "event"); @@ -90,7 +90,7 @@ void wm_event_free_all(wmWindow *win) /* ********************* notifiers, listeners *************** */ /* win and swinid are optional context limitors */ -void WM_event_add_notifier(wmWindowManager *wm, wmWindow *window, int swinid, int type, int value) +void WM_event_add_notifier(wmWindowManager *wm, wmWindow *window, int swinid, int type, int value, void *data) { wmNotifier *note= MEM_callocN(sizeof(wmNotifier), "notifier"); @@ -100,6 +100,7 @@ void WM_event_add_notifier(wmWindowManager *wm, wmWindow *window, int swinid, in note->swinid= swinid; note->type= type; note->value= value; + note->data= data; } static wmNotifier *wm_notifier_next(wmWindowManager *wm) @@ -126,7 +127,7 @@ void wm_event_do_notifiers(bContext *C) if(win->screen==NULL) continue; printf("notifier win %d screen %s\n", win->winid, win->screen->id.name+2); - ED_screen_do_listen(win->screen, note); + ED_screen_do_listen(win, note); for(sa= win->screen->areabase.first; sa; sa= sa->next) { ARegion *ar= sa->regionbase.first; @@ -138,6 +139,8 @@ void wm_event_do_notifiers(bContext *C) } } } + if(note->data) + MEM_freeN(note->data); MEM_freeN(note); } } @@ -151,7 +154,9 @@ static int wm_draw_update_test_window(wmWindow *win) return 1; if(win->screen->do_draw) return 1; - + if(win->screen->do_gesture) + return 1; + for(sa= win->screen->areabase.first; sa; sa= sa->next) { ARegion *ar= sa->regionbase.first; @@ -201,6 +206,9 @@ void wm_draw_update(bContext *C) if(win->screen->do_draw) ED_screen_draw(win); + if(win->screen->do_gesture) + ED_screen_gesture(win); + wm_window_swap_buffers(win); } } @@ -301,21 +309,23 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) event->keymap_idname= km->idname; /* weak, but allows interactive callback to not use rawkey */ action= wm_handler_operator_call(C, handler, event); + if(action==WM_HANDLER_BREAK) + break; } } - if(action==WM_HANDLER_BREAK) - break; } else { /* modal, swallows all */ action= wm_handler_operator_call(C, handler, event); - if(action==WM_HANDLER_BREAK) - break; } - + /* modal+blocking handler */ if(handler->flag & WM_HANDLER_BLOCKING) action= WM_HANDLER_BREAK; + + if(action==WM_HANDLER_BREAK) + break; + } return action; } @@ -341,6 +351,9 @@ void wm_event_do_handlers(bContext *C) while( (event=wm_event_next(win)) ) { int action; + if(event->type==BORDERSELECT) + printf("BORDERSELECT Event!!\n"); + /* MVC demands to not draw in event handlers... for now we leave it */ /* it also updates context (win, screen) */ wm_window_make_drawable(C, win); diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c new file mode 100644 index 00000000000..99f94b49537 --- /dev/null +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -0,0 +1,95 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "DNA_windowmanager_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + + +wmGesture *WM_gesture_new(int type) +{ + wmGesture *gesture= NULL; + wmGestureRect *rect; + + if(type==GESTURE_RECT) { + gesture= rect= MEM_mallocN(sizeof(wmGestureRect), "gesture rect new"); + gesture->type= type; + rect->x1= 0; + rect->y1= 0; + rect->x2= 1; + rect->y2= 1; + } + return(gesture); +} + +void wm_gesture_rect_copy(wmGestureRect *to, wmGestureRect *from) +{ + to->x1= from->x1; + to->x2= from->x2; + to->y1= from->y1; + to->y2= from->y2; +} + +wmGesture *WM_gesture_dup(wmGesture *from) +{ + wmGesture *to= WM_gesture_new(from->type); + + if(from->type==GESTURE_RECT) + wm_gesture_rect_copy((wmGestureRect *) to, (wmGestureRect *) from); + return (to); +} + +void WM_gesture_send(wmWindow *win, wmGesture *gesture) +{ + wmGestureRect *rect; + wmBorderSelect *wmbor; + wmEvent event; + + if(gesture->type==GESTURE_RECT) { + rect= (wmGestureRect*)gesture; + + wmbor= MEM_mallocN(sizeof(wmBorderSelect), "border select"); + wmbor->x1= rect->x1; + wmbor->y1= rect->y1; + wmbor->x2= rect->x2; + wmbor->y2= rect->y2; + + event.type= BORDERSELECT; + event.custom= EVT_GESTURE; + event.customdata= wmbor; + wm_event_add(win, &event); + } +} diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index c9fca2a38d2..b1b9d345c3a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -126,7 +126,110 @@ static void WM_OT_exit_blender(wmOperatorType *ot) ot->poll= WM_operator_winactive; } +/* ************ window / screen border operator definitions ************** */ +/* + * This is and example of global operator working with + * the gesture system. + */ +static int border_select_init(bContext *C, wmOperator *op) +{ + OP_set_int(op, "start_x", op->veci.x); + OP_set_int(op, "start_y", op->veci.y); + return 1; +} + +static int border_select_exec(bContext *C, wmOperator *op) +{ + wmGestureRect *rect; + int x, y; + + OP_get_int(op, "start_x", &x); + OP_get_int(op, "start_y", &y); + + rect= (wmGestureRect *) WM_gesture_new(GESTURE_RECT); + rect->x1= x; + rect->y1= y; + rect->x2= op->veci.x; + rect->y2= op->veci.y; + WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_GESTURE_CHANGED, 0, rect); + return 1; +} + +static int border_select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + /* operator arguments and storage. */ + op->properties= NULL; + op->veci.x= event->x; + op->veci.y= event->y; + + if(0==border_select_init(C, op)) + return 1; + + /* add temp handler */ + WM_event_add_modal_handler(&C->window->handlers, op); + return 0; +} + +static int border_select_exit(bContext *C, wmOperator *op) +{ + WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); + OP_free_property(op); + return 1; +} + +static int border_select_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + switch(event->type) { + case MOUSEMOVE: + op->veci.x= event->x; + op->veci.y= event->y; + border_select_exec(C, op); + WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); + break; + case LEFTMOUSE: + if(event->val==0) { + wmGestureRect *rect; + int x, y; + + OP_get_int(op, "start_x", &x); + OP_get_int(op, "start_y", &y); + + rect= (wmGestureRect *) WM_gesture_new(GESTURE_RECT); + rect->x1= x; + rect->y1= y; + rect->x2= op->veci.x; + rect->y2= op->veci.y; + WM_gesture_send(C->window, (wmGesture *) rect); + MEM_freeN(rect); + + border_select_exit(C, op); + WM_event_remove_modal_handler(&C->window->handlers, op); + } + break; + case ESCKEY: + WM_event_remove_modal_handler(&C->window->handlers, op); + border_select_exit(C, op); + break; + } + return 1; +} + +void WM_OT_border_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Border select"; + ot->idname= "WM_OT_border_select"; + + ot->init= border_select_init; + ot->invoke= border_select_invoke; + ot->modal= border_select_modal; + ot->exec= border_select_exec; + ot->exit= border_select_exit; + + ot->poll= WM_operator_winactive; +} + #define ADD_OPTYPE(opfunc) ot= MEM_callocN(sizeof(wmOperatorType), "operatortype"); \ opfunc(ot); \ BLI_addtail(&global_ops, ot) @@ -145,8 +248,9 @@ void wm_operatortype_init(void) ADD_OPTYPE(WM_OT_window_duplicate); ADD_OPTYPE(WM_OT_save_homefile); - ADD_OPTYPE(WM_OT_window_fullscreen_toggle); + ADD_OPTYPE(WM_OT_window_fullscreen_toggle); ADD_OPTYPE(WM_OT_exit_blender); + ADD_OPTYPE(WM_OT_border_select); } /* wrapped to get property from a operator. */ diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index cde600eaeae..e597eb9fef3 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -406,7 +406,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) printf("ghost redraw\n"); wm_window_make_drawable(C, win); - WM_event_add_notifier(C->wm, win, 0, WM_NOTE_WINDOW_REDRAW, 0); + WM_event_add_notifier(C->wm, win, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL); break; } @@ -446,13 +446,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) } wm_window_make_drawable(C, win); - WM_event_add_notifier(C->wm, win, 0, WM_NOTE_SCREEN_CHANGED, 0); + WM_event_add_notifier(C->wm, win, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL); break; } default: if(type==GHOST_kEventKeyDown) // XXX debug - WM_event_add_notifier(C->wm, win, 0, WM_NOTE_WINDOW_REDRAW, 0); + WM_event_add_notifier(C->wm, win, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL); wm_event_add_ghostevent(win, type, data); break; } diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 54cf45db61d..cbaef2a8c30 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -62,6 +62,7 @@ enum { }; +void wm_event_add(wmWindow *win, wmEvent *event_to_add); void wm_event_free_all (wmWindow *win); wmEvent *wm_event_next (wmWindow *win); void wm_event_free_handlers (ListBase *lb); diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index c6c9046d79e..842bf0fce84 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -37,6 +37,7 @@ /* custom data type */ #define EVT_TABLET 1 +#define EVT_GESTURE 2 #define MOUSEX 0x004 #define MOUSEY 0x005 @@ -252,5 +253,8 @@ #define REDRAWMARKER 0x4040 /* all views that display markers */ #define REDRAWVIEW3D_IMAGE 0x4041 +/* **************** BLENDER GESTURE EVENTS ********************* */ +#define BORDERSELECT 0x5000 + #endif /* WM_EVENT_TYPES_H */ diff --git a/source/blender/windowmanager/wm_gesture_types.h b/source/blender/windowmanager/wm_gesture_types.h new file mode 100644 index 00000000000..e412080a7ef --- /dev/null +++ b/source/blender/windowmanager/wm_gesture_types.h @@ -0,0 +1,38 @@ +/* + * $Id: wm_gesture_types.h + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef WM_GESTURE_TYPES_H +#define WM_GESTURE_TYPES_H + +typedef struct wmGesture { + /* gesture type. */ + short type; +} wmGesture; + +#endif /* WM_GESTURE_TYPES_H */ + |