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