6ddaaf345c39b3a2a89c73df55ea63ee21991e20
[blender-staging.git] / source / blender / python / api2_2x / sceneSequence.c
1 /*
2  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. The Blender
8  * Foundation also sells licenses for use in proprietary software under
9  * the Blender License.  See http://www.blender.org/BL/ for information
10  * about this.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * This is a new part of Blender.
25  *
26  * Contributor(s): Campbell Barton
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30
31 #include "sceneSequence.h" /* This must come first */
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_sequence_types.h"
36 #include "DNA_scene_types.h" /* for Base */
37
38 #include "BKE_mesh.h"
39 #include "BKE_library.h"
40 #include "BKE_global.h"
41 #include "BKE_main.h"
42 #include "BKE_scene.h"
43
44 #include "BIF_editseq.h" /* get_last_seq */
45 #include "BLI_blenlib.h"
46 #include "BSE_sequence.h"
47 #include "Ipo.h"
48 #include "blendef.h"  /* CLAMP */
49 #include "BKE_utildefines.h"
50 #include "Scene.h"
51 #include "Sound.h"
52 #include "gen_utils.h"
53
54 enum seq_consts {
55         EXPP_SEQ_ATTR_TYPE = 0,
56         EXPP_SEQ_ATTR_CHAN,
57         EXPP_SEQ_ATTR_LENGTH,
58         EXPP_SEQ_ATTR_START,
59         EXPP_SEQ_ATTR_STARTOFS,
60         EXPP_SEQ_ATTR_ENDOFS,
61         EXPP_SEQ_ATTR_STARTSTILL,
62         EXPP_SEQ_ATTR_ENDSTILL
63 };
64
65
66 /*****************************************************************************/
67 /* Python API function prototypes for the Blender module.                */
68 /*****************************************************************************/
69 /*PyObject *M_Sequence_Get( PyObject * self, PyObject * args );*/
70
71 /*****************************************************************************/
72 /* Python method structure definition for Blender.Object module:         */
73 /*****************************************************************************/
74 /*struct PyMethodDef M_Sequence_methods[] = {
75         {"Get", ( PyCFunction ) M_Sequence_Get, METH_VARARGS,
76 "(name) - return the sequence with the name 'name',\
77 returns None if notfound.\nIf 'name' is not specified, it returns a list of all sequences."},
78         {NULL, NULL, 0, NULL}
79 };*/
80
81 /*****************************************************************************/
82 /* Python BPy_Sequence methods table:                                      */
83 /*****************************************************************************/
84 static PyObject *Sequence_copy( BPy_Sequence * self );
85 static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args );
86 static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args );
87
88 static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args );
89 static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args );
90 static void intern_pos_update(Sequence * seq); 
91
92 static PyMethodDef BPy_Sequence_methods[] = {
93         /* name, method, flags, doc */
94         {"new", ( PyCFunction ) Sequence_new, METH_VARARGS,
95          "(data) - Return a new sequence."},
96         {"remove", ( PyCFunction ) Sequence_remove, METH_VARARGS,
97          "(data) - Remove a strip."},
98         {"__copy__", ( PyCFunction ) Sequence_copy, METH_NOARGS,
99          "() - Return a copy of the sequence containing the same objects."},
100         {"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS,
101          "() - Return a copy of the sequence containing the same objects."},
102         {NULL, NULL, 0, NULL}
103 };
104
105 static PyMethodDef BPy_SceneSeq_methods[] = {
106         /* name, method, flags, doc */
107         {"new", ( PyCFunction ) SceneSeq_new, METH_VARARGS,
108          "(data) - Return a new sequence."},
109         {"remove", ( PyCFunction ) SceneSeq_remove, METH_VARARGS,
110          "(data) - Remove a strip."},
111         {NULL, NULL, 0, NULL}
112 };
113
114 /* use to add a sequence to a scene or its listbase */
115 static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
116 {
117         PyObject *py_data = NULL;
118         
119         Sequence *seq;
120         int a;
121         Strip *strip;
122         StripElem *se;
123         int start, machine;
124         
125         if( !PyArg_ParseTuple( args, "Oii", &py_data, &start, &machine ) )
126                 return EXPP_ReturnPyObjError( PyExc_ValueError,
127                         "expect sequence data then 2 ints - (seqdata, start, track)" );
128         
129         seq = alloc_sequence(seqbase, start, machine); /* warning, this sets last */
130         
131         if (PyTuple_Check(py_data)) {
132                 /* Image */
133                 PyObject *list;
134                 char *name;
135                 
136                 if (!PyArg_ParseTuple( py_data, "sO!", &name, &PyList_Type, &list)) {
137                         BLI_remlink(seqbase, seq);
138                         MEM_freeN(seq);
139                         
140                         return EXPP_ReturnPyObjError( PyExc_ValueError,
141                                 "images data needs to be a tuple of a string and a list of images - (path, [filenames...])" );
142                 }
143                 
144                 seq->type= SEQ_IMAGE;
145                 
146                 seq->len = PyList_Size( list );
147                 
148                 
149                 /* strip and stripdata */
150                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
151                 strip->len= seq->len;
152                 strip->us= 1;
153                 strncpy(strip->dir, name, FILE_MAXDIR-1);
154                 strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
155
156                 for(a=0; a<seq->len; a++) {
157                         name = PyString_AsString(PyList_GetItem( list, a ));
158                         strncpy(se->name, name, FILE_MAXFILE-1);
159                         se->ok= 1;
160                         se++;
161                 }               
162                 
163         } else if (BPy_Sound_Check(py_data)) {
164                 /* sound */
165                 int totframe;
166                 bSound *sound = (( BPy_Sound * )py_data)->sound;
167                 
168                 
169                 seq->type= SEQ_RAM_SOUND;
170                 seq->sound = sound;
171                 
172                 totframe= (int) ( ((float)(sound->streamlen-1)/( (float)sce->audio.mixrate*4.0 ))* (float)sce->r.frs_sec / sce->r.frs_sec_base);
173                 
174                 sound->flags |= SOUND_FLAGS_SEQUENCE;
175                 
176                 
177                 /* strip and stripdata */
178                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
179                 strip->len= totframe;
180                 strip->us= 1;
181                 strncpy(strip->dir, sound->name, FILE_MAXDIR-1);
182                 strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
183
184                 /* name sound in first strip */
185                 strncpy(se->name, sound->name, FILE_MAXFILE-1);
186
187                 for(a=1; a<=totframe; a++, se++) {
188                         se->ok= 2; /* why? */
189                         se->ibuf= 0;
190                         se->nr= a;
191                 }
192                 
193         } else if (BPy_Scene_Check(py_data)) {
194                 /* scene */
195                 Scene *sce = ((BPy_Scene *)py_data)->scene;
196                 
197                 seq->type= SEQ_SCENE;
198                 seq->scene= sce;
199                 
200                 /*seq->sfra= sce->r.sfra;*/
201                 seq->len= sce->r.efra - sce->r.sfra + 1;
202
203                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
204                 strncpy(seq->name + 2, sce->id.name + 2, 
205                         sizeof(seq->name) - 2);
206                 strip->len= seq->len;
207                 strip->us= 1;
208                 if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
209                 
210         } else {
211                 /* movie, pydata is a path to a movie file */
212                 char *name = PyString_AsString ( py_data );
213                 if (!name) {
214                         /* only free these 2 because other stuff isnt set */
215                         BLI_remlink(seqbase, seq);
216                         MEM_freeN(seq);
217                         
218                         return EXPP_ReturnPyObjError( PyExc_TypeError,
219                                 "expects a string for chan/bone name and an int for the frame where to put the new key" );
220                 }
221                 
222                 seq->type= SEQ_MOVIE;
223         }
224         strncpy(seq->name+2, "Untitled", 21);
225         intern_pos_update(seq);
226         return Sequence_CreatePyObject(seq, NULL, sce);
227 }
228
229 static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args )
230 {
231         return NewSeq_internal(&self->seq->seqbase, args, self->scene);
232 }
233
234 static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args )
235 {
236         return NewSeq_internal( &((Editing *)self->scene->ed)->seqbase, args, self->scene);
237 }
238
239 static void del_seq__internal(Sequence *seq)
240 {
241         if(seq->ipo) seq->ipo->id.us--;
242         
243         if(seq->type==SEQ_RAM_SOUND && seq->sound) 
244                 seq->sound->id.us--;
245         free_sequence(seq);
246 }
247
248 static void recurs_del_seq(ListBase *lb)
249 {
250         Sequence *seq, *seqn;
251
252         seq= lb->first;
253         while(seq) {
254                 seqn= seq->next;
255                 BLI_remlink(lb, seq);
256                 if(seq->type==SEQ_META) recurs_del_seq(&seq->seqbase);
257                 del_seq__internal(seq);
258                 seq= seqn;
259         }
260 }
261
262 static PyObject *RemoveSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
263 {
264         BPy_Sequence *bpy_seq = NULL;
265         
266         if( !PyArg_ParseTuple( args, "O!", &Sequence_Type, &bpy_seq ) )
267                 return EXPP_ReturnPyObjError( PyExc_ValueError,
268                         "expects a sequence object" );
269         
270         /* quick way to tell if we dont have the seq */
271         if (sce != bpy_seq->scene)
272                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
273                         "Sequence does not exist here, cannot remove" );
274         
275         recurs_del_seq(&bpy_seq->seq->seqbase);
276         del_seq__internal(bpy_seq->seq);
277         clear_last_seq(); /* just incase */
278         Py_RETURN_NONE;
279 }
280
281 static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args )
282 {
283         return RemoveSeq_internal(&self->seq->seqbase, args, self->scene);
284 }
285
286 static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args )
287 {
288         return RemoveSeq_internal( &((Editing *)self->scene->ed)->seqbase, args, self->scene);
289 }
290
291
292 static PyObject *Sequence_copy( BPy_Sequence * self )
293 {
294         printf("Sequence Copy not implimented yet!\n");
295         Py_RETURN_NONE;
296 }
297
298 /*****************************************************************************/
299 /* PythonTypeObject callback function prototypes                         */
300 /*****************************************************************************/
301 static PyObject *Sequence_repr( BPy_Sequence * obj );
302 static PyObject *SceneSeq_repr( BPy_SceneSeq * obj );
303 static int Sequence_compare( BPy_Sequence * a, BPy_Sequence * b );
304 static int SceneSeq_compare( BPy_SceneSeq * a, BPy_SceneSeq * b );
305
306 /*****************************************************************************/
307 /* Python BPy_Sequence methods:                                                  */
308 /*****************************************************************************/
309
310
311 static PyObject *Sequence_getIter( BPy_Sequence * self )
312 {
313         Sequence *iter = self->seq->seqbase.first;
314         
315         if (!self->iter) {
316                 self->iter = iter;
317                 return EXPP_incr_ret ( (PyObject *) self );
318         } else {
319                 return Sequence_CreatePyObject(self->seq, iter, self->scene);
320         }
321 }
322
323 static PyObject *SceneSeq_getIter( BPy_SceneSeq * self )
324 {
325         Sequence *iter = ((Editing *)self->scene->ed)->seqbase.first;
326         
327         if (!self->iter) {
328                 self->iter = iter;
329                 return EXPP_incr_ret ( (PyObject *) self );
330         } else {
331                 return SceneSeq_CreatePyObject(self->scene, iter);
332         }
333 }
334
335
336 /*
337  * Return next Seq
338  */
339 static PyObject *Sequence_nextIter( BPy_Sequence * self )
340 {
341         PyObject *object;
342         if( !(self->iter) ) {
343                 self->iter = NULL; /* so we can add objects again */
344                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
345                                 "iterator at end" );
346         }
347         
348         object= Sequence_CreatePyObject( self->iter, NULL, self->scene ); 
349         self->iter= self->iter->next;
350         return object;
351 }
352
353
354 /*
355  * Return next Seq
356  */
357 static PyObject *SceneSeq_nextIter( BPy_Sequence * self )
358 {
359         PyObject *object;
360         if( !(self->iter) ) {
361                 self->iter = NULL; /* so we can add objects again */
362                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
363                                 "iterator at end" );
364         }
365         
366         object= Sequence_CreatePyObject( self->iter, NULL, self->scene );
367         self->iter= self->iter->next;
368         return object;
369 }
370
371
372
373 static PyObject *Sequence_getName( BPy_Sequence * self )
374 {
375         return PyString_FromString( self->seq->name+2 );
376 }
377
378 static int Sequence_setName( BPy_Sequence * self, PyObject * value )
379 {
380         char *name = NULL;
381         
382         name = PyString_AsString ( value );
383         if( !name )
384                 return EXPP_ReturnIntError( PyExc_TypeError,
385                                               "expected string argument" );
386
387         strncpy(self->seq->name+2, name, 21);
388         return 0;
389 }
390
391
392 static PyObject *Sequence_getSound( BPy_Sequence * self )
393 {
394         if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound)
395                 return Sound_CreatePyObject(self->seq->sound);
396         Py_RETURN_NONE;
397 }
398
399 static PyObject *Sequence_getIpo( BPy_Sequence * self )
400 {
401         struct Ipo *ipo;
402         
403         ipo = self->seq->ipo;
404
405         if( ipo )
406                 return Ipo_CreatePyObject( ipo );
407         Py_RETURN_NONE;
408 }
409
410
411 static PyObject *SceneSeq_getActive( BPy_SceneSeq * self )
412 {
413         Sequence *last_seq = NULL, *seq;
414         Editing *ed = self->scene->ed;
415
416         if (!ed)
417                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
418                                               "scene has no sequence data to edit" );
419         
420         seq = ed->seqbasep->first;
421         
422         while (seq) {
423                 if (seq->flag & SELECT)
424                         last_seq = seq;
425                 
426                 seq = seq->next;
427         }
428         if (last_seq)
429                 return Sequence_CreatePyObject(last_seq, NULL, self->scene );
430         
431         Py_RETURN_NONE;
432 }
433
434 static PyObject *SceneSeq_getMetaStrip( BPy_SceneSeq * self )
435 {
436         Sequence *seq = NULL;
437         Editing *ed = self->scene->ed;
438         MetaStack *ms;
439         if (!ed)
440                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
441                                               "scene has no sequence data to edit" );
442         
443         ms = ed->metastack.last;
444         if (!ms)
445                 Py_RETURN_NONE;
446         
447         seq = ms->parseq;
448         return Sequence_CreatePyObject(seq, NULL, self->scene);
449 }
450
451
452 /*
453  * this should accept a Py_None argument and just delete the Ipo link
454  * (as Object_clearIpo() does)
455  */
456
457 static int Sequence_setIpo( BPy_Sequence * self, PyObject * value )
458 {
459         Ipo *ipo = NULL;
460         Ipo *oldipo;
461         ID *id;
462         
463         oldipo = self->seq->ipo;
464         
465         /* if parameter is not None, check for valid Ipo */
466
467         if ( value != Py_None ) {
468                 if ( !BPy_Ipo_Check( value ) )
469                         return EXPP_ReturnIntError( PyExc_TypeError,
470                                         "expected an Ipo object" );
471
472                 ipo = Ipo_FromPyObject( value );
473
474                 if( !ipo )
475                         return EXPP_ReturnIntError( PyExc_RuntimeError,
476                                         "null ipo!" );
477
478                 if( ipo->blocktype != ID_SEQ )
479                         return EXPP_ReturnIntError( PyExc_TypeError,
480                                         "Ipo is not a sequence data Ipo" );
481         }
482
483         /* if already linked to Ipo, delete link */
484
485         if ( oldipo ) {
486                 id = &oldipo->id;
487                 if( id->us > 0 )
488                         id->us--;
489         }
490
491         /* assign new Ipo and increment user count, or set to NULL if deleting */
492
493         self->seq->ipo = ipo;
494         if ( ipo )
495                 id_us_plus(&ipo->id);
496
497         return 0;
498 }
499
500 static PyObject *Sequence_getScene( BPy_Sequence * self )
501 {
502         struct Scene *scene;
503         
504         scene = self->seq->scene;
505
506         if( scene )
507                 return Scene_CreatePyObject( scene );
508         Py_RETURN_NONE;
509 }
510
511
512 static PyObject *Sequence_getImages( BPy_Sequence * self )
513 {
514         Strip *strip;
515         StripElem *se;
516         int i;
517         PyObject *list, *ret;
518         
519         if (self->seq->type != SEQ_IMAGE) {
520                 list = PyList_New(0);
521                 ret= Py_BuildValue( "sO", "", list);
522                 Py_DECREF(list);
523                 return ret;
524         }
525         
526                         /*return EXPP_ReturnPyObjError( PyExc_TypeError,
527                                         "Sequence is not an image type" );*/
528         
529         
530         strip = self->seq->strip;
531         se = strip->stripdata;
532         list = PyList_New(strip->len);
533         
534         for (i=0; i<strip->len; i++, se++) {
535                 PyList_SetItem( list, i, PyString_FromString(se->name) );
536         }
537         
538         ret= Py_BuildValue( "sO", strip->dir, list);
539         Py_DECREF(list);
540         return ret;
541 }
542
543
544
545 /*
546  * get floating point attributes
547  */
548 static PyObject *getIntAttr( BPy_Sequence *self, void *type )
549 {
550         int param;
551         struct Sequence *seq= self->seq;
552         
553         /*printf("%i %i %i %i %i %i %i %i %i\n", seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->startdisp, seq->enddisp, seq->depth );*/
554         switch( (int)type ) {
555         case EXPP_SEQ_ATTR_TYPE: 
556                 param = seq->type;
557                 break;
558         case EXPP_SEQ_ATTR_CHAN:
559                 param = seq->machine;
560                 break;
561         case EXPP_SEQ_ATTR_LENGTH:
562                 param = seq->len;
563                 break;
564         case EXPP_SEQ_ATTR_START:
565                 param = seq->start;
566                 break;
567         case EXPP_SEQ_ATTR_STARTOFS:
568                 param = seq->startofs;
569                 break;
570         case EXPP_SEQ_ATTR_ENDOFS:
571                 param = seq->endofs;
572                 break;
573         case EXPP_SEQ_ATTR_STARTSTILL:
574                 param = seq->startstill;
575                 break;
576         case EXPP_SEQ_ATTR_ENDSTILL:
577                 param = seq->endstill;
578                 break;
579         default:
580                 return EXPP_ReturnPyObjError( PyExc_RuntimeError, 
581                                 "undefined type in getFloatAttr" );
582         }
583
584         return PyInt_FromLong( param );
585 }
586
587 /* internal functions for recursivly updating metastrip locatons */
588 static void intern_pos_update(Sequence * seq) {
589         /* update startdisp and enddisp */
590         calc_sequence_disp(seq);
591 }
592
593 void intern_recursive_pos_update(Sequence * seq, int offset) {
594         Sequence *iterseq;
595         intern_pos_update(seq);
596         if (seq->type != SEQ_META) return;
597         
598         for (iterseq = seq->seqbase.first; iterseq; iterseq= iterseq->next) {
599                 iterseq->start -= offset;
600                 intern_recursive_pos_update(iterseq, offset);
601         }
602 }
603
604
605 static int setIntAttrClamp( BPy_Sequence *self, PyObject *value, void *type )
606 {
607         struct Sequence *seq= self->seq;
608         int number, origval=0;
609
610         if( !PyInt_Check( value ) )
611                 return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
612         
613         number = PyInt_AS_LONG( value );
614                 
615         switch( (int)type ) {
616         case EXPP_SEQ_ATTR_CHAN:
617                 CLAMP(number, 1, 1024);
618                 seq->machine = number;
619                 break;
620         case EXPP_SEQ_ATTR_START:
621                 if (self->seq->type == SEQ_EFFECT)
622                         return EXPP_ReturnIntError( PyExc_RuntimeError,
623                                 "cannot set the location of an effect directly" );
624                 CLAMP(number, -MAXFRAME, MAXFRAME);
625                 origval = seq->start;
626                 seq->start = number;
627                 break;
628         
629         case EXPP_SEQ_ATTR_STARTOFS:
630                 if (self->seq->type == SEQ_EFFECT)
631                         return EXPP_ReturnIntError( PyExc_RuntimeError,
632                                 "This property dosnt apply to an effect" );
633                 CLAMP(number, 0, seq->len - seq->endofs);
634                 seq->startofs = number;
635                 break;
636         case EXPP_SEQ_ATTR_ENDOFS:
637                 if (self->seq->type == SEQ_EFFECT)
638                         return EXPP_ReturnIntError( PyExc_RuntimeError,
639                                 "This property dosnt apply to an effect" );
640                 CLAMP(number, 0, seq->len - seq->startofs);
641                 seq->endofs = number;
642                 break;
643         case EXPP_SEQ_ATTR_STARTSTILL:
644                 if (self->seq->type == SEQ_EFFECT)
645                         return EXPP_ReturnIntError( PyExc_RuntimeError,
646                                 "This property dosnt apply to an effect" );
647                 CLAMP(number, 1, MAXFRAME);
648                 seq->startstill = number;
649                 break;
650         case EXPP_SEQ_ATTR_ENDSTILL:
651                 if (self->seq->type == SEQ_EFFECT)
652                         return EXPP_ReturnIntError( PyExc_RuntimeError,
653                                 "This property dosnt apply to an effect" );
654                 CLAMP(number, seq->startstill+1, MAXFRAME);
655                 seq->endstill = number;
656                 break;
657         case EXPP_SEQ_ATTR_LENGTH:
658                 if (self->seq->type == SEQ_EFFECT)
659                         return EXPP_ReturnIntError( PyExc_RuntimeError,
660                                 "cannot set the length of an effect directly" );
661                 CLAMP(number, 1, MAXFRAME);
662                 origval = seq->len;
663                 seq->start = number;
664                 break;
665         default:
666                 return EXPP_ReturnIntError( PyExc_RuntimeError,
667                                 "undefined type in setFloatAttrClamp" );
668         }
669         
670         intern_pos_update(seq);
671         
672         if ((int)type == EXPP_SEQ_ATTR_START && number != origval )
673                 intern_recursive_pos_update(seq, origval - seq->start);
674         
675         return 0;
676 }
677
678
679 static PyObject *getFlagAttr( BPy_Sequence *self, void *type )
680 {
681         if (self->seq->flag & (int)type)
682                 Py_RETURN_TRUE;
683         else
684                 Py_RETURN_FALSE;
685 }
686
687
688 /*
689  * set floating point attributes which require clamping
690  */
691
692 static int setFlagAttr( BPy_Sequence *self, PyObject *value, void *type )
693 {
694         int t = (int)type;
695         int param = PyObject_IsTrue( value );
696         
697         if( param == -1 )
698                 return EXPP_ReturnIntError( PyExc_TypeError,
699                                 "expected True/False or 0/1" );
700         
701         if (param)
702                 self->seq->flag |= t;
703         else {
704                 /* dont allow leftsel and rightsel when its not selected */
705                 if (t == SELECT)
706                         t = t + SEQ_LEFTSEL + SEQ_RIGHTSEL;
707                 
708                 self->seq->flag &= ~t;
709         }
710         return 0;
711 }
712
713
714 /*****************************************************************************/
715 /* Python attributes get/set structure:                                      */
716 /*****************************************************************************/
717 static PyGetSetDef BPy_Sequence_getseters[] = {
718         {"name",
719          (getter)Sequence_getName, (setter)Sequence_setName,
720          "Sequence name",
721           NULL},
722         {"ipo",
723          (getter)Sequence_getIpo, (setter)Sequence_setIpo,
724          "Sequence ipo",
725           NULL},
726
727         {"scene",
728          (getter)Sequence_getScene, (setter)NULL,
729          "Sequence scene",
730           NULL},
731         {"sound",
732          (getter)Sequence_getSound, (setter)NULL,
733          "Sequence name",
734           NULL},
735         {"images",
736          (getter)Sequence_getImages, (setter)NULL,
737          "Sequence scene",
738           NULL},
739           
740         {"type",
741          (getter)getIntAttr, (setter)NULL,
742          "",
743          (void *) EXPP_SEQ_ATTR_TYPE},
744         {"channel",
745          (getter)getIntAttr, (setter)setIntAttrClamp,
746          "",
747          (void *) EXPP_SEQ_ATTR_CHAN},
748          
749         {"length",
750          (getter)getIntAttr, (setter)setIntAttrClamp,
751          "",
752          (void *) EXPP_SEQ_ATTR_LENGTH},
753         {"start",
754          (getter)getIntAttr, (setter)setIntAttrClamp,
755          "",
756          (void *) EXPP_SEQ_ATTR_START},
757         {"startOffset",
758          (getter)getIntAttr, (setter)setIntAttrClamp,
759          "",
760          (void *) EXPP_SEQ_ATTR_STARTOFS},
761         {"endOffset",
762          (getter)getIntAttr, (setter)setIntAttrClamp,
763          "",
764          (void *) EXPP_SEQ_ATTR_ENDOFS},
765         {"startStill",
766          (getter)getIntAttr, (setter)setIntAttrClamp,
767          "",
768          (void *) EXPP_SEQ_ATTR_STARTSTILL},
769         {"endStill",
770          (getter)getIntAttr, (setter)setIntAttrClamp,
771          "",
772          (void *) EXPP_SEQ_ATTR_ENDSTILL},
773          
774         {"sel",
775          (getter)getFlagAttr, (setter)setFlagAttr,
776          "Sequence audio mute option",
777          (void *)SELECT},
778         {"selLeft",
779          (getter)getFlagAttr, (setter)setFlagAttr,
780          "",
781          (void *)SEQ_LEFTSEL},
782         {"selRight",
783          (getter)getFlagAttr, (setter)setFlagAttr,
784          "",
785          (void *)SEQ_RIGHTSEL},
786         {"filtery",
787          (getter)getFlagAttr, (setter)setFlagAttr,
788          "",
789          (void *)SEQ_FILTERY},
790         {"mute",
791          (getter)getFlagAttr, (setter)setFlagAttr,
792          "",
793          (void *)SEQ_MUTE},
794         {"premul",
795          (getter)getFlagAttr, (setter)setFlagAttr,
796          "",
797          (void *)SEQ_MAKE_PREMUL},
798         {"reversed",
799          (getter)getFlagAttr, (setter)setFlagAttr,
800          "",
801          (void *)SEQ_REVERSE_FRAMES},
802         {"ipoLocked",
803          (getter)getFlagAttr, (setter)setFlagAttr,
804          "",
805          (void *)SEQ_IPO_FRAME_LOCKED},
806         {"ipoLocked",
807          (getter)getFlagAttr, (setter)setFlagAttr,
808          "",
809          (void *)SEQ_IPO_FRAME_LOCKED},
810          
811         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
812 };
813
814 /*****************************************************************************/
815 /* Python attributes get/set structure:                                      */
816 /*****************************************************************************/
817 static PyGetSetDef BPy_SceneSeq_getseters[] = {
818         {"active",
819          (getter)SceneSeq_getActive, (setter)NULL,
820          "the active strip",
821           NULL},
822         {"metastrip",
823          (getter)SceneSeq_getMetaStrip, (setter)NULL,
824          "The currently active metastrip the user is editing",
825           NULL},
826         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
827 };
828
829 /*****************************************************************************/
830 /* Python TypeSequence structure definition:                                 */
831 /*****************************************************************************/
832 PyTypeObject Sequence_Type = {
833         PyObject_HEAD_INIT( NULL )  /* required py macro */
834         0,                          /* ob_size */
835         /*  For printing, in format "<module>.<name>" */
836         "Blender Sequence",             /* char *tp_name; */
837         sizeof( BPy_Sequence ),         /* int tp_basicsize; */
838         0,                          /* tp_itemsize;  For allocation */
839
840         /* Methods to implement standard operations */
841
842         NULL,/* destructor tp_dealloc; */
843         NULL,                       /* printfunc tp_print; */
844         NULL,                       /* getattrfunc tp_getattr; */
845         NULL,                       /* setattrfunc tp_setattr; */
846         ( cmpfunc ) Sequence_compare,   /* cmpfunc tp_compare; */
847         ( reprfunc ) Sequence_repr,     /* reprfunc tp_repr; */
848
849         /* Method suites for standard classes */
850
851         NULL,                       /* PyNumberMethods *tp_as_number; */
852         NULL,                       /* PySequenceMethods *tp_as_sequence; */
853         NULL,                       /* PyMappingMethods *tp_as_mapping; */
854
855         /* More standard operations (here for binary compatibility) */
856
857         NULL,                       /* hashfunc tp_hash; */
858         NULL,                       /* ternaryfunc tp_call; */
859         NULL,                       /* reprfunc tp_str; */
860         NULL,                       /* getattrofunc tp_getattro; */
861         NULL,                       /* setattrofunc tp_setattro; */
862
863         /* Functions to access object as input/output buffer */
864         NULL,                       /* PyBufferProcs *tp_as_buffer; */
865
866   /*** Flags to define presence of optional/expanded features ***/
867         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
868
869         NULL,                       /*  char *tp_doc;  Documentation string */
870   /*** Assigned meaning in release 2.0 ***/
871         /* call function for all accessible objects */
872         NULL,                       /* traverseproc tp_traverse; */
873
874         /* delete references to contained objects */
875         NULL,                       /* inquiry tp_clear; */
876
877   /***  Assigned meaning in release 2.1 ***/
878   /*** rich comparisons ***/
879         NULL,                       /* richcmpfunc tp_richcompare; */
880
881   /***  weak reference enabler ***/
882         0,                          /* long tp_weaklistoffset; */
883
884   /*** Added in release 2.2 ***/
885         /*   Iterators */
886         ( getiterfunc ) Sequence_getIter,           /* getiterfunc tp_iter; */
887         ( iternextfunc ) Sequence_nextIter,           /* iternextfunc tp_iternext; */
888
889   /*** Attribute descriptor and subclassing stuff ***/
890         BPy_Sequence_methods,           /* struct PyMethodDef *tp_methods; */
891         NULL,                       /* struct PyMemberDef *tp_members; */
892         BPy_Sequence_getseters,         /* struct PyGetSetDef *tp_getset; */
893         NULL,                       /* struct _typeobject *tp_base; */
894         NULL,                       /* PyObject *tp_dict; */
895         NULL,                       /* descrgetfunc tp_descr_get; */
896         NULL,                       /* descrsetfunc tp_descr_set; */
897         0,                          /* long tp_dictoffset; */
898         NULL,                       /* initproc tp_init; */
899         NULL,                       /* allocfunc tp_alloc; */
900         NULL,                       /* newfunc tp_new; */
901         /*  Low-level free-memory routine */
902         NULL,                       /* freefunc tp_free;  */
903         /* For PyObject_IS_GC */
904         NULL,                       /* inquiry tp_is_gc;  */
905         NULL,                       /* PyObject *tp_bases; */
906         /* method resolution order */
907         NULL,                       /* PyObject *tp_mro;  */
908         NULL,                       /* PyObject *tp_cache; */
909         NULL,                       /* PyObject *tp_subclasses; */
910         NULL,                       /* PyObject *tp_weaklist; */
911         NULL
912 };
913
914
915
916 /*****************************************************************************/
917 /* Python TypeSequence structure definition:                                 */
918 /*****************************************************************************/
919 PyTypeObject SceneSeq_Type = {
920         PyObject_HEAD_INIT( NULL )  /* required py macro */
921         0,                          /* ob_size */
922         /*  For printing, in format "<module>.<name>" */
923         "Blender SceneSeq",             /* char *tp_name; */
924         sizeof( BPy_Sequence ),         /* int tp_basicsize; */
925         0,                          /* tp_itemsize;  For allocation */
926
927         /* Methods to implement standard operations */
928
929         NULL,/* destructor tp_dealloc; */
930         NULL,                       /* printfunc tp_print; */
931         NULL,                       /* getattrfunc tp_getattr; */
932         NULL,                       /* setattrfunc tp_setattr; */
933         ( cmpfunc ) SceneSeq_compare,   /* cmpfunc tp_compare; */
934         ( reprfunc ) SceneSeq_repr,     /* reprfunc tp_repr; */
935
936         /* Method suites for standard classes */
937
938         NULL,                       /* PyNumberMethods *tp_as_number; */
939         NULL,                       /* PySequenceMethods *tp_as_sequence; */
940         NULL,                       /* PyMappingMethods *tp_as_mapping; */
941
942         /* More standard operations (here for binary compatibility) */
943
944         NULL,                       /* hashfunc tp_hash; */
945         NULL,                       /* ternaryfunc tp_call; */
946         NULL,                       /* reprfunc tp_str; */
947         NULL,                       /* getattrofunc tp_getattro; */
948         NULL,                       /* setattrofunc tp_setattro; */
949
950         /* Functions to access object as input/output buffer */
951         NULL,                       /* PyBufferProcs *tp_as_buffer; */
952
953   /*** Flags to define presence of optional/expanded features ***/
954         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
955
956         NULL,                       /*  char *tp_doc;  Documentation string */
957   /*** Assigned meaning in release 2.0 ***/
958         /* call function for all accessible objects */
959         NULL,                       /* traverseproc tp_traverse; */
960
961         /* delete references to contained objects */
962         NULL,                       /* inquiry tp_clear; */
963
964   /***  Assigned meaning in release 2.1 ***/
965   /*** rich comparisons ***/
966         NULL,                       /* richcmpfunc tp_richcompare; */
967
968   /***  weak reference enabler ***/
969         0,                          /* long tp_weaklistoffset; */
970
971   /*** Added in release 2.2 ***/
972         /*   Iterators */
973         ( getiterfunc ) SceneSeq_getIter,           /* getiterfunc tp_iter; */
974         ( iternextfunc ) SceneSeq_nextIter,           /* iternextfunc tp_iternext; */
975
976   /*** Attribute descriptor and subclassing stuff ***/
977         BPy_SceneSeq_methods,           /* struct PyMethodDef *tp_methods; */
978         NULL,                       /* struct PyMemberDef *tp_members; */
979         BPy_SceneSeq_getseters,         /* struct PyGetSetDef *tp_getset; */
980         NULL,                       /* struct _typeobject *tp_base; */
981         NULL,                       /* PyObject *tp_dict; */
982         NULL,                       /* descrgetfunc tp_descr_get; */
983         NULL,                       /* descrsetfunc tp_descr_set; */
984         0,                          /* long tp_dictoffset; */
985         NULL,                       /* initproc tp_init; */
986         NULL,                       /* allocfunc tp_alloc; */
987         NULL,                       /* newfunc tp_new; */
988         /*  Low-level free-memory routine */
989         NULL,                       /* freefunc tp_free;  */
990         /* For PyObject_IS_GC */
991         NULL,                       /* inquiry tp_is_gc;  */
992         NULL,                       /* PyObject *tp_bases; */
993         /* method resolution order */
994         NULL,                       /* PyObject *tp_mro;  */
995         NULL,                       /* PyObject *tp_cache; */
996         NULL,                       /* PyObject *tp_subclasses; */
997         NULL,                       /* PyObject *tp_weaklist; */
998         NULL
999 };
1000
1001
1002 /*****************************************************************************/
1003 /* Function:      M_Sequence_Get                                                */
1004 /* Python equivalent:     Blender.Sequence.Get                          */
1005 /*****************************************************************************/
1006 /*
1007 PyObject *M_Sequence_Get( PyObject * self, PyObject * args )
1008 {
1009         return SceneSeq_CreatePyObject( G.scene, NULL );
1010 }
1011 */
1012
1013 /*****************************************************************************/
1014 /* Function:     initObject                                             */
1015 /*****************************************************************************/
1016 PyObject *Sequence_Init( void )
1017 {
1018         PyObject *submodule;
1019         if( PyType_Ready( &Sequence_Type ) < 0 )
1020                 return NULL;
1021         if( PyType_Ready( &SceneSeq_Type ) < 0 )
1022                 return NULL;
1023         
1024         /* NULL was M_Sequence_methods*/
1025         submodule = Py_InitModule3( "Blender.Scene.Sequence", NULL,
1026 "The Blender Sequence module\n\n\
1027 This module provides access to **Sequence Data** in Blender.\n" );
1028
1029         /*Add SUBMODULES to the module*/
1030         /*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
1031         return submodule;
1032 }
1033
1034
1035 /*****************************************************************************/
1036 /* Function:    Sequence_CreatePyObject                                  */
1037 /* Description: This function will create a new BlenObject from an existing  */
1038 /*              Object structure.                                        */
1039 /*****************************************************************************/
1040 PyObject *Sequence_CreatePyObject( struct Sequence * seq, struct Sequence * iter, struct Scene *sce)
1041 {
1042         BPy_Sequence *pyseq;
1043
1044         if( !seq )
1045                 Py_RETURN_NONE;
1046
1047         pyseq =
1048                 ( BPy_Sequence * ) PyObject_NEW( BPy_Sequence, &Sequence_Type );
1049
1050         if( pyseq == NULL ) {
1051                 return ( NULL );
1052         }
1053         pyseq->seq = seq;
1054         pyseq->iter = iter;
1055         pyseq->scene = sce;
1056         
1057         return ( ( PyObject * ) pyseq );
1058 }
1059
1060 /*****************************************************************************/
1061 /* Function:    SceneSeq_CreatePyObject                                  */
1062 /* Description: This function will create a new BlenObject from an existing  */
1063 /*              Object structure.                                        */
1064 /*****************************************************************************/
1065 PyObject *SceneSeq_CreatePyObject( struct Scene * scn, struct Sequence * iter)
1066 {
1067         BPy_SceneSeq *pysceseq;
1068
1069         if( !scn )
1070                 Py_RETURN_NONE;
1071
1072         pysceseq =
1073                 ( BPy_SceneSeq * ) PyObject_NEW( BPy_SceneSeq, &SceneSeq_Type );
1074
1075         if( pysceseq == NULL ) {
1076                 return ( NULL );
1077         }
1078         pysceseq->scene = scn;
1079         pysceseq->iter = iter;
1080         
1081         return ( ( PyObject * ) pysceseq );
1082 }
1083
1084 /*****************************************************************************/
1085 /* Function:    Sequence_FromPyObject                                    */
1086 /* Description: This function returns the Blender sequence from the given        */
1087 /*              PyObject.                                                */
1088 /*****************************************************************************/
1089 struct Sequence *Sequence_FromPyObject( PyObject * py_seq )
1090 {
1091         BPy_Sequence *blen_seq;
1092
1093         blen_seq = ( BPy_Sequence * ) py_seq;
1094         return ( blen_seq->seq );
1095 }
1096
1097 /*****************************************************************************/
1098 /* Function:    Sequence_compare                                                 */
1099 /* Description: This is a callback function for the BPy_Sequence type. It        */
1100 /*              compares two Sequence_Type objects. Only the "==" and "!="  */
1101 /*              comparisons are meaninful. Returns 0 for equality and -1 if  */
1102 /*              they don't point to the same Blender Object struct.      */
1103 /*              In Python it becomes 1 if they are equal, 0 otherwise.   */
1104 /*****************************************************************************/
1105 static int Sequence_compare( BPy_Sequence * a, BPy_Sequence * b )
1106 {
1107         Sequence *pa = a->seq, *pb = b->seq;
1108         return ( pa == pb ) ? 0 : -1;
1109 }
1110
1111 static int SceneSeq_compare( BPy_SceneSeq * a, BPy_SceneSeq * b )
1112 {
1113         
1114         Scene *pa = a->scene, *pb = b->scene;
1115         return ( pa == pb ) ? 0 : -1;
1116 }
1117
1118 /*****************************************************************************/
1119 /* Function:    Sequence_repr / SceneSeq_repr                                            */
1120 /* Description: This is a callback function for the BPy_Sequence type. It        */
1121 /*              builds a meaninful string to represent object objects.   */
1122 /*****************************************************************************/
1123 static PyObject *Sequence_repr( BPy_Sequence * self )
1124 {
1125         return PyString_FromFormat( "[Sequence Strip \"%s\"]",
1126                                         self->seq->name + 2 );
1127 }
1128 static PyObject *SceneSeq_repr( BPy_SceneSeq * self )
1129 {
1130         return PyString_FromFormat( "[Scene Sequence \"%s\"]",
1131                                 self->scene->id.name + 2 );
1132 }
1133