[pitivi] Add the clip configuration pane
- From: Edward Hervey <edwardrv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] Add the clip configuration pane
- Date: Wed, 22 Sep 2010 13:37:28 +0000 (UTC)
commit d4db6686bedeca5b14051490894550d5f390f369
Author: Thibault Saunier <tsaunier gnome org>
Date: Tue Jun 29 23:33:36 2010 -0400
Add the clip configuration pane
pitivi/timeline/timeline.py | 11 +
pitivi/ui/{projecttabs.py => basetabs.py} | 6 +-
pitivi/ui/clipproperties.py | 284 +++++++++++++++++++++++++++++
pitivi/ui/mainwindow.py | 32 +++-
4 files changed, 323 insertions(+), 10 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 89e096f..e5d95a8 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -531,6 +531,17 @@ class Selection(Signallable):
return set(objects)
+ def getSelectedTrackEffects(self):
+ """
+ Returns the list of L{TrackObject} contained in this selection.
+ """
+ track_effects = []
+ for timeline_object in self.selected:
+ for track in timeline_object.track_objects:
+ if isinstance(track, TrackEffect):
+ track_effects.append(track)
+
+ return set(track_effects)
def __len__(self):
return len(self.selected)
diff --git a/pitivi/ui/projecttabs.py b/pitivi/ui/basetabs.py
similarity index 95%
rename from pitivi/ui/projecttabs.py
rename to pitivi/ui/basetabs.py
index 8113656..ffa7430 100644
--- a/pitivi/ui/projecttabs.py
+++ b/pitivi/ui/basetabs.py
@@ -1,6 +1,6 @@
# PiTiVi , Non-linear video editor
#
-# ui/projecttabs.py
+# ui/basetabs.py
#
# Copyright (c) 2005, Edward Hervey <bilboed bilboed com>
#
@@ -21,7 +21,7 @@
import gtk
-class ProjectTabs(gtk.Notebook):
+class BaseTabs(gtk.Notebook):
def __init__(self):
""" initialize """
gtk.Notebook.__init__(self)
@@ -42,7 +42,7 @@ class ProjectTabs(gtk.Notebook):
def _set_child_properties(self, child, label):
self.child_set_property(child, "detachable", True)
- self.child_set_property(child, "tab-expand", True)
+ self.child_set_property(child, "tab-expand", False)
self.child_set_property(child, "tab-fill", True)
label.props.xalign = 0.0
diff --git a/pitivi/ui/clipproperties.py b/pitivi/ui/clipproperties.py
new file mode 100644
index 0000000..fd7235b
--- /dev/null
+++ b/pitivi/ui/clipproperties.py
@@ -0,0 +1,284 @@
+#!/usr/bin/env python
+#
+# ui/clipproperties.py
+#
+# Copyright (C) 2010 Thibault Saunier <tsaunier gnome org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+
+import gtk
+import pango
+import dnd
+
+from gettext import gettext as _
+
+from pitivi.log.loggable import Loggable
+from pitivi.effects import AUDIO_EFFECT, VIDEO_EFFECT
+from pitivi.receiver import receiver, handler
+from pitivi.timeline.track import TrackEffect
+from pitivi.stream import AudioStream, VideoStream
+from pitivi.effects import getNiceEffectName, getNiceEffectDescription
+
+(COL_ACTIVATED,
+ COL_TYPE,
+ COL_NAME_TEXT,
+ COL_DESC_TEXT) = range(4)
+
+class ClipProperties(gtk.VBox, Loggable):
+ """
+ Widget for configuring clips properties
+ """
+
+ def __init__(self, instance, uiman):
+ gtk.VBox.__init__(self)
+ Loggable.__init__(self)
+
+ self.app = instance
+ self.settings = instance.settings
+ self.project = None
+
+ self.effectExpander = EffectProperties(instance)
+ self.pack_start(self.effectExpander, expand=True, fill=True)
+
+ self.effectExpander.show()
+
+ def _setProject(self):
+ if self.project:
+ self.effectExpander.connectTimelineSelection(self.project.timeline)
+
+ project = receiver(_setProject)
+
+class EffectProperties(gtk.Expander):
+ """
+ Widget for viewing and configuring effects
+ """
+
+ def __init__(self, instance):
+ gtk.Expander.__init__(self, "Effects")
+ self.set_expanded(True)
+
+ self.selected_effects = []
+ self.timeline_object = None
+ self.app = instance
+
+ self.VContent = gtk.VBox()
+ self.add(self.VContent)
+
+ self.table = gtk.Table(2, 1, False)
+ self.VContent.pack_start(self.table, expand=False, fill=True)
+
+ self.toolbar1 = gtk.Toolbar()
+ self.removeEffectBt = gtk.ToolButton("gtk-delete")
+ self.removeEffectBt.set_label("Remove effect")
+ self.removeEffectBt.set_use_underline(True)
+ self.removeEffectBt.set_is_important(True)
+ self.toolbar1.insert(self.removeEffectBt, 0)
+ self.table.attach(self.toolbar1, 0, 1, 0, 1)
+
+ #self.toolbar2 = gtk.Toolbar()
+ ##self.toolbar2.set_style(gtk.TOOLBAR_BOTH_HORIZ)
+ #self.removeKeyframeBt = gtk.ToolButton("gtk-remove")
+ #self.removeKeyframeBt.set_label("Remove keyframe")
+ #self.removeKeyframeBt.set_use_underline(True)
+ #self.removeKeyframeBt.set_is_important(True)
+ #self.toolbar2.insert(self.removeKeyframeBt, 0)
+ #self.table.attach(self.toolbar2, 1, 2, 0, 1)
+
+ self.storemodel = gtk.ListStore(bool, str, str, str)
+
+ #Treeview
+ self.treeview_scrollwin = gtk.ScrolledWindow()
+ self.treeview_scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ self.treeview_scrollwin.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+
+ # TreeView
+ # Displays name, description
+ self.treeview = gtk.TreeView(self.storemodel)
+ self.treeview_scrollwin.add(self.treeview)
+ self.treeview.set_property("rules_hint", True)
+ self.treeview.set_property("has_tooltip", True)
+ tsel = self.treeview.get_selection()
+ tsel.set_mode(gtk.SELECTION_SINGLE)
+
+ activatedcol = gtk.TreeViewColumn(_("Activated"))
+ activatedcol.set_sort_column_id(COL_TYPE)
+ self.treeview.append_column(activatedcol)
+ activatedcol.set_spacing(5)
+ activatedcol.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ activatedcol.set_min_width(15)
+ activatedcell = gtk.CellRendererToggle()
+ activatedcell.props.xpad = 6
+ activatedcol.pack_start(activatedcell)
+
+ activatedcell.connect("toggled", self.effectActiveToggleCb)
+
+ desccol = gtk.TreeViewColumn(_("Type"))
+ desccol.set_sort_column_id(COL_TYPE)
+ self.treeview.append_column(desccol)
+ desccol.set_spacing(5)
+ desccol.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+ desccol.set_min_width(50)
+ desccell = gtk.CellRendererText()
+ desccell.props.xpad = 6
+ desccell.set_property("ellipsize", pango.ELLIPSIZE_END)
+ desccol.pack_start(desccell)
+ desccol.add_attribute(desccell, "text", COL_TYPE)
+
+ namecol = gtk.TreeViewColumn(_("Effect name"))
+ namecol.set_sort_column_id(COL_NAME_TEXT)
+ self.treeview.append_column(namecol)
+ namecol.set_spacing(5)
+ #namecol.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+ #namecol.set_fixed_width(40)
+ namecell = gtk.CellRendererText()
+ namecell.props.xpad = 6
+ namecell.set_property("ellipsize", pango.ELLIPSIZE_END)
+ namecol.pack_start(namecell)
+ namecol.add_attribute(namecell, "text", COL_NAME_TEXT)
+
+ #Explain how to configure effects
+ self.explain_box = gtk.EventBox()
+ self.explain_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('white'))
+
+ self.explain_label = gtk.Label()
+ self.explain_label.set_padding(10, 10)
+ self.explain_label.set_line_wrap(True)
+ self.explain_label.set_line_wrap_mode(pango.WRAP_WORD)
+ self.explain_label.set_justify(gtk.JUSTIFY_CENTER)
+ self.explain_label.set_markup(
+ _("<span size='x-large'>You must select a clip on the timeline "
+ "to configure its associated effects</span>"))
+ self.explain_box.add(self.explain_label)
+
+ self.treeview.drag_dest_set(gtk.DEST_DEFAULT_MOTION,
+ [dnd.EFFECT_TUPLE],
+ gtk.gdk.ACTION_COPY)
+
+ self.treeview.connect("drag-data-received", self._dragDataReceivedCb)
+ self.treeview.connect("drag-leave", self._dragLeaveCb)
+ self.treeview.connect("drag-drop", self._dragDropCb)
+ self.treeview.connect("drag-motion", self._dragMotionCb)
+ self.treeview.connect("query-tooltip",
+ self._treeViewQueryTooltipCb)
+
+ self.connect('notify::expanded', self.expandedcb)
+
+ self.table.attach(self.treeview_scrollwin, 0, 1, 1, 2)
+ self.VContent.pack_start(self.explain_box, expand=True, fill=True)
+
+ self._showExplainLabel()
+ self.VContent.show()
+
+ timeline = receiver()
+
+ @handler(timeline, "selection-changed")
+ def selectionChangedCb(self, timeline):
+ self.selected_effects = timeline.selection.getSelectedTrackEffects()
+ if timeline.selection.selected:
+ self.timeline_object = list(timeline.selection.selected)[0]
+ else:
+ self.timeline_object = None
+ print self.timeline_object
+ self._updateAll()
+
+ timeline_object = receiver()
+
+ @handler(timeline_object, "track-object-added")
+ def trackAddedCb(self, unused_timeline_object, track_object):
+ if isinstance (track_object, TrackEffect):
+ self.selected_effects = self.timeline.selection.getSelectedTrackEffects()
+ print self.timeline.selection.getSelectedTrackEffects()
+ self._updateAll()
+
+ @handler(timeline_object, "track-object-removed")
+ def trackAddedCb(self, track_object, unused):
+ if isinstance (track_object, TrackEffect):
+ self._updateAll()
+
+ def connectTimelineSelection(self, timeline):
+ self.timeline = timeline
+
+ def _dragDataReceivedCb(self, unused, context, x, y, timestamp):
+ print "Receive"
+
+ def _dragDropCb(self, unused, context, x, y, timestamp):
+ print "Drop"
+
+ def _dragLeaveCb(self, unused_layout, unused_context, unused_tstamp):
+ self.drag_unhighlight()
+
+ def _dragMotionCb(self, unused, context, x, y, timestamp):
+ self.drag_highlight()
+
+ def _timelineWatcherCb(self, timeline):
+ print timeline.selection
+
+ def effectActiveToggleCb(self, cellrenderertoggle, path):
+ cellrenderertoggle.set_active(not cellrenderertoggle.get_active())
+
+ def expandedcb(self, expander, params):
+ self._updateAll()
+
+ def _treeViewQueryTooltipCb(self, treeview, x, y, keyboard_mode, tooltip):
+ context = treeview.get_tooltip_context(x, y, keyboard_mode)
+
+ if context is None:
+ return False
+
+ treeview.set_tooltip_row (tooltip, context[1][0])
+ tooltip.set_text(self.storemodel.get_value(context[2], COL_DESC_TEXT))
+
+ return True
+
+ def _updateAll(self):
+ print "Updating"
+ if self.get_expanded():
+ if self.timeline_object:
+ self.table.show_all()
+ if not self.selected_effects:
+ self.toolbar1.hide()
+ self.explain_box.hide()
+ self._updateTreeview()
+ else:
+ self.table.hide()
+ self._showExplainLabel()
+ self.VContent.show()
+ else:
+ self.VContent.hide()
+
+ def _updateTreeview(self):
+ self.storemodel.clear()
+ for effect in self.selected_effects:
+ to_append = [True]
+ if isinstance(effect.factory.getInputStreams()[0], VideoStream):
+ to_append.append("Video")
+ elem = self.app.effects.getElementFromFactoryName(effect.factory.name, VIDEO_EFFECT)
+ else:
+ to_append.append("Audio")
+ elem = self.app.effects.getElementFromFactoryName(effect.factory.name, AUDIO_EFFECT)
+
+ to_append.append(getNiceEffectName(elem))
+ to_append.append(getNiceEffectDescription(elem))
+
+ self.storemodel.append(to_append)
+
+ def _showExplainLabel(self):
+ self.explain_box.show()
+ self.explain_label.show()
diff --git a/pitivi/ui/mainwindow.py b/pitivi/ui/mainwindow.py
index 3b60d4d..c7d67f3 100644
--- a/pitivi/ui/mainwindow.py
+++ b/pitivi/ui/mainwindow.py
@@ -44,7 +44,7 @@ from gettext import gettext as _
from pitivi.log.loggable import Loggable
from pitivi.ui.timeline import Timeline
-from pitivi.ui.projecttabs import ProjectTabs
+from pitivi.ui.basetabs import BaseTabs
from pitivi.ui.viewer import PitiviViewer
from pitivi.configure import pitivi_version, APPNAME, get_pixmap_dir, \
get_global_pixmap_dir, LIBDIR
@@ -57,6 +57,7 @@ import pitivi.formatters.format as formatter
from pitivi.sourcelist import SourceListError
from pitivi.ui.sourcelist import SourceList
from pitivi.ui.effectlist import EffectList
+from pitivi.ui.clipproperties import ClipProperties
from pitivi.ui.common import beautify_factory
from pitivi.utils import beautify_length
from pitivi.ui.zoominterface import Zoomable
@@ -396,12 +397,17 @@ class PitiviMainWindow(gtk.Window, Loggable):
self.timeline = Timeline(instance, self.uimanager)
self.timeline.project = self.project
- vpaned.pack2(self.timeline, resize=False, shrink=False)
+ vpaned.pack2(self.timeline, resize=True, shrink=False)
self.timeline.show()
+ hpanedprincipal = gtk.HPaned()
+ vpaned.pack1(hpanedprincipal, resize=True, shrink=False)
+
hpaned = gtk.HPaned()
- vpaned.pack1(hpaned, resize=True, shrink=False)
+ hpanedprincipal.pack1(hpaned, resize=True, shrink=False)
hpaned.show()
- self.projecttabs = ProjectTabs()
+ hpanedprincipal.show()
+
+ self.projecttabs = BaseTabs()
self.sourcelist = SourceList(instance, self.uimanager)
self.effectlist = EffectList(instance, self.uimanager)
@@ -414,6 +420,16 @@ class PitiviMainWindow(gtk.Window, Loggable):
hpaned.pack1(self.projecttabs, resize=True, shrink=False)
self.projecttabs.show()
+ #Clips properties
+ self.propertiestabs = BaseTabs()
+ self.clipconfig = ClipProperties(instance, self.uimanager)
+ self.clipconfig.project = self.project
+ self.propertiestabs.append_page(self.clipconfig, gtk.Label(_("Clip Properties")))
+ self.clipconfig.show()
+
+ hpaned.pack2(self.propertiestabs, resize= True, shrink=False)
+ self.propertiestabs.show()
+
# Viewer
self.viewer = PitiviViewer()
# drag and drop
@@ -421,11 +437,12 @@ class PitiviMainWindow(gtk.Window, Loggable):
[dnd.FILESOURCE_TUPLE, dnd.URI_TUPLE],
gtk.gdk.ACTION_COPY)
self.viewer.connect("drag_data_received", self._viewerDndDataReceivedCb)
- hpaned.pack2(self.viewer, resize=False, shrink=False)
+ hpanedprincipal.pack2(self.viewer, resize=False, shrink=False)
self.viewer.show()
self.viewer.connect("expose-event", self._exposeEventCb)
# window and pane position defaults
+ self.hpanedprincipal = hpanedprincipal
self.hpaned = hpaned
self.vpaned = vpaned
height = -1
@@ -591,7 +608,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
def _revertToSavedProjectCb(self, unused_action):
return self.app.projectManager.revertToSavedProject()
-
+
def _projectSettingsCb(self, unused_action):
from projectsettings import ProjectSettingsDialog
@@ -851,7 +868,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
if response <> gtk.RESPONSE_YES:
return False
return True
-
+
def _projectManagerNewProjectFailedCb(self, projectManager, uri, exception):
# ungrey UI
@@ -965,6 +982,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
self.project_timeline = self.project.timeline
if self.timeline:
self.timeline.project = self.project
+ self.clipconfig.project = self.project
project = receiver(_setProject)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]