soc-2008-mxcurioni: foundations for Freestyle as a render layer - new UI buttons...
[blender.git] / source / blender / src / buttons_script.c
1 /**
2  * $Id$ 
3  *
4  * ***** BEGIN GPL 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.
10  *
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.
15  *
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.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <time.h>
31 #include <math.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "MEM_guardedalloc.h"
40 #include "DNA_action_types.h"
41 #include "DNA_armature_types.h"
42 #include "DNA_camera_types.h"
43 #include "DNA_constraint_types.h"
44 #include "DNA_curve_types.h"
45 #include "DNA_effect_types.h"
46 #include "DNA_group_types.h"
47 #include "DNA_ID.h"
48 #include "DNA_image_types.h"
49 #include "DNA_key_types.h"
50 #include "DNA_lamp_types.h"
51 #include "DNA_lattice_types.h"
52 #include "DNA_material_types.h"
53 #include "DNA_meta_types.h"
54 #include "DNA_object_types.h"
55 #include "DNA_radio_types.h"
56 #include "DNA_screen_types.h"
57 #include "DNA_scene_types.h"
58 #include "DNA_sound_types.h"
59 #include "DNA_text_types.h"
60 #include "DNA_texture_types.h"
61 #include "DNA_userdef_types.h"
62 #include "DNA_vfont_types.h"
63 #include "DNA_view3d_types.h"
64 #include "DNA_world_types.h"
65 #include "DNA_space_types.h"
66
67 #include "BKE_anim.h"
68 #include "BKE_armature.h"
69 #include "BKE_constraint.h"
70 #include "BKE_curve.h"
71 #include "BKE_displist.h"
72 #include "BKE_effect.h"
73 #include "BKE_font.h"
74 #include "BKE_image.h"
75 #include "BKE_ipo.h"
76 #include "BKE_lattice.h"
77 #include "BKE_main.h"
78 #include "BKE_material.h"
79 #include "BKE_mball.h"
80 #include "BKE_mesh.h"
81 #include "BKE_object.h"
82 #include "BKE_sound.h"
83 #include "BKE_texture.h"
84 #include "BKE_global.h"
85 #include "BKE_utildefines.h"
86
87 #include "BLI_blenlib.h"
88 #include "BLI_dynstr.h"
89
90 #include "BSE_filesel.h"
91
92 #include "BIF_gl.h"
93 #include "BIF_graphics.h"
94 #include "BIF_keyval.h"
95 #include "BIF_mainqueue.h"
96 #include "BIF_resources.h"
97 #include "BIF_screen.h"
98 #include "BIF_mywindow.h"
99 #include "BIF_space.h"
100 #include "BIF_glutil.h"
101 #include "BIF_interface.h"
102 #include "BIF_toolbox.h"
103
104 #include "BIF_butspace.h"
105
106 #include "mydevice.h"
107 #include "blendef.h"
108 #include "butspace.h"
109
110 /* ************************ function prototypes ********************** */
111 void draw_scriptlink(uiBlock *, ScriptLink *, int , int , int ) ;
112
113 /* *************************** SCRIPT ******************************** */
114
115 static void extend_scriptlink(ScriptLink *slink)
116 {
117         void *stmp, *ftmp;
118
119         if (!slink) return;
120                 
121         stmp= slink->scripts;           
122         slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1), "scriptlistL");
123         
124         ftmp= slink->flag;              
125         slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1), "scriptlistF");
126         
127         if (slink->totscript) {
128                 memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript));
129                 MEM_freeN(stmp);
130
131                 memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript));
132                 MEM_freeN(ftmp);
133         }
134
135         slink->scripts[slink->totscript]= NULL;
136         slink->flag[slink->totscript]= SCRIPT_FRAMECHANGED;
137
138         slink->totscript++;
139         slink->actscript = slink->totscript;
140 }
141
142 static void delete_scriptlink(ScriptLink *slink)
143 {
144         int i;
145         
146         if (!slink) return;
147         
148         if (slink->totscript>0) {
149                 for (i=slink->actscript-1; i<slink->totscript-1; i++) {
150                         slink->flag[i]= slink->flag[i+1];
151                         slink->scripts[i]= slink->scripts[i+1];
152                 }
153                 
154                 slink->totscript--;
155         }
156                 
157         CLAMP(slink->actscript, 1, slink->totscript);
158                 
159         if (slink->totscript==0) {
160                 if (slink->scripts) MEM_freeN(slink->scripts);
161                 if (slink->flag) MEM_freeN(slink->flag);
162
163                 slink->scripts= NULL;
164                 slink->flag= NULL;
165                 slink->totscript= slink->actscript= 0;                  
166         }
167 }
168
169 static char *scriptlinks_menu_string(void)
170 {
171         char *menu = NULL;
172         DynStr *ds = BLI_dynstr_new();
173         Text *text = G.main->text.first;
174         int txtcounter = 0;
175
176         if (text) {
177                 BLI_dynstr_append(ds, "Select Script Link%t");
178                 while (text) {
179                         BLI_dynstr_append(ds, "|");
180                         BLI_dynstr_append(ds, text->id.name+2);
181                         txtcounter += 1;
182                         text = text->id.next;
183                 }
184                 if (txtcounter) menu = BLI_dynstr_get_cstring(ds);
185         }
186         BLI_dynstr_free(ds);
187         return menu;
188 }
189
190 static void scriptlinks_pupmenu(ScriptLink *slink)
191 {
192         short menuitem;
193         char *menustr = scriptlinks_menu_string();
194
195         if (!slink) return;
196
197         if (menustr) {
198                 menuitem = pupmenu_col(menustr, 20);
199                 MEM_freeN(menustr);
200                 if (menuitem > 0) {
201                         Text *text = G.main->text.first;
202                         while (--menuitem) text = text->id.next;
203                         if (text) slink->scripts[slink->totscript - 1]= (ID *)text;
204                 }
205         }
206 }
207
208 void do_scriptbuts(unsigned short event)
209 {
210         Object *ob=NULL;
211         ScriptLink *slink=NULL;
212         Material *ma;
213         
214         switch (event) {
215         case B_SSCRIPT_ADD:
216                 slink = &G.scene->scriptlink;
217                 extend_scriptlink(slink);
218                 BIF_undo_push("Add scriptlink");
219                 scriptlinks_pupmenu(slink);
220                 break;
221         case B_SSCRIPT_DEL:
222                 BIF_undo_push("Delete scriptlink");
223                 delete_scriptlink(&G.scene->scriptlink);
224                 break;
225                 
226         case B_SCRIPT_ADD:
227         case B_SCRIPT_DEL:
228                 ob= OBACT;
229
230                 if (ob && G.buts->scriptblock==ID_OB) {
231                                 slink= &ob->scriptlink;
232
233                 } else if (ob && G.buts->scriptblock==ID_MA) {
234                         ma= give_current_material(ob, ob->actcol);
235                         if (ma) slink= &ma->scriptlink;
236
237                 } else if (ob && G.buts->scriptblock==ID_CA) {
238                         if (ob->type==OB_CAMERA)
239                                 slink= &((Camera *)ob->data)->scriptlink;
240
241                 } else if (ob && G.buts->scriptblock==ID_LA) {
242                         if (ob->type==OB_LAMP)
243                                 slink= &((Lamp *)ob->data)->scriptlink;
244
245                 } else if (G.buts->scriptblock==ID_WO) {
246                         if (G.scene->world) 
247                                 slink= &(G.scene->world->scriptlink);
248                 }
249                 
250                 if (event==B_SCRIPT_ADD) {
251                         extend_scriptlink(slink);
252                         BIF_undo_push("Add scriptlink");
253                         scriptlinks_pupmenu(slink);
254                 }
255                 else {
256                         delete_scriptlink(slink);
257                         BIF_undo_push("Delete scriptlink");
258                 }
259                 break;
260         default:
261                 break;
262         }
263
264         allqueue(REDRAWBUTSSCRIPT, 0);
265         allqueue(REDRAWOOPS, 0);
266 }
267
268 void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int idcode) 
269 {
270         char str[256];
271
272         if (script->totscript) {
273                 strcpy(str, "FrameChanged%x 1|");
274                 strcat(str, "Redraw%x 4|");
275                 strcat(str, "Render%x 16|");
276                 if (idcode==ID_SCE) {
277                         strcat(str, "OnLoad%x 2|");
278                         strcat(str, "OnSave%x 8");
279                 } else {
280                         strcat(str, "ObjectUpdate%x 64|");
281                         strcat(str, "ObDataUpdate%x 128");
282                 }
283                 uiBlockBeginAlign(block);
284                 uiDefButS(block, MENU, 1, str, (short)sx, (short)sy, 140, 19, &script->flag[script->actscript-1], 0, 0, 0, 0, "Script links for this event");
285
286                 uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", (short)(sx+140),(short)sy, 140, 19, &script->scripts[script->actscript-1], "Name of Script to link");
287                 uiBlockEndAlign(block);
288         }
289         
290         sprintf(str,"%d Scr:", script->totscript);
291         
292         uiDefButS(block, NUM, REDRAWBUTSSCRIPT, str, (short)(sx+140), (short)sy-20,60,19, &script->actscript, 1, script->totscript, 0, 0, "Total / Active Script link (LeftMouse + Drag to change)");
293
294         if (idcode==ID_SCE) {
295                 
296                 if (script->totscript<32767) 
297                         uiDefBut(block, BUT, B_SSCRIPT_ADD, "New", (short)(sx+240), (short)sy-20, 40, 19, 0, 0, 0, 0, 0, "Add a new Script link");
298                 if (script->totscript) 
299                         uiDefBut(block, BUT, B_SSCRIPT_DEL, "Del", (short)(sx+200), (short)sy-20, 40, 19, 0, 0, 0, 0, 0, "Delete the current Script link");
300                 uiDefBut(block, LABEL, 0, "Scene Script link",  sx,sy-20,140,20, 0, 0, 0, 0, 0, "");
301         }
302         else {
303                 if (script->totscript<32767) 
304                         uiDefBut(block, BUT, B_SCRIPT_ADD, "New", (short)(sx+240), (short)sy-20, 40, 19, 0, 0, 0, 0, 0, "Add a new Script link");
305                 if (script->totscript) 
306                         uiDefBut(block, BUT, B_SCRIPT_DEL, "Del", (short)(sx+200), (short)sy-20, 40, 19, 0, 0, 0, 0, 0, "Delete the current Script link");
307                 uiDefBut(block, LABEL, 0, "Selected Script link",       sx,sy-20,140,20, 0, 0, 0, 0, 0, "");
308                 
309         }
310         
311 }
312
313 /* ************************************* */
314
315 static void  script_panel_scriptlink(void)
316 {
317         uiBlock *block;
318         Object *ob=NULL;
319         ScriptLink *script=NULL;
320         Material *ma;
321         int xco = 10;
322
323         block= uiNewBlock(&curarea->uiblocks, "script_panel_scriptlink", UI_EMBOSS, UI_HELV, curarea->win);
324         if(uiNewPanel(curarea, block, "Scriptlinks", "Script", 0, 0, 318, 204)==0) return;
325
326         uiDefButBitI(block, TOG, G_DOSCRIPTLINKS, REDRAWBUTSSCRIPT,
327                         "Enable Script Links", xco, 200, 150, 20, &G.f, 0, 0, 0, 0,
328                         "Enable execution of all assigned Script links and Space Handelers");
329         /* for proper alignment: */
330         uiDefBut(block, LABEL, 0, "",   160, 200,150,20, NULL, 0.0, 0.0, 0, 0, "");
331         
332         if (G.f & G_DOSCRIPTLINKS) {
333                 //uiBlockBeginAlign(block);
334                 ob= OBACT;
335                 if(ob) 
336                         uiDefIconButS(block, ROW, B_REDR, ICON_OBJECT, xco,175,25,20, &G.buts->scriptblock,  2.0, (float)ID_OB, 0, 0, "Displays Object script links");
337
338                 if(ob && give_current_material(ob, ob->actcol))
339                         uiDefIconButS(block, ROW, B_REDR, ICON_MATERIAL,        xco+=25,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_MA, 0, 0, "Displays Material script links ");
340
341                 if(G.scene->world) 
342                         uiDefIconButS(block, ROW, B_REDR, ICON_WORLD,   xco+=25,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_WO, 0, 0, "Displays World script links");
343
344                 if(ob && ob->type==OB_CAMERA)
345                         uiDefIconButS(block, ROW, B_REDR, ICON_CAMERA,  xco+=25,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_CA, 0, 0, "Displays Camera script links");
346
347                 if(ob && ob->type==OB_LAMP)
348                         uiDefIconButS(block, ROW, B_REDR, ICON_LAMP,    xco+=25,175,25,20, &G.buts->scriptblock, 2.0, (float)ID_LA, 0, 0, "Displays Lamp script links");
349                 //uiBlockEndAlign(block);
350
351                 if (ob && G.buts->scriptblock==ID_OB) {
352                         script= &ob->scriptlink;
353                 
354                 } else if (ob && G.buts->scriptblock==ID_MA) {
355                         ma= give_current_material(ob, ob->actcol);
356                         if (ma) script= &ma->scriptlink;
357                 
358                 } else if (ob && G.buts->scriptblock==ID_CA) {
359                         if (ob->type==OB_CAMERA)
360                                 script= &((Camera *)ob->data)->scriptlink;
361                         
362                 } else if (ob && G.buts->scriptblock==ID_LA) {
363                         if (ob->type==OB_LAMP)
364                                 script= &((Lamp *)ob->data)->scriptlink;
365
366                 } else if (G.buts->scriptblock==ID_WO) {
367                         if (G.scene->world)
368                                 script= &(G.scene->world->scriptlink);
369                 }
370
371                 if (script) draw_scriptlink(block, script, 10, 140, 0);
372
373                 draw_scriptlink(block, &G.scene->scriptlink, 10, 80, ID_SCE);
374         }
375 }
376
377
378
379
380 void script_panels()
381 {
382         script_panel_scriptlink();
383         
384 }