More change to the gesture manager.

After check this a little more I make some changes to the
API and now work on the following form:
	WM_gesture_init(C, type);

	while() {
		/* handler event, etc */
		/* if something change. */
		if(need_update) {
			/* update the gesture data and notify about it. */
			WM_gesture_update(C, data);
			WM_event_add_notifier (.. WM_NOTE_GESTURE_CHANGE ..);
		}
	}
	WM_gesture_end(C, type);

Another of the change is that now the gesture data is a link list
in the window struct, so we can have multiples "gestures" (but
of different type) at the same time.

Also take care that the "gesture data" is reusable, that mean that
only alloc it 1 time and use in all the place, that is
why don't support multiple gesture of the same type, but of course
that can be change.
This commit is contained in:
Diego Borghetti
2008-01-19 21:54:33 +00:00
parent b80049a139
commit 0db1aed7e1
7 changed files with 102 additions and 42 deletions

View File

@@ -51,17 +51,21 @@
#include "screen_intern.h" /* own module include */
/* ******************* gesture manager ******************* */
void ed_gesture_draw_rect(wmWindow *win)
void ed_gesture_draw_rect(wmWindow *win, wmGesture *gt)
{
wmGestureRect *rect= (wmGestureRect *)win->gesture;
wmGestureRect *rect= (wmGestureRect *)gt;
sdrawbox(rect->x1, rect->y1, rect->x2, rect->y2);
}
void ed_gesture_update(wmWindow *win)
{
wmGesture *gesture= (wmGesture *)win->gesture;
if(gesture->type==GESTURE_RECT)
ed_gesture_draw_rect(win);
wmGesture *gt= (wmGesture *)win->gesture.first;
while(gt) {
if(gt->type==GESTURE_RECT)
ed_gesture_draw_rect(win, gt);
gt= gt->next;
}
}
/* ******************* screen vert, edge, area managing *********************** */
@@ -786,7 +790,6 @@ void ED_screen_do_listen(wmWindow *win, wmNotifier *note)
case WM_NOTE_GESTURE_CHANGED:
printf("WM_NOTE_GESTURE_CHANGED\n");
win->screen->do_gesture= 1;
win->gesture= WM_gesture_dup((wmGesture *) note->data);
break;
}
}
@@ -809,10 +812,8 @@ void ED_screen_gesture(wmWindow *win)
{
printf("gesture draw screen\n");
if(win->gesture) {
if(win->gesture.first) {
ed_gesture_update(win);
MEM_freeN(win->gesture);
win->gesture= NULL;
}
win->screen->do_gesture= 0;
}

View File

@@ -97,7 +97,7 @@ typedef struct wmWindow {
ListBase handlers; /* window+screen handlers, overriding all queues */
ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */
void *gesture; /* gesture stuff. */
ListBase gesture; /* gesture stuff */
} wmWindow;
#

View File

@@ -135,9 +135,10 @@ 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);
void WM_gesture_init(bContext *C, int type);
void WM_gesture_update(bContext *C, struct wmGesture *from);
void WM_gesture_end(bContext *C, int type);
void WM_gesture_free(wmWindow *win);
/* OpenGL wrappers, mimicing opengl syntax */
void wmLoadMatrix (wmWindow *win, float mat[][4]);

View File

