|
Blender
V2.59
|
00001 /* 00002 * $Id: wm_gesture.c 35953 2011-04-02 02:08:33Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Blender Foundation 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include "DNA_screen_types.h" 00035 #include "DNA_vec_types.h" 00036 #include "DNA_userdef_types.h" 00037 #include "DNA_windowmanager_types.h" 00038 00039 #include "MEM_guardedalloc.h" 00040 00041 #include "BLI_blenlib.h" 00042 #include "BLI_editVert.h" /* lasso tessellation */ 00043 #include "BLI_math.h" 00044 #include "BLI_scanfill.h" /* lasso tessellation */ 00045 #include "BLI_utildefines.h" 00046 00047 #include "BKE_context.h" 00048 00049 00050 #include "WM_api.h" 00051 #include "WM_types.h" 00052 00053 #include "wm.h" 00054 #include "wm_event_system.h" 00055 #include "wm_subwindow.h" 00056 #include "wm_draw.h" 00057 00058 00059 #include "BIF_gl.h" 00060 #include "BIF_glutil.h" 00061 00062 00063 /* context checked on having screen, window and area */ 00064 wmGesture *WM_gesture_new(bContext *C, wmEvent *event, int type) 00065 { 00066 wmGesture *gesture= MEM_callocN(sizeof(wmGesture), "new gesture"); 00067 wmWindow *window= CTX_wm_window(C); 00068 ARegion *ar= CTX_wm_region(C); 00069 int sx, sy; 00070 00071 BLI_addtail(&window->gesture, gesture); 00072 00073 gesture->type= type; 00074 gesture->event_type= event->type; 00075 gesture->swinid= ar->swinid; /* means only in area-region context! */ 00076 00077 wm_subwindow_getorigin(window, gesture->swinid, &sx, &sy); 00078 00079 if( ELEM5(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK, WM_GESTURE_CIRCLE, WM_GESTURE_STRAIGHTLINE)) { 00080 rcti *rect= MEM_callocN(sizeof(rcti), "gesture rect new"); 00081 00082 gesture->customdata= rect; 00083 rect->xmin= event->x - sx; 00084 rect->ymin= event->y - sy; 00085 if(type==WM_GESTURE_CIRCLE) { 00086 #ifdef GESTURE_MEMORY 00087 rect->xmax= circle_select_size; 00088 #else 00089 rect->xmax= 25; // XXX temp 00090 #endif 00091 } else { 00092 rect->xmax= event->x - sx; 00093 rect->ymax= event->y - sy; 00094 } 00095 } 00096 else if (ELEM(type, WM_GESTURE_LINES, WM_GESTURE_LASSO)) { 00097 short *lasso; 00098 gesture->customdata= lasso= MEM_callocN(2*sizeof(short)*WM_LASSO_MIN_POINTS, "lasso points"); 00099 lasso[0] = event->x - sx; 00100 lasso[1] = event->y - sy; 00101 gesture->points= 1; 00102 gesture->size = WM_LASSO_MIN_POINTS; 00103 } 00104 00105 return gesture; 00106 } 00107 00108 void WM_gesture_end(bContext *C, wmGesture *gesture) 00109 { 00110 wmWindow *win= CTX_wm_window(C); 00111 00112 if(win->tweak==gesture) 00113 win->tweak= NULL; 00114 BLI_remlink(&win->gesture, gesture); 00115 MEM_freeN(gesture->customdata); 00116 MEM_freeN(gesture); 00117 } 00118 00119 void WM_gestures_remove(bContext *C) 00120 { 00121 wmWindow *win= CTX_wm_window(C); 00122 00123 while(win->gesture.first) 00124 WM_gesture_end(C, win->gesture.first); 00125 } 00126 00127 00128 /* tweak and line gestures */ 00129 #define TWEAK_THRESHOLD 10 00130 int wm_gesture_evaluate(wmGesture *gesture) 00131 { 00132 if(gesture->type==WM_GESTURE_TWEAK) { 00133 rcti *rect= gesture->customdata; 00134 int dx= rect->xmax - rect->xmin; 00135 int dy= rect->ymax - rect->ymin; 00136 if(ABS(dx)+ABS(dy) > TWEAK_THRESHOLD) { 00137 int theta= (int)floor(4.0f*atan2f((float)dy, (float)dx)/(float)M_PI + 0.5f); 00138 int val= EVT_GESTURE_W; 00139 00140 if(theta==0) val= EVT_GESTURE_E; 00141 else if(theta==1) val= EVT_GESTURE_NE; 00142 else if(theta==2) val= EVT_GESTURE_N; 00143 else if(theta==3) val= EVT_GESTURE_NW; 00144 else if(theta==-1) val= EVT_GESTURE_SE; 00145 else if(theta==-2) val= EVT_GESTURE_S; 00146 else if(theta==-3) val= EVT_GESTURE_SW; 00147 00148 #if 0 00149 /* debug */ 00150 if(val==1) printf("tweak north\n"); 00151 if(val==2) printf("tweak north-east\n"); 00152 if(val==3) printf("tweak east\n"); 00153 if(val==4) printf("tweak south-east\n"); 00154 if(val==5) printf("tweak south\n"); 00155 if(val==6) printf("tweak south-west\n"); 00156 if(val==7) printf("tweak west\n"); 00157 if(val==8) printf("tweak north-west\n"); 00158 #endif 00159 return val; 00160 } 00161 } 00162 return 0; 00163 } 00164 00165 00166 /* ******************* gesture draw ******************* */ 00167 00168 static void wm_gesture_draw_rect(wmGesture *gt) 00169 { 00170 rcti *rect= (rcti *)gt->customdata; 00171 00172 glEnable(GL_BLEND); 00173 glColor4f(1.0, 1.0, 1.0, 0.05); 00174 glBegin(GL_QUADS); 00175 glVertex2s(rect->xmax, rect->ymin); 00176 glVertex2s(rect->xmax, rect->ymax); 00177 glVertex2s(rect->xmin, rect->ymax); 00178 glVertex2s(rect->xmin, rect->ymin); 00179 glEnd(); 00180 glDisable(GL_BLEND); 00181 00182 glEnable(GL_LINE_STIPPLE); 00183 glColor3ub(96, 96, 96); 00184 glLineStipple(1, 0xCCCC); 00185 sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); 00186 glColor3ub(255, 255, 255); 00187 glLineStipple(1, 0x3333); 00188 sdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); 00189 glDisable(GL_LINE_STIPPLE); 00190 } 00191 00192 static void wm_gesture_draw_line(wmGesture *gt) 00193 { 00194 rcti *rect= (rcti *)gt->customdata; 00195 00196 glEnable(GL_LINE_STIPPLE); 00197 glColor3ub(96, 96, 96); 00198 glLineStipple(1, 0xAAAA); 00199 sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax); 00200 glColor3ub(255, 255, 255); 00201 glLineStipple(1, 0x5555); 00202 sdrawline(rect->xmin, rect->ymin, rect->xmax, rect->ymax); 00203 00204 glDisable(GL_LINE_STIPPLE); 00205 00206 } 00207 00208 static void wm_gesture_draw_circle(wmGesture *gt) 00209 { 00210 rcti *rect= (rcti *)gt->customdata; 00211 00212 glTranslatef((float)rect->xmin, (float)rect->ymin, 0.0f); 00213 00214 glEnable(GL_BLEND); 00215 glColor4f(1.0, 1.0, 1.0, 0.05); 00216 glutil_draw_filled_arc(0.0, M_PI*2.0, rect->xmax, 40); 00217 glDisable(GL_BLEND); 00218 00219 glEnable(GL_LINE_STIPPLE); 00220 glColor3ub(96, 96, 96); 00221 glLineStipple(1, 0xAAAA); 00222 glutil_draw_lined_arc(0.0, M_PI*2.0, rect->xmax, 40); 00223 glColor3ub(255, 255, 255); 00224 glLineStipple(1, 0x5555); 00225 glutil_draw_lined_arc(0.0, M_PI*2.0, rect->xmax, 40); 00226 00227 glDisable(GL_LINE_STIPPLE); 00228 glTranslatef((float)-rect->xmin, (float)-rect->ymin, 0.0f); 00229 00230 } 00231 00232 static void draw_filled_lasso(wmGesture *gt) 00233 { 00234 EditVert *v=NULL, *lastv=NULL, *firstv=NULL; 00235 EditEdge *e; 00236 EditFace *efa; 00237 short *lasso= (short *)gt->customdata; 00238 int i; 00239 00240 for (i=0; i<gt->points; i++, lasso+=2) { 00241 float co[3]; 00242 00243 co[0]= (float)lasso[0]; 00244 co[1]= (float)lasso[1]; 00245 co[2]= 0.0f; 00246 00247 v = BLI_addfillvert(co); 00248 if (lastv) 00249 e = BLI_addfilledge(lastv, v); 00250 lastv = v; 00251 if (firstv==NULL) firstv = v; 00252 } 00253 00254 /* highly unlikely this will fail, but could crash if (gt->points == 0) */ 00255 if(firstv) { 00256 BLI_addfilledge(firstv, v); 00257 BLI_edgefill(0); 00258 00259 glEnable(GL_BLEND); 00260 glColor4f(1.0, 1.0, 1.0, 0.05); 00261 glBegin(GL_TRIANGLES); 00262 for (efa = fillfacebase.first; efa; efa=efa->next) { 00263 glVertex2f(efa->v1->co[0], efa->v1->co[1]); 00264 glVertex2f(efa->v2->co[0], efa->v2->co[1]); 00265 glVertex2f(efa->v3->co[0], efa->v3->co[1]); 00266 } 00267 glEnd(); 00268 glDisable(GL_BLEND); 00269 00270 BLI_end_edgefill(); 00271 } 00272 } 00273 00274 static void wm_gesture_draw_lasso(wmGesture *gt) 00275 { 00276 short *lasso= (short *)gt->customdata; 00277 int i; 00278 00279 draw_filled_lasso(gt); 00280 00281 glEnable(GL_LINE_STIPPLE); 00282 glColor3ub(96, 96, 96); 00283 glLineStipple(1, 0xAAAA); 00284 glBegin(GL_LINE_STRIP); 00285 for(i=0; i<gt->points; i++, lasso+=2) 00286 glVertex2sv(lasso); 00287 if(gt->type==WM_GESTURE_LASSO) 00288 glVertex2sv((short *)gt->customdata); 00289 glEnd(); 00290 00291 glColor3ub(255, 255, 255); 00292 glLineStipple(1, 0x5555); 00293 glBegin(GL_LINE_STRIP); 00294 lasso= (short *)gt->customdata; 00295 for(i=0; i<gt->points; i++, lasso+=2) 00296 glVertex2sv(lasso); 00297 if(gt->type==WM_GESTURE_LASSO) 00298 glVertex2sv((short *)gt->customdata); 00299 glEnd(); 00300 00301 glDisable(GL_LINE_STIPPLE); 00302 00303 } 00304 00305 static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt) 00306 { 00307 rcti *rect= (rcti *)gt->customdata; 00308 00309 glEnable(GL_LINE_STIPPLE); 00310 glColor3ub(96, 96, 96); 00311 glLineStipple(1, 0xCCCC); 00312 sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin); 00313 sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey); 00314 00315 glColor3ub(255, 255, 255); 00316 glLineStipple(1, 0x3333); 00317 sdrawline(rect->xmin - win->sizex, rect->ymin, rect->xmin + win->sizex, rect->ymin); 00318 sdrawline(rect->xmin, rect->ymin - win->sizey, rect->xmin, rect->ymin + win->sizey); 00319 glDisable(GL_LINE_STIPPLE); 00320 } 00321 00322 /* called in wm_draw.c */ 00323 void wm_gesture_draw(wmWindow *win) 00324 { 00325 wmGesture *gt= (wmGesture *)win->gesture.first; 00326 00327 for(; gt; gt= gt->next) { 00328 /* all in subwindow space */ 00329 wmSubWindowSet(win, gt->swinid); 00330 00331 if(gt->type==WM_GESTURE_RECT) 00332 wm_gesture_draw_rect(gt); 00333 // else if(gt->type==WM_GESTURE_TWEAK) 00334 // wm_gesture_draw_line(gt); 00335 else if(gt->type==WM_GESTURE_CIRCLE) 00336 wm_gesture_draw_circle(gt); 00337 else if(gt->type==WM_GESTURE_CROSS_RECT) { 00338 if(gt->mode==1) 00339 wm_gesture_draw_rect(gt); 00340 else 00341 wm_gesture_draw_cross(win, gt); 00342 } 00343 else if(gt->type==WM_GESTURE_LINES) 00344 wm_gesture_draw_lasso(gt); 00345 else if(gt->type==WM_GESTURE_LASSO) 00346 wm_gesture_draw_lasso(gt); 00347 else if(gt->type==WM_GESTURE_STRAIGHTLINE) 00348 wm_gesture_draw_line(gt); 00349 } 00350 } 00351 00352 void wm_gesture_tag_redraw(bContext *C) 00353 { 00354 wmWindow *win= CTX_wm_window(C); 00355 bScreen *screen= CTX_wm_screen(C); 00356 ARegion *ar= CTX_wm_region(C); 00357 00358 if(screen) 00359 screen->do_draw_gesture= 1; 00360 00361 wm_tag_redraw_overlay(win, ar); 00362 }