2 #Copyright 2009 - 2011 Paul Hänsch
4 # This file is part of Viper.
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.
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.
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/>
21 from vframeset import *
24 class Timeline(Frame):
26 This widget represents a sequence of video chunks.
28 It holds a list of chunks and provides an interface to manipulate the order
29 of these chunks. The main control widgets are placed on the VChunk ojects.
31 subgets - a dictionary of subordinated widgets
32 chunks (list) - list of VChunk objects, do not edit this list manually
33 use add() to add a >chunk< object, the vchunk will be
34 built and displayed automatically
35 timer (Tk) - internal timer for regular execution of tasks scheduled by
39 def __init__(self, master):
43 Frame.__init__(self, master = master)
46 self.mods = [] # list of chunk modifying objects (filter and effect dialogs)
47 self.view = None # viewer widget
48 self.basedir = None #path of project directory, required for framesets
49 self.animChunks = BooleanVar(value = True)
50 tooltips = Pmw.Balloon(self)
52 self.subgets['chunklist'] = Pmw.ScrolledFrame(self, usehullsize = 1,
53 hull_height = 142, hull_width = 800)
54 self.subgets['chunklist'].pack(side=TOP, fill=X)
55 self.subgets['b_PlayAll'] = Button(self, text='Play All', command=self.playall)
56 self.subgets['b_PlayAll'].pack(side=LEFT)
57 self.subgets['b_InvPlay'] = Button(self, text='Invert Play', command=self.invplay)
58 self.subgets['b_InvPlay'].pack(side=LEFT)
59 tooltips.bind(self.subgets['b_PlayAll'],
60 'Mark all video snippets for playback.')
61 self.subgets['b_MarkAll'] = Button(self, text='Mark All', command=self.markall)
62 self.subgets['b_MarkAll'].pack(side=LEFT)
63 self.subgets['b_InvMark'] = Button(self, text='Invert Mark', command=self.invmark)
64 self.subgets['b_InvMark'].pack(side=LEFT)
65 tooltips.bind(self.subgets['b_MarkAll'],
66 'Mark all video snippets for filter and effect application.')
68 self.subgets['b_info'] = Button(self, text='Video Info', command=self.info)
69 self.subgets['b_info'].pack(side=RIGHT)
70 tooltips.bind(self.subgets['b_info'],
71 'Show detailed information about the marked video chunks.')
73 self.subgets['b_frameset'] = Button(self, text='Make Frameset', command=self.convert,
75 self.subgets['b_frameset'].pack(side=RIGHT)
76 tooltips.bind(self.subgets['b_frameset'],
77 'Convert marked video chunks into framesets.\n' +
78 'This enables you to perform advanced video operations.')
80 self.process_schedule()
82 def switch_animChunks(self):
83 for chunk in self.chunks:
84 chunk.animate = self.animChunks.get()
89 Displays a window with information about loaded video files.
92 frm = LabelFrame(win, text = 'Info')
93 frm.pack(side = TOP, expand = True, fill = BOTH)
94 text = Text(frm, width = 40, height = 10)
95 text.pack(side = LEFT, fill = BOTH, expand = True)
96 scroll = Scrollbar(frm, orient = VERTICAL, command = text.yview)
97 scroll.pack(side = RIGHT, fill = Y, anchor = W)
98 text.config(yscrollcommand = scroll.set)
99 Button(win, command = win.destroy, text = 'OK').pack(side = RIGHT, anchor = N)
101 for vc in self.chunks:
103 text.insert(END, '###=- ' + vc.cget('text') + ':\n####\n')
104 pkeys = vc.videoprops.keys()
107 text.insert(END, pkey + ':\t')
108 text.insert(END, vc.videoprops[pkey] + '\n')
109 text.insert(END, '\n')
110 text.config(state = 'disabled')
114 Converts marked chunks to framesets
116 for vc in self.chunks:
118 index = self.chunks.index(vc)
119 new = VFrameset(self.subgets['chunklist'].interior(),
122 new.played.set(value = vc.played.get())
123 new.marked.set(value = vc.marked.get())
124 if self.animChunks.get(): new.play()
125 new.pack(before = vc, side=LEFT)
126 self.chunks.insert(index, new)
127 self.chunks.remove(vc)
133 Internal button press execution code
135 for vc in self.chunks:
136 vc.subgets['c_play'].select()
140 Internal button press execution code
142 for vc in self.chunks:
143 vc.subgets['c_play'].toggle()
147 Internal button press execution code
149 for vc in self.chunks:
150 vc.subgets['c_mark'].select()
154 Internal button press execution code
156 for vc in self.chunks:
157 vc.subgets['c_mark'].toggle()
159 def process_schedule(self):
161 Process scheduled events on video chunks.
163 This function is internal. Its used to execute actions like
164 moving and copying of chunks
169 for vc in self.chunks:
171 params.extend(vc.slave_subcommand())
175 if vc.schedule == '':
177 elif vc.schedule == 'delete':
178 self.chunks.remove(vc)
181 elif vc.schedule == 'copy':
182 index = self.chunks.index(vc)
183 new = VChunk(self.subgets['chunklist'].interior(),
188 new.filters = list(vc.filters)
189 new.played.set(value = vc.played.get())
190 new.marked.set(value = vc.marked.get())
191 if self.animChunks.get(): new.play()
193 new.pack(before = vc, side=LEFT)
194 self.chunks.insert(index, new)
196 elif vc.schedule == 'mv left':
197 index = self.chunks.index(vc)
198 if vc != self.chunks[0]:
200 self.chunks.remove(vc)
201 self.chunks.insert(index - 1, vc)
202 vc.pack(before = self.chunks[index], side = LEFT)
204 elif vc.schedule == 'mv right':
205 index = self.chunks.index(vc)
206 if vc != self.chunks[-1]:
208 self.chunks.remove(vc)
209 self.chunks.insert(index + 1, vc)
210 vc.pack(after = self.chunks[index], side = LEFT)
213 if self.view != None:
214 self.view.set_playback_params(params)
215 for mod in self.mods:
216 mod.set_chunks(marked)
218 self.after(20, self.process_schedule)
220 def add(self, file, start = None, frames = None):
222 Append video chunk to the list
224 vc = VChunk(self.subgets['chunklist'].interior(),
228 play = self.animChunks.get()
231 self.chunks.append(vc)
233 def set_view(self, view):
236 def set_mods(self, mods):
239 def set_basedir(self, basedir):
240 self.basedir = basedir
241 self.subgets['b_frameset'].config(state = 'normal')
243 def get_basedir(self):