@@ -32,20 +32,36 @@
#include "BLI_blenlib.h"
#include "BKE_global.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm_event_system.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
wmGesture *WM_gesture_new(int type)
wmGesture *wm_gesture_find(ListBase *list, int type)
{
wmGesture *gt= list->first;
while(gt) {
if(gt->type==type)
return(gt);
gt= gt->next;
}
return(NULL);
}
wmGesture *wm_gesture_new(int type)
{
wmGesture *gesture= NULL;
wmGestureRect *rect;
if(type==GESTURE_RECT) {
gesture= rect= MEM_mallocN(sizeof(wmGestureRect), "gesture rect new");
rect= MEM_mallocN(sizeof(wmGestureRect), "gesture rect new");
gesture= (wmGesture*) rect;
gesture->type= type;
rect->x1= 0;
rect->y1= 0;
@@ -55,6 +71,19 @@ wmGesture *WM_gesture_new(int type)
return(gesture);
}
void WM_gesture_init(bContext *C, int type)
{
wmGesture *gt= NULL;
if(C->window) {
gt= wm_gesture_find(&C->window->gesture, type);
if(!gt) {
gt= wm_gesture_new(type);
BLI_addtail(&C->window->gesture, gt);
}
}
}
void wm_gesture_rect_copy(wmGestureRect *to, wmGestureRect *from)
{
to->x1= from->x1;
@@ -63,23 +92,46 @@ void wm_gesture_rect_copy(wmGestureRect *to, wmGestureRect *from)
to->y2= from->y2;
}
wmGesture *WM_gesture_dup(wmGesture *from)
void WM_gesture_update(bContext *C, wmGesture *from)
{
wmGesture *to= WM_gesture_new(from->type);
wmGesture *to;
if(from->type==GESTURE_RECT)
wm_gesture_rect_copy((wmGestureRect *) to, (wmGestureRect *) from);
return (to);
if(!C->window)
return;
to= wm_gesture_find(&C->window->gesture, from->type);
if(!to)
return;
printf("found gesture!!\n");
if(to->type==GESTURE_RECT)
wm_gesture_rect_copy((wmGestureRect*)to, (wmGestureRect*)from);
}
void WM_gesture_send(wmWindow *win, wmGesture *gesture)
void WM_gesture_free(wmWindow *win)
{
/* Now don't have multiple struct so
* a simple BLI_freelistN is what we need.
*/
BLI_freelistN(&win->gesture);
}
void WM_gesture_end(bContext *C, int type)
{
wmGesture *gt;
wmGestureRect *rect;
wmBorderSelect *wmbor;
wmEvent event;
if(gesture->type==GESTURE_RECT) {
rect= (wmGestureRect*)gesture;
if(!C->window)
return;
gt= wm_gesture_find(&C->window->gesture, type);
if(!gt)
return;
if(gt->type==GESTURE_RECT) {
rect= (wmGestureRect*)gt;
wmbor= MEM_mallocN(sizeof(wmBorderSelect), "border select");
wmbor->x1= rect->x1;
@@ -90,6 +142,6 @@ void WM_gesture_send(wmWindow *win, wmGesture *gesture)
event.type= BORDERSELECT;
event.custom= EVT_GESTURE;
event.customdata= wmbor;
wm_event_add(win, &event);
wm_event_add(C->window, &event);
}
}

View File

@@ -135,24 +135,26 @@ 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);
WM_gesture_init(C, GESTURE_RECT);
return 1;
}
static int border_select_exec(bContext *C, wmOperator *op)
{
wmGestureRect *rect;
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);
rect.gesture.next= rect.gesture.prev= NULL;
rect.gesture.type= GESTURE_RECT;
rect.x1= x;
rect.y1= y;
rect.x2= op->veci.x;
rect.y2= op->veci.y;
WM_gesture_update(C, (wmGesture *) &rect);
WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_GESTURE_CHANGED, GESTURE_RECT, NULL);
return 1;
}
@@ -189,19 +191,20 @@ static int border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case LEFTMOUSE:
if(event->val==0) {
wmGestureRect *rect;
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);
rect.gesture.next= rect.gesture.prev= NULL;
rect.gesture.type= GESTURE_RECT;
rect.x1= x;
rect.y1= y;
rect.x2= op->veci.x;
rect.y2= op->veci.y;
WM_gesture_update(C, (wmGesture*)&rect);
WM_gesture_end(C, GESTURE_RECT);
border_select_exit(C, op);
WM_event_remove_modal_handler(&C->window->handlers, op);

View File

@@ -106,7 +106,8 @@ void wm_window_free(bContext *C, wmWindow *win)
/* XXX free screens */
if(win->eventstate) MEM_freeN(win->eventstate);
WM_gesture_free(win);
wm_event_free_handlers(&win->handlers);
wm_event_free_all(win);
wm_subwindows_free(win);

View File

@@ -30,8 +30,10 @@
#define WM_GESTURE_TYPES_H
typedef struct wmGesture {
struct wmGesture *next, *prev;
/* gesture type. */
short type;
int type;
} wmGesture;
#endif /* WM_GESTURE_TYPES_H */