Lotsa undo stuff added;
[blender.git] / source / blender / src / buttons_script.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 <time.h>
34 #include <math.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #ifdef WIN32
43 #include "BLI_winstuff.h"
44 #endif
45
46 #include "MEM_guardedalloc.h"
47 #include "DNA_action_types.h"
48 #include "DNA_armature_types.h"
49 #include "DNA_camera_types.h"
50 #include "DNA_constraint_types.h"
51 #include "DNA_curve_types.h"
52 #include "DNA_effect_types.h"
53 #include "DNA_group_types.h"
54 #include "DNA_ika_types.h"
55 #include "DNA_image_types.h"
56 #include "DNA_key_types.h"
57 #include "DNA_lamp_types.h"
58 #include "DNA_lattice_types.h"
59 #include "DNA_material_types.h"
60 #include "DNA_meta_types.h"
61 #include "DNA_object_types.h"
62 #include "DNA_radio_types.h"
63 #include "DNA_screen_types.h"
64 #include "DNA_scene_types.h"
65 #include "DNA_sound_types.h"
66 #include "DNA_texture_types.h"
67 #include "DNA_userdef_types.h"
68 #include "DNA_vfont_types.h"
69 #include "DNA_view3d_types.h"
70 #include "DNA_world_types.h"
71 #include "DNA_space_types.h"
72
73 #include "BKE_anim.h"
74 #include "BKE_armature.h"
75 #include "BKE_constraint.h"
76 #include "BKE_curve.h"
77 #include "BKE_displist.h"
78 #include "BKE_effect.h"
79 #include "BKE_font.h"
80 #include "BKE_ika.h"
81 #include "BKE_image.h"
82 #include "BKE_ipo.h"
83 #include "BKE_lattice.h"
84 #include "BKE_material.h"
85 #include "BKE_mball.h"
86 #include "BKE_mesh.h"
87 #include "BKE_object.h"
88 #include "BKE_sound.h"
89 #include "BKE_texture.h"
90 #include "BKE_global.h"
91 #include "BKE_utildefines.h"
92
93 #include "BLI_blenlib.h"
94
95 #include "BSE_filesel.h"
96
97 #include "BIF_gl.h"
98 #include "BIF_graphics.h"
99 #include "BIF_keyval.h"
100 #include "BIF_mainqueue.h"
101 #include "BIF_resources.h"
102 #include "BIF_screen.h"
103 #include "BIF_mywindow.h"
104 #include "BIF_space.h"
105 #include "BIF_glutil.h"
106 #include "BIF_interface.h"
107 #include "BIF_toolbox.h"
108
109 #include "BIF_butspace.h"
110
111 #include "mydevice.h"
112 #include "blendef.h"
113 #include "butspace.h"
114
115
116
117
118
119
120 /* *************************** SCRIPT ******************************** */
121
122 static void extend_scriptlink(ScriptLink *slink)
123 {
124         void *stmp, *ftmp;
125
126         if (!slink) return;
127                 
128         stmp= slink->scripts;           
129         slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1), "scriptlistL");
130         
131         ftmp= slink->flag;              
132         slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1), "scriptlistF");
133         
134         if (slink->totscript) {
135                 memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript));
136                 MEM_freeN(stmp);
137
138                 memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript));
139                 MEM_freeN(ftmp);
140         }
141
142         slink->scripts[slink->totscript]= NULL;
143         slink->flag[slink->totscript]= SCRIPT_FRAMECHANGED;
144
145         slink->totscript++;
146                                 
147         if(slink->actscript<1) slink->actscript=1;
148 }
149
150 static void delete_scriptlink(ScriptLink *slink)
151 {
152         int i;
153         
154         if (!slink) return;
155         
156         if (slink->totscript>0) {
157                 for (i=slink->actscript-1; i<slink->totscript-1; i++) {
158                         slink->flag[i]= slink->flag[i+1];
159                         slink->scripts[i]= slink->scripts[i+1];
160                 }
161                 
162                 slink->totscript--;
163         }
164                 
165         CLAMP(slink->actscript, 1, slink->totscript);
166                 
167         if (slink->totscript==0) {
168                 if (slink->scripts) MEM_freeN(slink->scripts);
169                 if (slink->flag) MEM_freeN(slink->flag);
170
171                 slink->scripts= NULL;
172                 slink->flag= NULL;
173                 slink->totscript= slink->actscript= 0;                  
174         }
175 }
176
177 void do_scriptbuts(unsigned short event)
178 {
179         Object *ob=NULL;
180         ScriptLink *script=NULL;
181         Material *ma;
182         
183         switch (event) {
184         case B_SSCRIPT_ADD:
185                 extend_scriptlink(&G.scene->scriptlink);
186                 BIF_undo_push("Add scriptlink");
187                 break;
188         case B_SSCRIPT_DEL:
189                 BIF_undo_push("Delete scriptlink");
190                 delete_scriptlink(&G.scene->scriptlink);
191                 break;
192                 
193         case B_SCRIPT_ADD:
194         case B_SCRIPT_DEL:
195                 ob= OBACT;
196
197                 if (ob && G.buts->scriptblock==ID_OB) {
198                                 script= &ob->scriptlink;
199
200                 } else if (ob && G.buts->scriptblock==ID_MA) {
201                         ma= give_current_material(ob, ob->actcol);
202                         if (ma) script= &ma->scriptlink;
203
204                 } else if (ob && G.buts->scriptblock==ID_CA) {
205                         if (ob->type==OB_CAMERA)
206                                 script= &((Camera *)ob->data)->scriptlink;
207
208                 } else if (ob && G.buts->scriptblock==ID_LA) {
209                         if (ob->type==OB_LAMP)
210                                 script= &((Lamp *)ob->data)->scriptlink;
211
212                 } else if (G.buts->scriptblock==ID_WO) {
213                         if (G.scene->world) 
214                                 script= &(G.scene->world->scriptlink);
215                 }
216                 
217                 if (event==B_SCRIPT_ADD) {
218                         extend_scriptlink(script);
219                         BIF_undo_push("Add scriptlink");
220                 }
221                 else {
222                         delete_scriptlink(script);
223                         BIF_undo_push("Delete scriptlink");
224                 }
225                 break;
226         default:
227                 break;
228         }
229
230         allqueue(REDRAWBUTSSCRIPT, 0);
231 }
232
233 void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int scene) 
234 {
235         char str[256];
236
237         if (script->totscript) {
238                 strcpy(str, "FrameChanged%x 1|");
239                 strcat(str, "Redraw%x 4|");
240                 if (scene) {
241                         strcat(str, "OnLoad%x 2|");
242                         strcat(str, "OnSave%x 8");
243                 }
244
245                 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");
246
247                 uiDefIDPoinBut(block, test_scriptpoin_but, 1, "", (short)(sx+140),(short)sy, 140, 19, &script->scripts[script->actscript-1], "Name of Script to link");
248         }
249
250         sprintf(str,"%d Scr:", script->totscript);
251         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)");
252
253         if (scene) {
254                 if (script->totscript<32767) 
255                         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");
256                 if (script->totscript) 
257                         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");
258
259                 uiDefBut(block, LABEL, 0, "Scene scriptlink",   sx,sy-20,140,20, 0, 0, 0, 0, 0, "");
260
261         } 
262         else {
263                 if (script->totscript<32767) 
264                         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");
265                 if (script->totscript) 
266                         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");
267
268                 uiDefBut(block, LABEL, 0, "Selected scriptlink",        sx,sy-20,140,20, 0, 0, 0, 0, 0, "");
269         }               
270 }
271
272 /* ************************************* */
273
274 static void  script_panel_scriptlink(void)
275 {
276         uiBlock *block;
277         Object *ob=NULL;
278         ScriptLink *script=NULL;
279         Material *ma;
280         int xco = 10;
281         
282         block= uiNewBlock(&curarea->uiblocks, "script_panel_scriptlink", UI_EMBOSS, UI_HELV, curarea->win);
283         if(uiNewPanel(curarea, block, "Scriptlinks", "Script", 0, 0, 318, 204)==0) return;
284         
285         
286         ob= OBACT;
287         if(ob) 
288                 uiDefIconButS(block, ROW, B_REDR, ICON_OBJECT, xco,180,25,20, &G.buts->scriptblock,  2.0, (float)ID_OB, 0, 0, "Displays Object script links");
289
290         if(ob && give_current_material(ob, ob->actcol))
291                 uiDefIconButS(block, ROW, B_REDR, ICON_MATERIAL,        xco+=25,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_MA, 0, 0, "Displays Material script links ");
292
293         if(G.scene->world) 
294                 uiDefIconButS(block, ROW, B_REDR, ICON_WORLD,   xco+=25,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_WO, 0, 0, "Displays World script links");
295
296         if(ob && ob->type==OB_CAMERA)
297                 uiDefIconButS(block, ROW, B_REDR, ICON_CAMERA,  xco+=25,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_CA, 0, 0, "Displays Camera script links");
298
299         if(ob && ob->type==OB_LAMP)
300                 uiDefIconButS(block, ROW, B_REDR, ICON_LAMP,    xco+=25,180,25,20, &G.buts->scriptblock, 2.0, (float)ID_LA, 0, 0, "Displays Lamp script links");
301
302
303         if (ob && G.buts->scriptblock==ID_OB) {
304                 script= &ob->scriptlink;
305                 
306         } else if (ob && G.buts->scriptblock==ID_MA) {
307                 ma= give_current_material(ob, ob->actcol);
308                 if (ma) script= &ma->scriptlink;
309                 
310         } else if (ob && G.buts->scriptblock==ID_CA) {
311                 if (ob->type==OB_CAMERA)
312                         script= &((Camera *)ob->data)->scriptlink;
313                         
314         } else if (ob && G.buts->scriptblock==ID_LA) {
315                 if (ob->type==OB_LAMP)
316                         script= &((Lamp *)ob->data)->scriptlink;
317
318         } else if (G.buts->scriptblock==ID_WO) {
319                 if (G.scene->world)
320                         script= &(G.scene->world->scriptlink);
321         }
322
323         if (script) draw_scriptlink(block, script, 10, 140, 0);                 
324
325         draw_scriptlink(block, &G.scene->scriptlink, 10, 80, 1);
326
327
328 }
329
330
331
332
333 void script_panels()
334 {
335         script_panel_scriptlink();
336         
337 }