4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2008 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Blender Foundation
26 * ***** END GPL LICENSE BLOCK *****
29 #define _USE_MATH_DEFINES
32 #include "DNA_screen_types.h"
33 #include "DNA_vec_types.h"
34 #include "DNA_windowmanager_types.h"
36 #include "MEM_guardedalloc.h"
38 #include "BLI_blenlib.h"
40 #include "BKE_global.h"
41 #include "BKE_utildefines.h"
46 #include "wm_event_system.h"
47 #include "wm_subwindow.h"
50 #include "BIF_glutil.h"
53 /* context checked on having screen, window and area */
54 wmGesture *WM_gesture_new(bContext *C, wmEvent *event, int type)
56 wmGesture *gesture= MEM_callocN(sizeof(wmGesture), "new gesture");
59 BLI_addtail(&C->window->gesture, gesture);
62 gesture->event_type= event->type;
63 gesture->swinid= C->screen->subwinactive; /* means only in area-region context! */
65 wm_subwindow_getorigin(C->window, gesture->swinid, &sx, &sy);
67 if( ELEM3(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK)) {
68 rcti *rect= MEM_callocN(sizeof(rcti), "gesture rect new");
70 gesture->customdata= rect;
71 rect->xmin= event->x - sx;
72 rect->ymin= event->y - sy;
73 rect->xmax= event->x - sx;
74 rect->ymax= event->y - sy;
80 void WM_gesture_end(bContext *C, wmGesture *gesture)
82 BLI_remlink(&C->window->gesture, gesture);
83 MEM_freeN(gesture->customdata);
87 /* for line, lasso, ... */
88 void wm_gesture_point_add(bContext *C, wmGesture *gesture)
93 /* tweak and line gestures */
94 #define TWEAK_THRESHOLD 10
95 int wm_gesture_evaluate(bContext *C, wmGesture *gesture)
97 if(gesture->type==WM_GESTURE_TWEAK) {
98 rcti *rect= gesture->customdata;
99 int dx= rect->xmax - rect->xmin;
100 int dy= rect->ymax - rect->ymin;
101 if(ABS(dx)+ABS(dy) > TWEAK_THRESHOLD) {
102 int theta= (int)floor(4.0f*atan2((float)dy, (float)dx)/M_PI + 0.5);
103 int val= EVT_GESTURE_W;
105 if(theta==0) val= EVT_GESTURE_E;
106 else if(theta==1) val= EVT_GESTURE_NE;
107 else if(theta==2) val= EVT_GESTURE_N;
108 else if(theta==3) val= EVT_GESTURE_NW;
109 else if(theta==-1) val= EVT_GESTURE_SE;
110 else if(theta==-2) val= EVT_GESTURE_S;
111 else if(theta==-3) val= EVT_GESTURE_SW;
115 if(val==1) printf("tweak north\n");
116 if(val==2) printf("tweak north-east\n");
117 if(val==3) printf("tweak east\n");
118 if(val==4) printf("tweak south-east\n");
119 if(val==5) printf("tweak south\n");
120 if(val==6) printf("tweak south-west\n");
121 if(val==7) printf("tweak west\n");
122 if(val==8) printf("tweak north-west\n");
131 /* ******************* gesture draw ******************* */
133 static void wm_gesture_draw_rect(wmWindow *win, wmGesture *gt)
135 rcti *rect= (rcti *)gt->customdata;
137 glEnable(GL_LINE_STIPPLE);
139 glLineStipple(1, 0xCCCC);
140 sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
141 glColor3ub(255, 255, 255);
142 glLineStipple(1, 0x3333);
143 sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
144 glDisable(GL_LINE_STIPPLE);
147 static void wm_gesture_draw_line(wmWindow *win, wmGesture *gt)
149 rcti *rect= (rcti *)gt->customdata;
151 glEnable(GL_LINE_STIPPLE);
153 glLineStipple(1, 0xAAAA);
154 sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
155 glColor3ub(255, 255, 255);
156 glLineStipple(1, 0x5555);
157 sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
159 glDisable(GL_LINE_STIPPLE);
163 static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
165 rcti *rect= (rcti *)gt->customdata;
167 glEnable(GL_LINE_STIPPLE);
169 glLineStipple(1, 0xCCCC);
170 sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin);
171 sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey);
173 glColor3ub(255, 255, 255);
174 glLineStipple(1, 0x3333);
175 sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin);
176 sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey);
177 glDisable(GL_LINE_STIPPLE);
180 /* called in wm_event_system.c */
181 void wm_gesture_draw(wmWindow *win)
183 wmGesture *gt= (wmGesture *)win->gesture.first;
185 for(; gt; gt= gt->next) {
186 /* all in subwindow space */
187 wm_subwindow_set(win, gt->swinid);
189 if(gt->type==WM_GESTURE_RECT)
190 wm_gesture_draw_rect(win, gt);
191 else if(gt->type==WM_GESTURE_TWEAK)
192 wm_gesture_draw_line(win, gt);
193 else if(gt->type==WM_GESTURE_CROSS_RECT) {
195 wm_gesture_draw_rect(win, gt);
197 wm_gesture_draw_cross(win, gt);