first of the c code comment translation in the mother of all directories!
[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 #ifdef _WIN32
42 #include "BLI_winstuff.h"
43 #endif
44
45 #include "BMF_Api.h"
46
47 #include "BLI_blenlib.h"
48 #include "BLI_arithb.h"
49 #include "BLI_editVert.h"
50
51 #include "DNA_ID.h"
52 #include "DNA_mesh_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_oops_types.h"
55 #include "DNA_scene_types.h"
56 #include "DNA_screen_types.h"
57 #include "DNA_space_types.h"
58 #include "DNA_view2d_types.h"
59
60 #include "BKE_utildefines.h"
61 #include "BKE_global.h"
62
63 #include "BIF_gl.h"
64 #include "BIF_interface.h"
65 #include "BIF_glutil.h"
66 #include "BIF_resources.h"
67 #include "BIF_screen.h"
68 #include "BIF_interface.h"
69 #include "BIF_mywindow.h"
70
71 /*  #include "BIF_drawoops.h" bad name :(*/
72 #include "BIF_oops.h"
73
74 #include "BSE_drawipo.h"
75 #include "BSE_drawoops.h"
76 #include "interface.h"
77
78 float oopscalex;
79
80 void boundbox_oops()
81 {
82         Oops *oops;
83         float min[2], max[2];
84         int ok= 0;
85         
86         if(G.soops==0) return;
87         
88         min[0]= 1000.0;
89         max[0]= -10000.0;
90         min[1]= 1000.0;
91         max[1]= -1000.0;
92         
93         oops= G.soops->oops.first;
94         while(oops) {
95                 if(oops->hide==0) {
96                         ok= 1;
97                         
98                         min[0]= MIN2(min[0], oops->x);
99                         max[0]= MAX2(max[0], oops->x+OOPSX);
100                         min[1]= MIN2(min[1], oops->y);
101                         max[1]= MAX2(max[1], oops->y+OOPSY);
102                 }
103                 oops= oops->next;
104         }
105         
106         if(ok==0) return;
107         
108         G.v2d->tot.xmin= min[0];
109         G.v2d->tot.xmax= max[0];
110         G.v2d->tot.ymin= min[1];
111         G.v2d->tot.ymax= max[1];
112         
113 }
114
115 void give_oopslink_line(Oops *oops, OopsLink *ol, float *v1, float *v2)
116 {
117
118         if(ol->to && ol->to->hide==0) {
119                 v1[0]= oops->x+ol->xof;
120                 v1[1]= oops->y+ol->yof;
121                 v2[0]= ol->to->x+OOPSX/2;
122                 v2[1]= ol->to->y;
123         }
124         else if(ol->from && ol->from->hide==0) {
125                 v1[0]= ol->from->x + ol->xof;
126                 v1[1]= ol->from->y + ol->xof;
127                 v2[0]= oops->x+OOPSX/2;
128                 v2[1]= oops->y;
129         }
130 }
131
132 void draw_oopslink(Oops *oops)
133 {
134         OopsLink *ol;
135         float vec[4];
136         
137         if(oops->type==ID_SCE) {
138                 if(oops->flag & SELECT) {
139                         if(oops->id->lib) cpack(0x4080A0);
140                         else cpack(0x808080);
141                 }
142                 else cpack(0x606060);
143         }
144         else {
145                 if(oops->flag & SELECT) {
146                         if(oops->id->lib) cpack(0x11AAFF);
147                         else cpack(0xFFFFFF);
148                 }
149                 else cpack(0x0);
150         }
151         
152         ol= oops->link.first;
153         while(ol) {
154                 if(ol->to && ol->to->hide==0) {
155                         
156                         give_oopslink_line(oops, ol, vec, vec+2);
157                         
158                         glBegin(GL_LINE_STRIP);
159                         glVertex2fv(vec);
160                         glVertex2fv(vec+2);
161                         glEnd();
162                 }
163                 ol= ol->next;
164         }
165 }
166
167 void draw_icon_oops(float *co, short type)
168 {
169         BIFIconID icon;
170         
171         switch(type) {
172         default: return;
173
174         case ID_OB:     icon= ICON_OBJECT_HLT; break;
175         case ID_ME:     icon= ICON_MESH_HLT; break;
176         case ID_CU:     icon= ICON_CURVE_HLT; break;
177         case ID_MB:     icon= ICON_MBALL_HLT; break;
178         case ID_LT:     icon= ICON_LATTICE_HLT; break;
179         case ID_LA:     icon= ICON_LAMP_HLT; break;
180         case ID_MA:     icon= ICON_MATERIAL_HLT; break;
181         case ID_TE:     icon= ICON_TEXTURE_HLT; break;
182         case ID_IP:     icon= ICON_IPO_HLT; break;
183         case ID_LI:     icon= ICON_LIBRARY_HLT; break;
184         case ID_IM:     icon= ICON_IMAGE_HLT; break;
185         }
186
187         glEnable(GL_BLEND);
188         glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA); 
189
190         glRasterPos2f(co[0],  co[1]-0.2);
191         BIF_draw_icon(icon);
192
193         glBlendFunc(GL_ONE,  GL_ZERO); 
194         glDisable(GL_BLEND);
195 }
196
197 void mysbox(float x1, float y1, float x2, float y2)
198 {
199         float vec[2];
200         
201         glBegin(GL_LINE_LOOP);
202         vec[0]= x1; vec[1]= y1;
203         glVertex2fv(vec);
204         vec[0]= x2;
205         glVertex2fv(vec);
206         vec[1]= y2;
207         glVertex2fv(vec);
208         vec[0]= x1;
209         glVertex2fv(vec);
210         glEnd();
211 }
212
213 unsigned int give_oops_color(short type, short sel, unsigned int *border)
214 {
215         unsigned int body;
216         /* also finds out if a dashed line should be drawn */
217
218         switch(type) {
219         case ID_OB:
220                 body= 0x707070; break;
221         case ID_SCE:
222                 body= 0x608060; break;
223         case ID_MA:
224                 body= 0x808060; break;
225         case ID_TE:
226                 body= 0x7080a0; break;
227         case ID_IP:
228                 body= 0x906050; break;
229         case ID_LA:
230                 body= 0x608080; break;
231         case ID_LI:
232                 body= 0x2198DC; break;
233         case ID_IM:
234                 body= 0x35659F; break;
235         default:
236                 body= 0x606070; break;
237         }
238
239         if(sel) {
240                 if(G.moving) *border= 0xf0f0f0;
241                 else *border= 0xc0c0c0; 
242         }
243         else *border= 0x0;
244
245         
246         return body;
247 }
248
249 void calc_oopstext(char *str, float *v1)
250 {
251         float f1, f2, size;
252         short mval[2], len, flen;
253         
254         ipoco_to_areaco_noclip(G.v2d, v1, mval);
255         f1= mval[0];
256         v1[0]+= OOPSX;
257         ipoco_to_areaco_noclip(G.v2d, v1, mval);
258         f2= mval[0];
259         size= f2-f1;
260
261         len= strlen(str);
262         
263         while( (flen= BMF_GetStringWidth(G.fonts, str)) > size) {
264                 if(flen < 10 || len<2) break;
265                 len--;
266                 str[len]= 0;
267         }
268         
269         mval[0]= (f1+f2-flen+1)/2;
270         mval[1]= 1;
271         areamouseco_to_ipoco(G.v2d, mval, &f1, &f2);
272         
273         v1[0]= f1;
274         
275 }
276
277 void draw_oops(Oops *oops, uiBlock *block)
278 {
279         OopsLink *ol;
280         float v1[2], x1, y1, x2, y2, f1, f2;
281         unsigned int body, border;
282         short line= 0;
283         char str[32];
284
285         x1= oops->x; 
286         x2= oops->x+OOPSX;
287         y1= oops->y; 
288         y2= oops->y+OOPSY;
289
290         if(x2 < G.v2d->cur.xmin || x1 > G.v2d->cur.xmax) return;
291         if(y2 < G.v2d->cur.ymin || y1 > G.v2d->cur.ymax) return;
292
293         body= give_oops_color(oops->type, oops->flag & SELECT, &border);
294         if(oops->id== (ID *)((G.scene->basact) ? (G.scene->basact->object) : 0)) line= 1;
295         else if(oops->id== (ID *)G.scene) line= 1;
296
297         if(oops->id->us) {
298                 cpack(body);
299
300                 glRectf(x1,  y1,  x2,  y2);
301         }
302         if(oops->id->lib) {
303                 if(oops->id->flag & LIB_INDIRECT) cpack(0x1144FF);
304                 else cpack(0x11AAFF);
305
306                 glRectf(x2-0.2*OOPSX,  y2-0.2*OOPSX,  x2-0.1*OOPSX,  y2-0.1*OOPSX);
307         }
308
309         v1[0]= x1; 
310         v1[1]= (y1+y2)/2 -0.3;
311         if(oops->type==ID_LI) {
312                 sprintf(str, "     %s", ((Library *)oops->id)->name);
313         }
314         else {
315                 sprintf(str, "     %s", oops->id->name+2);
316         }
317         calc_oopstext(str, v1);
318
319         /* ICON */
320         if(str[1] && oopscalex>1.1) {
321                 draw_icon_oops(v1, oops->type);
322         }
323         if(oops->flag & SELECT) cpack(0xFFFFFF); 
324         else cpack(0x0);
325         glRasterPos3f(v1[0],  v1[1], 0.0);
326         BMF_DrawString(G.fonts, str);
327
328         if(line) setlinestyle(2);
329         cpack(border);
330
331         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
332         glRectf(x1,  y1,  x2,  y2);
333         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
334         if(line) setlinestyle(0);
335
336         /* connection blocks */
337         ol= oops->link.first;
338         while(ol) {
339
340                 f1= x1+ol->xof; 
341                 f2= y1+ol->yof;
342
343                 body= give_oops_color(ol->type, oops->flag & SELECT, &border);
344                 cpack(body);
345
346                 glRectf(f1-.2,  f2-.2,  f1+.2,  f2+.2);
347                 cpack(border);
348
349                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
350
351                 glRectf(f1-.2,  f2-.2,  f1+.2,  f2+.2);
352
353                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
354
355                 ol= ol->next;
356         }
357
358         if(oops->flag & OOPS_REFER) {
359                         /* Draw the little rounded connection point */
360                 glColor3ub(0, 0, 0);
361                 glPushMatrix();
362
363                 glTranslatef(oops->x + 0.5*OOPSX, oops->y, 0.0);
364                 glutil_draw_filled_arc(0.0, M_PI, 0.05*OOPSX, 7);
365
366                 glPopMatrix();
367         }
368 }
369
370 void drawoopsspace(ScrArea *sa, void *spacedata)
371 {
372         uiBlock *block;
373         Oops *oops;
374         int ofsx, ofsy;
375         char name[32];
376         
377         glClearColor(0.55, 0.55, 0.55, 0.0);
378         glClear(GL_COLOR_BUFFER_BIT);
379         if(G.soops==0) return;  
380
381         sprintf(name, "win %d", curarea->win);
382         block= uiNewBlock(&curarea->uiblocks, name, UI_EMBOSSF, UI_HELVB, curarea->win);
383
384         boundbox_oops();
385         calc_scrollrcts(G.v2d, curarea->winx, curarea->winy);
386
387         if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
388                 if(G.v2d->scroll) {     
389                         ofsx= curarea->winrct.xmin;     /* because of mywin */
390                         ofsy= curarea->winrct.ymin;
391
392                         glViewport(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); 
393                         glScissor(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
394                 }
395         }
396
397         myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
398
399         oopscalex= .14*((float)curarea->winx)/(G.v2d->cur.xmax-G.v2d->cur.xmin);
400         calc_ipogrid(); /* for scrollvariables */
401         build_oops();
402
403         oops= G.soops->oops.first;
404         while(oops) {
405                 if(oops->hide==0) {
406                         draw_oopslink(oops);
407                 }
408                 oops= oops->next;
409         }
410         oops= G.soops->oops.first;
411         while(oops) {
412                 if(oops->hide==0) {
413                         if(oops->flag & SELECT); else draw_oops(oops, block);
414                 }
415                 oops= oops->next;
416         }
417         oops= G.soops->oops.first;
418         while(oops) {
419                 if(oops->hide==0) {
420                         if(oops->flag & SELECT) draw_oops(oops, block);
421                 }
422                 oops= oops->next;
423         }
424         
425         /* restore viewport */
426         mywinset(curarea->win);
427
428         
429         if(G.v2d->scroll) {     
430                 /* ortho at pixel level curarea */
431                 myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5);
432                 drawscroll(0);          
433         }
434         
435         uiDrawBlock(block);
436         
437         curarea->win_swap= WIN_BACK_OK;
438 }
439
440
441