Made WeightPaint use shaded mode. This thanks to the preparations as done
[blender.git] / source / blender / src / drawoops.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <math.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include "BMF_Api.h"
42
43 #include "BLI_blenlib.h"
44 #include "BLI_arithb.h"
45
46 #include "DNA_ID.h"
47 #include "DNA_object_types.h"
48 #include "DNA_oops_types.h"
49 #include "DNA_scene_types.h"
50 #include "DNA_screen_types.h"
51 #include "DNA_space_types.h"
52 #include "DNA_view2d_types.h"
53
54 #include "BKE_utildefines.h"
55 #include "BKE_global.h"
56
57 #include "BIF_interface.h"
58 #include "BIF_gl.h"
59 #include "BIF_glutil.h"
60 #include "BIF_mywindow.h"
61 #include "BIF_outliner.h"
62 #include "BIF_resources.h"
63 #include "BIF_screen.h"
64
65 /*  #include "BIF_drawoops.h" bad name :(*/
66 #include "BIF_oops.h"
67
68 #include "BSE_drawipo.h"
69 #include "BSE_drawoops.h"
70
71 float oopscalex;
72
73 void boundbox_oops()
74 {
75         Oops *oops;
76         float min[2], max[2];
77         int ok= 0;
78         
79         if(G.soops==0) return;
80         
81         min[0]= 1000.0;
82         max[0]= -10000.0;
83         min[1]= 1000.0;
84         max[1]= -1000.0;
85         
86         oops= G.soops->oops.first;
87         while(oops) {
88                 if(oops->hide==0) {
89                         ok= 1;
90                         
91                         min[0]= MIN2(min[0], oops->x);
92                         max[0]= MAX2(max[0], oops->x+OOPSX);
93                         min[1]= MIN2(min[1], oops->y);
94                         max[1]= MAX2(max[1], oops->y+OOPSY);
95                 }
96                 oops= oops->next;
97         }
98         
99         if(ok==0) return;
100         
101         G.v2d->tot.xmin= min[0];
102         G.v2d->tot.xmax= max[0];
103         G.v2d->tot.ymin= min[1];
104         G.v2d->tot.ymax= max[1];
105         
106 }
107
108 void give_oopslink_line(Oops *oops, OopsLink *ol, float *v1, float *v2)
109 {
110
111         if(ol->to && ol->to->hide==0) {
112                 v1[0]= oops->x+ol->xof;
113                 v1[1]= oops->y+ol->yof;
114                 v2[0]= ol->to->x+OOPSX/2;
115                 v2[1]= ol->to->y;
116         }
117         else if(ol->from && ol->from->hide==0) {
118                 v1[0]= ol->from->x + ol->xof;
119                 v1[1]= ol->from->y + ol->xof;
120                 v2[0]= oops->x+OOPSX/2;
121                 v2[1]= oops->y;
122         }
123 }
124
125 void draw_oopslink(Oops *oops)
126 {
127         OopsLink *ol;
128         float vec[4][3], dist;
129         int a;
130         
131         if(oops->type==ID_SCE) {
132                 if(oops->flag & SELECT) {
133                         if(oops->id->lib) cpack(0x4080A0);
134                         else cpack(0x808080);
135                 }
136                 else cpack(0x606060);
137         }
138         else {
139                 if(oops->flag & SELECT) {
140                         if(oops->id->lib) cpack(0x11AAFF);
141                         else cpack(0xFFFFFF);
142                 }
143                 else cpack(0x0);
144         }
145         
146         glEnable(GL_MAP1_VERTEX_3);
147         vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0;
148         
149         ol= oops->link.first;
150         while(ol) {
151                 if(ol->to && ol->to->hide==0) {
152                         
153                         give_oopslink_line(oops, ol, vec[0], vec[3]);
154                         
155                         dist= 0.5*VecLenf(vec[0], vec[3]);
156
157                         /* check ol->xof and yof for direction */
158                         if(ol->xof == 0.0) {
159                                 vec[1][0]= vec[0][0]-dist;
160                                 vec[1][1]= vec[0][1];
161                         }
162                         else if(ol->xof==OOPSX) {
163                                 vec[1][0]= vec[0][0]+dist;
164                                 vec[1][1]= vec[0][1];
165                         }
166                         else {
167                                 vec[1][0]= vec[0][0];
168                                 vec[1][1]= vec[0][1]+dist;
169                         }
170                         
171                         /* v3 is always pointing down */
172                         vec[2][0]= vec[3][0];
173                         vec[2][1]= vec[3][1] - dist;
174
175                         glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, vec[0]);
176                         
177                         glBegin(GL_LINE_STRIP);
178                         for(a=0; a<=30; a++) {
179                                 glEvalCoord1f((float)a/30.0);
180                         }
181                         glEnd();
182                 }
183                 ol= ol->next;
184         }
185 }
186
187 void draw_icon_oops(float *co, short type)
188 {
189         BIFIconID icon;
190         
191         switch(type) {
192         default: return;
193
194         case ID_OB:     icon= ICON_OBJECT_HLT; break;
195         case ID_ME:     icon= ICON_MESH_HLT; break;
196         case ID_CU:     icon= ICON_CURVE_HLT; break;
197         case ID_MB:     icon= ICON_MBALL_HLT; break;
198         case ID_LT:     icon= ICON_LATTICE_HLT; break;
199         case ID_LA:     icon= ICON_LAMP_HLT; break;
200         case ID_MA:     icon= ICON_MATERIAL_HLT; break;
201         case ID_TE:     icon= ICON_TEXTURE_HLT; break;
202         case ID_IP:     icon= ICON_IPO_HLT; break;
203         case ID_LI:     icon= ICON_LIBRARY_HLT; break;
204         case ID_IM:     icon= ICON_IMAGE_HLT; break;
205         }
206
207         glEnable(GL_BLEND);
208         glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA); 
209
210         BIF_draw_icon(co[0], co[1]-0.2, icon);
211
212         glBlendFunc(GL_ONE,  GL_ZERO); 
213         glDisable(GL_BLEND);
214 }
215
216 void mysbox(float x1, float y1, float x2, float y2)
217 {
218         float vec[2];
219         
220         glBegin(GL_LINE_LOOP);
221         vec[0]= x1; vec[1]= y1;
222         glVertex2fv(vec);
223         vec[0]= x2;
224         glVertex2fv(vec);
225         vec[1]= y2;
226         glVertex2fv(vec);
227         vec[0]= x1;
228         glVertex2fv(vec);
229         glEnd();
230 }
231
232 unsigned int give_oops_color(short type, short sel, unsigned int *border)
233 {
234         unsigned int body;
235         /* also finds out if a dashed line should be drawn */
236
237         switch(type) {
238         case ID_OB:
239                 body= 0x707070; break;
240         case ID_SCE:
241                 body= 0x608060; break;
242         case ID_MA:
243                 body= 0x808060; break;
244         case ID_TE:
245                 body= 0x7080a0; break;
246         case ID_IP:
247                 body= 0x906050; break;
248         case ID_LA:
249                 body= 0x608080; break;
250         case ID_LI:
251                 body= 0x2198DC; break;
252         case ID_IM:
253                 body= 0x35659F; break;
254         default:
255                 body= 0x606070; break;
256         }
257
258         if(sel) {
259                 if(G.moving) *border= 0xf0f0f0;
260                 else *border= 0xc0c0c0; 
261         }
262         else *border= 0x0;
263
264         
265         return body;
266 }
267
268 void calc_oopstext(char *str, float *v1)
269 {
270         float f1, f2, size;
271         short mval[2], len, flen;
272         
273         ipoco_to_areaco_noclip(G.v2d, v1, mval);
274         f1= mval[0];
275         v1[0]+= OOPSX;
276         ipoco_to_areaco_noclip(G.v2d, v1, mval);
277         f2= mval[0];
278         size= f2-f1;
279
280         len= strlen(str);
281         
282         while( (flen= BMF_GetStringWidth(G.fonts, str)) > size) {
283                 if(flen < 10 || len<2) break;
284                 len--;
285                 str[len]= 0;
286         }
287         
288         mval[0]= (f1+f2-flen+1)/2;
289         mval[1]= 1;
290         areamouseco_to_ipoco(G.v2d, mval, &f1, &f2);
291         
292         v1[0]= f1;
293         
294 }
295
296 void draw_oops(Oops *oops)
297 {
298         OopsLink *ol;
299         float v1[2], x1, y1, x2, y2, f1, f2;
300         unsigned int body, border;
301         short line= 0;
302         char str[32];
303
304         x1= oops->x; 
305         x2= oops->x+OOPSX;
306         y1= oops->y; 
307         y2= oops->y+OOPSY;
308
309         if(x2 < G.v2d->cur.xmin || x1 > G.v2d->cur.xmax) return;
310         if(y2 < G.v2d->cur.ymin || y1 > G.v2d->cur.ymax) return;
311
312         body= give_oops_color(oops->type, oops->flag & SELECT, &border);
313         if(oops->id== (ID *)((G.scene->basact) ? (G.scene->basact->object) : 0)) line= 1;
314         else if(oops->id== (ID *)G.scene) line= 1;
315
316         if(oops->id->us) {
317                 cpack(body);
318
319                 glRectf(x1,  y1,  x2,  y2);
320         }
321         if(oops->id->lib) {
322                 if(oops->id->flag & LIB_INDIRECT) cpack(0x1144FF);
323                 else cpack(0x11AAFF);
324
325                 glRectf(x2-0.2*OOPSX,  y2-0.2*OOPSX,  x2-0.1*OOPSX,  y2-0.1*OOPSX);
326         }
327
328         v1[0]= x1; 
329         v1[1]= (y1+y2)/2 -0.3;
330         if(oops->type==ID_LI) {
331                 sprintf(str, "     %s", ((Library *)oops->id)->name);
332         }
333         else {
334                 sprintf(str, "     %s", oops->id->name+2);
335         }
336         calc_oopstext(str, v1);
337
338         /* ICON */
339         if(str[1] && oopscalex>1.1) {
340                 draw_icon_oops(v1, oops->type);
341         }
342         if(oops->flag & SELECT) cpack(0xFFFFFF); 
343         else cpack(0x0);
344         glRasterPos3f(v1[0],  v1[1], 0.0);
345         BMF_DrawString(G.fonts, str);
346
347         if(line) setlinestyle(2);
348         cpack(border);
349
350         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
351         glRectf(x1,  y1,  x2,  y2);
352         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
353         if(line) setlinestyle(0);
354
355         /* connection blocks */
356         ol= oops->link.first;
357         while(ol) {
358
359                 f1= x1+ol->xof; 
360                 f2= y1+ol->yof;
361
362                 body= give_oops_color(ol->type, oops->flag & SELECT, &border);
363                 cpack(body);
364
365                 glRectf(f1-.2,  f2-.2,  f1+.2,  f2+.2);
366                 cpack(border);
367
368                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
369
370                 glRectf(f1-.2,  f2-.2,  f1+.2,  f2+.2);
371
372                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
373
374                 ol= ol->next;
375         }
376
377         if(oops->flag & OOPS_REFER) {
378                         /* Draw the little rounded connection point */
379                 glColor3ub(0, 0, 0);
380                 glPushMatrix();
381
382                 glTranslatef(oops->x + 0.5*OOPSX, oops->y, 0.0);
383                 glutil_draw_filled_arc(0.0, M_PI, 0.05*OOPSX, 7);
384
385                 glPopMatrix();
386         }
387 }
388
389 void drawoopsspace(ScrArea *sa, void *spacedata)
390 {
391         SpaceOops *soops= spacedata;
392         Oops *oops;
393         float col[3];
394         
395         BIF_GetThemeColor3fv(TH_BACK, col);
396         glClearColor(col[0], col[1], col[2], 0.0);
397         glClear(GL_COLOR_BUFFER_BIT);
398         if(soops==0) return;    
399         
400         if(soops->type==SO_OUTLINER) draw_outliner(sa, soops);
401         else {
402                 build_oops();   /* changed to become first call... */
403                 
404                 boundbox_oops();
405                 calc_scrollrcts(sa, G.v2d, curarea->winx, curarea->winy);
406
407                 myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
408
409                 oopscalex= .14*((float)curarea->winx)/(G.v2d->cur.xmax-G.v2d->cur.xmin);
410                 calc_ipogrid(); /* for scrollvariables */
411
412                 oops= soops->oops.first;
413                 while(oops) {
414                         if(oops->hide==0) {
415                                 draw_oopslink(oops);
416                         }
417                         oops= oops->next;
418                 }
419                 oops= soops->oops.first;
420                 while(oops) {
421                         if(oops->hide==0) {
422                                 if(oops->flag & SELECT); else draw_oops(oops);
423                         }
424                         oops= oops->next;
425                 }
426                 oops= soops->oops.first;
427                 while(oops) {
428                         if(oops->hide==0) {
429                                 if(oops->flag & SELECT) draw_oops(oops);
430                         }
431                         oops= oops->next;
432                 }
433         }
434         
435         /* restore viewport */
436         mywinset(curarea->win);
437         
438         /* ortho at pixel level curarea */
439         myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
440
441         if(soops->type==SO_OUTLINER) {
442                 if(sa->winx>SCROLLB+10 && sa->winy>SCROLLH+10) {
443                         if(G.v2d->scroll) drawscroll(0);                
444                 }
445         }
446         draw_area_emboss(sa);   
447         
448         curarea->win_swap= WIN_BACK_OK;
449 }
450
451
452