2 #Copyright 2009 - 2010 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/>
23 class Timeline(Frame):
25 This widget represents a sequence of video chunks.
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.
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
38 def __init__(self, master):
42 Frame.__init__(self, master = master)
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)
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.')
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.')
71 self.subgets['b_frameset'] = Button(self, text='Make Frameset', command=self.convert,
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.')
78 self.process_schedule()
80 def switch_animChunks(self):
81 for chunk in self.chunks:
82 chunk.animate = self.animChunks.get()
87 Displays a window with information about loaded video files.
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)
99 for vc in self.chunks:
101 text.insert(END, '###=- ' + vc.cget('text') + ':\n####\n')
102 pkeys = vc.videoprops.keys()
105 text.insert(END, pkey + ':\t')
106 text.insert(END, vc.videoprops[pkey] + '\n')
107 text.insert(END, '\n')
108 text.config(state = 'disabled')
112 Converts marked chunks to framesets (not yet implemented)
118 Internal button press execution code
120 for vc in self.chunks:
121 vc.subgets['c_play'].select()
125 Internal button press execution code
127 for vc in self.chunks:
128 vc.subgets['c_play'].toggle()
132 Internal button press execution code
134 for vc in self.chunks:
135 vc.subgets['c_mark'].select()
139 Internal button press execution code
141 for vc in self.chunks:
142 vc.subgets['c_mark'].toggle()
144 def process_schedule(self):
146 Process scheduled events on video chunks.
148 This function is internal. Its used to execute actions like
149 moving and copying of chunks
154 for vc in self.chunks:
156 params.extend(vc.slave_subcommand())
160 if vc.schedule == '':
162 elif vc.schedule == 'delete':
163 self.chunks.remove(vc)
166 elif vc.schedule == 'copy':
167 index = self.chunks.index(vc)
168 new = VChunk(self.subgets['chunklist'].interior(),
173 new.filters = list(vc.filters)
174 new.played.set(value = vc.played.get())
175 new.marked.set(value = vc.marked.get())
177 new.pack(before = vc, side=LEFT)
178 self.chunks.insert(index, new)
180 elif vc.schedule == 'mv left':
181 index = self.chunks.index(vc)
182 if vc != self.chunks[0]:
184 self.chunks.remove(vc)
185 self.chunks.insert(index - 1, vc)
186 vc.pack(before = self.chunks[index], side = LEFT)
188 elif vc.schedule == 'mv right':
189 index = self.chunks.index(vc)
190 if vc != self.chunks[-1]:
192 self.chunks.remove(vc)
193 self.chunks.insert(index + 1, vc)
194 vc.pack(after = self.chunks[index], side = LEFT)
197 if self.view != None:
198 self.view.set_playback_params(params)
199 for mod in self.mods:
200 mod.set_chunks(marked)
202 self.after(20, self.process_schedule)
204 def add(self, file, start = None, frames = None):
206 Append video chunk to the list
208 vc = VChunk(self.subgets['chunklist'].interior(),
212 play = self.animChunks.get()
215 self.chunks.append(vc)
217 def set_view(self, view):
220 def set_mods(self, mods):