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:
authorTon Roosendaal <ton@blender.org>2008-11-24 13:45:36 +0300
committerTon Roosendaal <ton@blender.org>2008-11-24 13:45:36 +0300
commit41ac50b3d3ed17ead1ffd4cbba188880bb20cfea (patch)
treece6707375fac4224ea39e615ef7fd6de64feebe5 /source/blender/windowmanager
parentaf6b221107ab998a37bccf1e89ac96525a519b97 (diff)
Work on gesture, some more cleaning.
- Added standard "tweak" gesture operator, which can be set per region, to generate EVT_TWEAK events. You can configure tweaks for any mouse button and have handlers for such events check for modifiers etc. It even stores tweak direction (8 directions). Might be fun to experiment with tweak gestures N, S, etc. :) In general it can be used to replace the current tweak code in 2.48 (std_rmouse_transform). Test added: on screen level it now adds LMB tweaks, if tweak-South it splits the area. Will be removed of course. - Added to Border operator a property to store event used to end border with. - Moved the "AZone" triangle drawing to the right context (area). It was on screen level, not respecting area-redraws. Also cleaned up drawing for it, and moved the "swap buffers indicator" square to look nicer. Those squares are only for test! - event-match function had bad code for checking for event-value. Made a "KM_ANY" define so keymaps can be defined ignoring event values. - Gesture todo: lasso, "real gesture" (like blender now has)
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r--source/blender/windowmanager/WM_api.h3
-rw-r--r--source/blender/windowmanager/WM_types.h22
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c26
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c69
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c3
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c100
-rw-r--r--source/blender/windowmanager/wm.h1
-rw-r--r--source/blender/windowmanager/wm_event_types.h32
8 files changed, 224 insertions, 32 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index cb2bc80dfd2..9b2c1409887 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -103,6 +103,9 @@ void WM_operator_cancel (struct bContext *C, ListBase *modalops, wmOperatorTyp
int WM_border_select_invoke (struct bContext *C, wmOperator *op, struct wmEvent *event);
int WM_border_select_modal (struct bContext *C, wmOperator *op, struct wmEvent *event);
+ /* default operator for arearegions, generates event */
+void WM_OT_tweak_gesture(wmOperatorType *ot);
+
/* Gesture manager API */
struct wmGesture *WM_gesture_new(struct bContext *C, struct wmEvent *event, int type);
void WM_gesture_end(struct bContext *C, struct wmGesture *gesture);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index adf4e2226b0..35dad1f0db2 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -81,8 +81,9 @@ typedef struct wmEvent {
#define KM_OSKEY2 128
/* val */
-#define KM_PRESS 2
-#define KM_RELEASE 1
+#define KM_ANY -1
+#define KM_RELEASE 0
+#define KM_PRESS 1
/* ************** notifiers ****************** */
@@ -113,17 +114,20 @@ enum {
/* ************** Gesture Manager data ************** */
/* wmGesture->type */
-#define WM_GESTURE_LINE 0
-#define WM_GESTURE_RECT 1
-#define WM_GESTURE_CROSS_RECT 2
-#define WM_GESTURE_LASSO 3
-#define WM_GESTURE_CIRCLE 4
+#define WM_GESTURE_TWEAK 0
+#define WM_GESTURE_LINE 1
+#define WM_GESTURE_RECT 2
+#define WM_GESTURE_CROSS_RECT 3
+#define WM_GESTURE_LASSO 4
+#define WM_GESTURE_CIRCLE 5
/* wmGesture is registered to window listbase, handled by operator callbacks */
typedef struct wmGesture {
struct wmGesture *next, *prev;
- int eventtype, mode;
- int type, swinid;
+ int event_type; /* event->type */
+ int mode; /* for modal callback */
+ int type; /* gesture type define */
+ int swinid; /* initial subwindow id where it started */
void *customdata;
/* customdata for border is a recti */
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index d0f812e31e6..c10faa6cadf 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -223,6 +223,8 @@ void wm_draw_update(bContext *C)
ED_screen_refresh(C->wm, win);
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+ int area_do_draw= 0;
+
C->area= sa;
for(ar=sa->regionbase.first; ar; ar= ar->next) {
@@ -232,12 +234,17 @@ void wm_draw_update(bContext *C)
if(ar->do_refresh)
ED_region_do_refresh(C, ar);
- if(ar->swinid && ar->do_draw)
+ if(ar->swinid && ar->do_draw) {
ED_region_do_draw(C, ar);
-
+ area_do_draw= 1;
+ }
+
C->region= NULL;
}
-
+ /* only internal decoration, like AZone */
+ if(area_do_draw)
+ ED_area_do_draw(C, sa);
+
C->area = NULL;
}
@@ -364,10 +371,11 @@ void WM_event_remove_handlers(ListBase *handlers)
static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *km)
{
+
if(winevent->type!=km->type) return 0;
- if(km->val) /* KM_PRESS, KM_RELEASE */
- if(winevent->val!=km->val-1) return 0;
+ if(km->val!=KM_ANY)
+ if(winevent->val!=km->val) return 0;
if(winevent->shift!=km->shift) return 0;
if(winevent->ctrl!=km->ctrl) return 0;
@@ -648,7 +656,7 @@ void WM_event_add_message(wmWindowManager *wm, void *customdata, short customdat
event.type= MESSAGE;
if(customdata) {
- event.custom= EVT_MESSAGE;
+ event.custom= EVT_DATA_MESSAGE;
event.customdata= customdata;
event.customdatafree= customdatafree;
}
@@ -748,7 +756,7 @@ static void update_tablet_data(wmWindow *win, wmEvent *event)
wmtab->Xtilt = td->Xtilt;
wmtab->Ytilt = td->Ytilt;
- event->custom= EVT_TABLET;
+ event->custom= EVT_DATA_TABLET;
event->customdata= wmtab;
event->customdatafree= 1;
}
@@ -812,7 +820,7 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
GHOST_TEventKeyData *kd= customdata;
event.type= convert_key(kd->key);
event.ascii= kd->ascii;
- event.val= (type==GHOST_kEventKeyDown);
+ event.val= (type==GHOST_kEventKeyDown); /* XXX eventmatch uses defines, bad code... */
/* modifiers */
if (event.type==LEFTSHIFTKEY || event.type==RIGHTSHIFTKEY) {
@@ -845,7 +853,7 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
}
case GHOST_kEventTimer: {
event.type= TIMER;
- event.custom= EVT_TIMER;
+ event.custom= EVT_DATA_TIMER;
event.customdata= customdata;
wm_event_add(win, &event);
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 0a927f3f191..a28eedc631e 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -26,6 +26,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <math.h>
+
#include "DNA_screen_types.h"
#include "DNA_vec_types.h"
#include "DNA_windowmanager_types.h"
@@ -55,12 +57,12 @@ wmGesture *WM_gesture_new(bContext *C, wmEvent *event, int type)
BLI_addtail(&C->window->gesture, gesture);
gesture->type= type;
- gesture->eventtype= event->type;
+ gesture->event_type= event->type;
gesture->swinid= C->screen->subwinactive; /* means only in area-region context! */
wm_subwindow_getorigin(C->window, gesture->swinid, &sx, &sy);
- if( ELEM(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT)) {
+ if( ELEM3(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK)) {
rcti *rect= MEM_callocN(sizeof(rcti), "gesture rect new");
gesture->customdata= rect;
@@ -80,6 +82,47 @@ void WM_gesture_end(bContext *C, wmGesture *gesture)
MEM_freeN(gesture);
}
+/* for line, lasso, ... */
+void wm_gesture_point_add(bContext *C, wmGesture *gesture)
+{
+
+}
+
+/* tweak and line gestures */
+#define TWEAK_THRESHOLD 10
+int wm_gesture_evaluate(bContext *C, wmGesture *gesture)
+{
+ if(gesture->type==WM_GESTURE_TWEAK) {
+ rcti *rect= gesture->customdata;
+ int dx= rect->xmax - rect->xmin;
+ int dy= rect->ymax - rect->ymin;
+ if(ABS(dx)+ABS(dy) > TWEAK_THRESHOLD) {
+ int theta= (int)round(4.0f*atan2((float)dy, (float)dx)/M_PI);
+ int val= EVT_GESTURE_W;
+
+ if(theta==0) val= EVT_GESTURE_E;
+ else if(theta==1) val= EVT_GESTURE_NE;
+ else if(theta==2) val= EVT_GESTURE_N;
+ else if(theta==3) val= EVT_GESTURE_NW;
+ else if(theta==-1) val= EVT_GESTURE_SE;
+ else if(theta==-2) val= EVT_GESTURE_S;
+ else if(theta==-3) val= EVT_GESTURE_SW;
+
+ /* debug */
+ if(val==1) printf("tweak north\n");
+ if(val==2) printf("tweak north-east\n");
+ if(val==3) printf("tweak east\n");
+ if(val==4) printf("tweak south-east\n");
+ if(val==5) printf("tweak south\n");
+ if(val==6) printf("tweak south-west\n");
+ if(val==7) printf("tweak west\n");
+ if(val==8) printf("tweak north-west\n");
+
+ return val;
+ }
+ }
+ return 0;
+}
/* ******************* gesture draw ******************* */
@@ -90,7 +133,7 @@ static void wm_gesture_draw_rect(wmWindow *win, wmGesture *gt)
glEnable(GL_LINE_STIPPLE);
glColor3ub(0, 0, 0);
- glLineStipple(1, 0xAAAA);
+ glLineStipple(1, 0xCCCC);
sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
glColor3ub(255, 255, 255);
glLineStipple(1, 0x3333);
@@ -98,13 +141,29 @@ static void wm_gesture_draw_rect(wmWindow *win, wmGesture *gt)
glDisable(GL_LINE_STIPPLE);
}
-static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
+static void wm_gesture_draw_line(wmWindow *win, wmGesture *gt)
{
rcti *rect= (rcti *)gt->customdata;
glEnable(GL_LINE_STIPPLE);
glColor3ub(0, 0, 0);
glLineStipple(1, 0xAAAA);
+ sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ glColor3ub(255, 255, 255);
+ glLineStipple(1, 0x5555);
+ sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+ glDisable(GL_LINE_STIPPLE);
+
+}
+
+static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
+{
+ rcti *rect= (rcti *)gt->customdata;
+
+ glEnable(GL_LINE_STIPPLE);
+ glColor3ub(0, 0, 0);
+ glLineStipple(1, 0xCCCC);
sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin);
sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey);
@@ -126,6 +185,8 @@ void wm_gesture_draw(wmWindow *win)
if(gt->type==WM_GESTURE_RECT)
wm_gesture_draw_rect(win, gt);
+ else if(gt->type==WM_GESTURE_TWEAK)
+ wm_gesture_draw_line(win, gt);
else if(gt->type==WM_GESTURE_CROSS_RECT) {
if(gt->mode==1)
wm_gesture_draw_rect(win, gt);
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 7a5ec0e4d47..610222b4372 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -71,12 +71,11 @@ static void keymap_set(wmKeymapItem *km, short type, short val, int modifier, sh
km->oskey= 2;
}
-/* if item was added, then replace */
+/* if item was added, then bail out */
void WM_keymap_verify_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier)
{
wmKeymapItem *km;
- /* if item was added, then bail out */
for(km= lb->first; km; km= km->next)
if(strncmp(km->idname, idname, OP_MAX_TYPENAME)==0)
break;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index b8c822592df..32800ff31dc 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -48,6 +48,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "wm.h"
#include "wm_window.h"
#include "wm_subwindow.h"
#include "wm_event_system.h"
@@ -143,7 +144,16 @@ static void WM_OT_exit_blender(wmOperatorType *ot)
* These are default callbacks for use in operators requiring gesture input
*/
-static void border_select_apply(bContext *C, wmOperator *op)
+/* **************** Border gesture *************** */
+
+/* Border gesture has two types:
+ 1) WM_GESTURE_CROSS_RECT: starts a cross, on mouse click it changes to border
+ 2) WM_GESTURE_RECT: starts immediate as a border, on mouse click or release it ends
+
+ It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
+*/
+
+static void border_select_apply(bContext *C, wmOperator *op, int event_type)
{
wmGesture *gesture= op->customdata;
rcti *rect= gesture->customdata;
@@ -154,6 +164,8 @@ static void border_select_apply(bContext *C, wmOperator *op)
RNA_int_default(op->rna, "xmax", rect->xmax);
RNA_int_default(op->rna, "ymax", rect->ymax);
+ RNA_int_default(op->rna, "event_type", event_type);
+
op->type->exec(C, op);
}
@@ -205,6 +217,8 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case LEFTMOUSE:
+ case MIDDLEMOUSE:
+ case RIGHTMOUSE:
if(event->val==1) {
if(gesture->type==WM_GESTURE_CROSS_RECT && gesture->mode==0) {
gesture->mode= 1;
@@ -212,7 +226,7 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
}
}
else {
- border_select_apply(C, op);
+ border_select_apply(C, op, event->type);
border_select_end(C, op);
return OPERATOR_FINISHED;
}
@@ -224,6 +238,87 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+/* **************** Tweak gesture *************** */
+
+static int tweak_gesture_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ op->customdata= WM_gesture_new(C, event, WM_GESTURE_TWEAK);
+
+ /* add modal handler */
+ WM_event_add_modal_handler(&C->window->handlers, op);
+
+ WM_event_add_notifier(C->wm, C->window, C->screen->subwinactive, WM_NOTE_GESTURE_REDRAW, 0, NULL);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void tweak_gesture_end(bContext *C, wmOperator *op)
+{
+ wmGesture *gesture= op->customdata;
+
+ WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
+ op->customdata= NULL;
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ WM_event_add_notifier(C->wm, C->window, gesture->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
+
+}
+
+static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ wmGesture *gesture= op->customdata;
+ rcti *rect= gesture->customdata;
+ int sx, sy, val;
+
+ switch(event->type) {
+ case MOUSEMOVE:
+
+ wm_subwindow_getorigin(C->window, gesture->swinid, &sx, &sy);
+
+ rect->xmax= event->x - sx;
+ rect->ymax= event->y - sy;
+
+ if((val= wm_gesture_evaluate(C, gesture))) {
+ wmEvent event;
+
+ event= *(C->window->eventstate);
+ event.type= EVT_TWEAK;
+ event.val= val;
+ /* mouse coords! */
+ wm_event_add(C->window, &event);
+
+ tweak_gesture_end(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else
+ WM_event_add_notifier(C->wm, C->window, gesture->swinid, WM_NOTE_GESTURE_REDRAW, 0, NULL);
+
+ break;
+
+ case LEFTMOUSE:
+ case RIGHTMOUSE:
+ case MIDDLEMOUSE:
+ if(gesture->event_type==event->type) {
+ wm_gesture_evaluate(C, gesture);
+ tweak_gesture_end(C, op);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ }
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void WM_OT_tweak_gesture(wmOperatorType *ot)
+{
+ ot->name= "Tweak Gesture";
+ ot->idname= "WM_OT_tweak_gesture";
+
+ ot->invoke= tweak_gesture_invoke;
+ ot->modal= tweak_gesture_modal;
+
+ ot->poll= WM_operator_winactive;
+}
+
+
/* ******************************************************* */
/* called on initialize WM_exit() */
@@ -239,6 +334,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_save_homefile);
WM_operatortype_append(WM_OT_window_fullscreen_toggle);
WM_operatortype_append(WM_OT_exit_blender);
+ WM_operatortype_append(WM_OT_tweak_gesture);
}
/* default keymap for windows and screens, only call once per WM */
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index ec9c56f6404..139c360dfda 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -49,6 +49,7 @@ void wm_window_keymap(wmWindowManager *wm);
/* wm_gesture.c */
void wm_gesture_draw(struct wmWindow *win);
+int wm_gesture_evaluate(bContext *C, wmGesture *gesture);
#endif /* WM_H */
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index da644d77611..1edaec417c2 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -35,11 +35,11 @@
#ifndef WM_EVENT_TYPES_H
#define WM_EVENT_TYPES_H
-/* custom data type */
-#define EVT_TABLET 1
-#define EVT_GESTURE 2
-#define EVT_TIMER 3
-#define EVT_MESSAGE 4
+/* customdata type */
+#define EVT_DATA_TABLET 1
+#define EVT_DATA_GESTURE 2
+#define EVT_DATA_TIMER 3
+#define EVT_DATA_MESSAGE 4
#define MOUSEX 0x004
#define MOUSEY 0x005
@@ -259,8 +259,28 @@
/* **************** BLENDER GESTURE EVENTS ********************* */
-#define BORDERSELECT 0x5000
#define EVT_ACTIONZONE 0x5001
+#define EVT_TWEAK 0x5002
+#define EVT_GESTURE 0x5003
+
+/* value of tweaks and line gestures, note, KM_ANY (-1) works for this case too */
+#define EVT_GESTURE_N 1
+#define EVT_GESTURE_NE 2
+#define EVT_GESTURE_E 3
+#define EVT_GESTURE_SE 4
+#define EVT_GESTURE_S 5
+#define EVT_GESTURE_SW 6
+#define EVT_GESTURE_W 7
+#define EVT_GESTURE_NW 8
+/* value of corner gestures */
+#define EVT_GESTURE_N_E 9
+#define EVT_GESTURE_N_W 10
+#define EVT_GESTURE_E_N 11
+#define EVT_GESTURE_E_S 12
+#define EVT_GESTURE_S_E 13
+#define EVT_GESTURE_S_W 14
+#define EVT_GESTURE_W_S 15
+#define EVT_GESTURE_W_N 16
#endif /* WM_EVENT_TYPES_H */