]> git.plutz.net Git - viper/blob - timeline.py
moved from svn.imp.fu-berlin.de/viper rev33
[viper] / timeline.py
1 #encoding: utf-8
2 #Copyright 2009 - 2010 Paul Hänsch
3
4 #This file is part of Viper.
5
6 #Viper is free software: you can redistribute it and/or modify
7 #it under the terms of the GNU General Public License as published by
8 #the Free Software Foundation, either version 3 of the License, or
9 #(at your option) any later version.
10
11 #Viper 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 Viper.  If not, see <http://www.gnu.org/licenses/>
18
19 from Tkinter import *
20 from vchunk import *
21 import Pmw
22
23 class Timeline(Frame):
24     """
25     This widget represents a sequence of video chunks.
26
27     It holds a list of chunks and provides an interface to manipulate the order
28     of these chunks. The main control widgets are placed on the VChunk ojects.
29     Properties:
30     subgets       - a dictionary of subordinated widgets 
31     chunks (list) - list of VChunk objects, do not edit this list manually
32                     use add() to add a >chunk< object, the vchunk will be
33                     built and displayed automatically
34     timer (Tk)    - internal timer for regular execution of tasks scheduled by
35                     vchunks
36     """
37
38     def __init__(self, master):
39         """
40         Constructor
41         """
42         Frame.__init__(self, master = master)
43         self.subgets = {}
44         self.chunks = []
45         self.mods = []    # list of chunk modifying objects (filter and effect dialogs)
46         self.view = None  # viewer widget
47         self.animChunks = BooleanVar(value = True)
48         tooltips = Pmw.Balloon(self)
49
50         self.subgets['chunklist'] = Pmw.ScrolledFrame(self, usehullsize = 1, 
51                                                       hull_height = 142, hull_width = 800)
52         self.subgets['chunklist'].pack(side=TOP, fill=X)
53         self.subgets['b_PlayAll'] = Button(self, text='Play All', command=self.playall)
54         self.subgets['b_PlayAll'].pack(side=LEFT)
55         self.subgets['b_InvPlay'] = Button(self, text='Invert Play', command=self.invplay)
56         self.subgets['b_InvPlay'].pack(side=LEFT)
57         tooltips.bind(self.subgets['b_PlayAll'],
58                            'Mark all video snippets for playback.')
59         self.subgets['b_MarkAll'] = Button(self, text='Mark All', command=self.markall)
60         self.subgets['b_MarkAll'].pack(side=LEFT)
61         self.subgets['b_InvMark'] = Button(self, text='Invert Mark', command=self.invmark)
62         self.subgets['b_InvMark'].pack(side=LEFT)
63         tooltips.bind(self.subgets['b_MarkAll'],
64                            'Mark all video snippets for filter and effect application.')
65
66         self.subgets['b_info'] = Button(self, text='Video Info', command=self.info)
67         self.subgets['b_info'].pack(side=RIGHT)
68         tooltips.bind(self.subgets['b_info'],
69                            'Show detailed information about the marked video chunks.')
70
71         self.subgets['b_frameset'] = Button(self, text='Make Frameset', command=self.convert,
72                                             state = 'disabled')
73         self.subgets['b_frameset'].pack(side=RIGHT)
74         tooltips.bind(self.subgets['b_frameset'],
75                            'Convert marked video chunks into framesets.\n' +
76                            'This enables you to perform advanced video operations.')
77
78         self.process_schedule()
79
80     def switch_animChunks(self):
81         for chunk in self.chunks:
82             chunk.animate = self.animChunks.get()
83             chunk.chprops()
84
85     def info(self):
86         """
87         Displays a window with information about loaded video files.
88         """
89         win = Tk()
90         frm = LabelFrame(win, text = 'Info')
91         frm.pack(side = TOP, expand = True, fill = BOTH)
92         text = Text(frm, width = 40, height = 10)
93         text.pack(side = LEFT, fill = BOTH, expand = True)
94         scroll = Scrollbar(frm, orient = VERTICAL, command = text.yview)
95         scroll.pack(side = RIGHT, fill = Y, anchor = W)
96         text.config(yscrollcommand = scroll.set)
97         Button(win, command = win.destroy, text = 'OK').pack(side = RIGHT, anchor = N)
98
99         for vc in self.chunks:
100             if vc.marked.get():
101                 text.insert(END, '###=- ' + vc.cget('text') + ':\n####\n')
102                 pkeys = vc.videoprops.keys()
103                 pkeys.sort()
104                 for pkey in pkeys:
105                     text.insert(END, pkey + ':\t')
106                     text.insert(END, vc.videoprops[pkey] + '\n')
107                 text.insert(END, '\n')
108         text.config(state = 'disabled')
109
110     def convert(self):
111         """
112         Converts marked chunks to framesets (not yet implemented)
113         """
114         pass
115
116     def playall(self):
117         """
118         Internal button press execution code
119         """
120         for vc in self.chunks:
121             vc.subgets['c_play'].select()
122
123     def invplay(self):
124         """
125         Internal button press execution code
126         """
127         for vc in self.chunks:
128             vc.subgets['c_play'].toggle()
129
130     def markall(self):
131         """
132         Internal button press execution code
133         """
134         for vc in self.chunks:
135             vc.subgets['c_mark'].select()
136
137     def invmark(self):
138         """
139         Internal button press execution code
140         """
141         for vc in self.chunks:
142             vc.subgets['c_mark'].toggle()
143
144     def process_schedule(self):
145         """
146         Process scheduled events on video chunks.
147
148         This function is internal. Its used to execute actions like 
149         moving and copying of chunks
150         """
151         params = []
152         marked = []
153
154         for vc in self.chunks:
155             if vc.played.get():
156                 params.extend(vc.slave_subcommand())
157             if vc.marked.get():
158                 marked.append(vc)
159
160             if vc.schedule == '':
161                 pass
162             elif vc.schedule == 'delete':
163                 self.chunks.remove(vc)
164                 vc.stop()
165                 vc.destroy()
166             elif vc.schedule == 'copy':
167                 index = self.chunks.index(vc)
168                 new = VChunk(self.subgets['chunklist'].interior(),
169                              file = vc.videofile,
170                              start = vc.start,
171                              frames = vc.frames
172                              )
173                 new.filters = list(vc.filters)
174                 new.played.set(value = vc.played.get())
175                 new.marked.set(value = vc.marked.get())
176                 new.play()
177                 new.pack(before = vc, side=LEFT)
178                 self.chunks.insert(index, new)
179                 vc.schedule = ''
180             elif vc.schedule == 'mv left':
181                 index = self.chunks.index(vc)
182                 if vc != self.chunks[0]:
183                     vc.pack_forget()
184                     self.chunks.remove(vc)
185                     self.chunks.insert(index - 1, vc)
186                     vc.pack(before = self.chunks[index], side = LEFT)
187                 vc.schedule = ''
188             elif vc.schedule == 'mv right':
189                 index = self.chunks.index(vc)
190                 if vc != self.chunks[-1]:
191                     vc.pack_forget()
192                     self.chunks.remove(vc)
193                     self.chunks.insert(index + 1, vc)
194                     vc.pack(after = self.chunks[index], side = LEFT)
195                 vc.schedule = ''
196
197         if self.view != None:
198             self.view.set_playback_params(params)
199         for mod in self.mods:
200             mod.set_chunks(marked)
201
202         self.after(20, self.process_schedule)
203
204     def add(self, file, start = None, frames = None):
205         """
206         Append video chunk to the list
207         """
208         vc = VChunk(self.subgets['chunklist'].interior(),
209                     file = file,
210                     start = start,
211                     frames = frames,
212                     play = self.animChunks.get()
213                     )
214         vc.pack(side = LEFT)
215         self.chunks.append(vc)
216
217     def set_view(self, view):
218         self.view = view
219
220     def set_mods(self, mods):
221         self.mods = mods