pitivi r1380 - in trunk/pitivi: timeline ui
- From: edwardrv svn gnome org
- To: svn-commits-list gnome org
- Subject: pitivi r1380 - in trunk/pitivi: timeline ui
- Date: Fri, 28 Nov 2008 17:04:41 +0000 (UTC)
Author: edwardrv
Date: Fri Nov 28 17:04:40 2008
New Revision: 1380
URL: http://svn.gnome.org/viewvc/pitivi?rev=1380&view=rev
Log:
refactored CompositionLayers into TimelineCanvas and split into separate module
Modified:
trunk/pitivi/timeline/timeline.py
trunk/pitivi/ui/complextimeline.py
Modified: trunk/pitivi/timeline/timeline.py
==============================================================================
--- trunk/pitivi/timeline/timeline.py (original)
+++ trunk/pitivi/timeline/timeline.py Fri Nov 28 17:04:40 2008
@@ -188,8 +188,6 @@
# TODO: filtering mechanism
self.__edges = edges.keys()
self.__edges.sort()
- print self.__edges
- print self.__deadband
def snapTimeToEdge(self, time):
"""Returns the input time or the nearest edge"""
Modified: trunk/pitivi/ui/complextimeline.py
==============================================================================
--- trunk/pitivi/ui/complextimeline.py (original)
+++ trunk/pitivi/ui/complextimeline.py Fri Nov 28 17:04:40 2008
@@ -32,52 +32,10 @@
from complexlayer import LayerInfoList
import ruler
from complexinterface import Zoomable
-import goocanvas
-# FIXME : wildcard imports are BAD !
-from util import *
-
-from pitivi.utils import closest_item
-from gettext import gettext as _
-
-# ui imports
import dnd
-from track import Track
-# default heights for composition layer objects
-
-RAZOR_LINE = (
- goocanvas.Rect,
- {
- "line_width" : 0,
- "fill_color" : "orange",
- "width" : 1,
- },
- {}
-)
-
-# the vsiual appearance for the selection marquee
-MARQUEE = (
- goocanvas.Rect,
- {
- "stroke_color_rgba" : 0x33CCFF66,
- "fill_color_rgba" : 0x33CCFF66,
- },
- {}
-)
-
-# cursors to be used for resizing objects
-ARROW = gtk.gdk.Cursor(gtk.gdk.ARROW)
-# TODO: replace this with custom cursor
-RAZOR_CURSOR = gtk.gdk.Cursor(gtk.gdk.XTERM)
-
-# FIXME: do we want this expressed in pixels or miliseconds?
-# If we express it in miliseconds, then we can have the core handle edge
-# snapping (it's really best implemented in the core). On the other hand, if
-# the dead-band is a constant unit of time, it will be too large at high zoom,
-# and too small at low zoom. So we might want to be able to adjust the
-# deadband from the UI.
-# default number of pixels to use for edge snaping
-DEADBAND = 5
+from gettext import gettext as _
+from timelinecanvas import TimelineCanvas
# tooltip text for toolbar
DELETE = _("Delete Selected")
@@ -103,251 +61,6 @@
</ui>
'''
-# FIXME: this class should be renamed CompositionTracks, or maybe just Tracks.
-
-class CompositionLayers(goocanvas.Canvas, Zoomable):
- """ Souped-up VBox that contains the timeline's CompositionLayer """
-
- def __init__(self, layerinfolist):
- goocanvas.Canvas.__init__(self)
- self._selected_sources = []
- self._timeline_position = 0
-
- self._block_size_request = False
- self.props.integer_layout = True
- self.props.automatic_bounds = False
-
- self.layerInfoList = layerinfolist
- self.layerInfoList.connect('layer-added', self._layerAddedCb)
- self.layerInfoList.connect('layer-removed', self._layerRemovedCb)
-
- self._createUI()
- self.connect("size_allocate", self._size_allocate)
-
- def _createUI(self):
- self._cursor = ARROW
-
- self.layers = VList(canvas=self)
- self.layers.connect("notify::width", self._request_size)
- self.layers.connect("notify::height", self._request_size)
-
- root = self.get_root_item()
- root.add_child(self.layers)
-
- root.connect("enter_notify_event", self._mouseEnterCb)
- self._marquee = make_item(MARQUEE)
- manage_selection(self, self._marquee, True, self._selection_changed_cb)
-
- self._razor = make_item(RAZOR_LINE)
- self._razor.props.visibility = goocanvas.ITEM_INVISIBLE
- root.add_child(self._razor)
-
-## methods for dealing with updating the canvas size
-
- def block_size_request(self, status):
- self._block_size_request = status
-
- def _size_allocate(self, unused_layout, allocation):
- self._razor.props.height = allocation.height
-
- def _request_size(self, unused_item, unused_prop):
- #TODO: figure out why this doesn't work... (wtf?!?)
- if self._block_size_request:
- return True
- # we only update the bounds of the canvas by chunks of 100 pixels
- # in width, otherwise we would always be redrawing the whole canvas.
- # Make sure canvas is at least 800 pixels wide, and at least 100 pixels
- # wider than it actually needs to be.
- w = max(800, ((int(self.layers.width + 100) / 100) + 1 ) * 100)
- h = int(self.layers.height)
- x1, y1, x2, y2 = self.get_bounds()
- pw = abs(x2 - x1)
- ph = abs(y2 - y1)
- if not (w == pw and h == ph):
- self.set_bounds(0, 0, w, h)
- return True
-
-## mouse callbacks
-
- def _mouseEnterCb(self, unused_item, unused_target, event):
- event.window.set_cursor(self._cursor)
- return True
-
-## Editing Operations
-
- # FIXME: here once again we're doing something that would be better done
- # in the core. As we add different types of objects in the Core, we'll
- # have to modify this code here (maybe there are different ways of
- # deleting different objects: you might delete() a source, but unset() a
- # keyframe)
-
- def deleteSelected(self, unused_action):
- for obj in self._selected_sources:
- if obj.comp:
- obj.comp.removeSource(obj.element, remove_linked=True,
- collapse_neighbours=False)
- set_selection(self, set())
- return True
-
-
- # FIXME: the razor is the one toolbar tool that violates the noun-verb
- # principle. Do I really want to make an exception for this? What about
- # just double-clicking on the source like jokosher?
-
- def activateRazor(self, unused_action):
- self._cursor = RAZOR_CURSOR
- # we don't want mouse events passing through to the canvas items
- # underneath, so we connect to the canvas's signals
- self._razor_sigid = self.connect("button_press_event",
- self._razorClickedCb)
- self._razor_motion_sigid = self.connect("motion_notify_event",
- self._razorMovedCb)
- self._razor.props.visibility = goocanvas.ITEM_VISIBLE
- return True
-
- def _razorMovedCb(self, canvas, event):
- x = event_coords(self, event)[0]
- self._razor.props.x = self.nsToPixel(self.pixelToNs(x))
- return True
-
- def _razorClickedCb(self, unused_canvas, event):
- self._cursor = ARROW
- event.window.set_cursor(ARROW)
- self.disconnect(self._razor_sigid)
- self.disconnect(self._razor_motion_sigid)
- self._razor.props.visibility = goocanvas.ITEM_INVISIBLE
-
- # Find the topmost source under the mouse. This is tricky because not
- # all objects in the timeline are TimelineObjects. Some of them
- # are drag handles, for example. For now, only objects marked as
- # selectable should be sources
- x, y = event_coords(self, event)
- items = self.get_items_at(x, y, True)
- if not items:
- return True
- for item in items:
- if item.get_data("selectable"):
- parent = item.get_parent()
- gst.log("attempting to split source at position %d" % x)
- self._splitSource(parent, self.pixelToNs(x))
- return True
-
- # FIXME: this DEFINITELY needs to be in the core. Also, do we always want
- # to split linked sources? Should the user be forced to un-link linked
- # sources when they only wisth to split one of them? If not,
-
- def _splitSource(self, obj, editpoint):
- comp = obj.comp
- element = obj.element
-
- # we want to divide element in elementA, elementB at the
- # edit point.
- a_start = element.start
- a_end = editpoint
- b_start = editpoint
- b_end = element.start + element.duration
-
- # so far so good, but we need this expressed in the form
- # start/duration.
- a_dur = a_end - a_start
- b_dur = b_end - b_start
- if not (a_dur and b_dur):
- gst.Log("cannot cut at existing edit point, aborting")
- return
-
- # and finally, we need the media-start/duration for both sources.
- # in this case, media-start = media-duration, but this would not be
- # true if timestretch were applied to either source. this is why I
- # really think we should not have to care about media-start /duratoin
- # here, and have a more abstract method for setting time stretch that
- # would keep media start/duration in sync for sources that have it.
- a_media_start = element.media_start
- b_media_start = a_media_start + a_dur
-
- # trim source a
- element.setMediaStartDurationTime(a_media_start, a_dur)
- element.setStartDurationTime(a_start, a_dur)
-
- # add source b
- # TODO: for linked sources, split linked and create brother
- # TODO: handle other kinds of sources
- new = TimelineFileSource(factory=element.factory,
- media_type=comp.media_type)
- new.setMediaStartDurationTime(b_media_start, b_dur)
- new.setStartDurationTime(b_start, b_dur)
- comp.addSource(new, 0, True)
-
- # FIXME: should be implemented in core, if at all. Another alternative
- # would be directly suppporting ripple edits in the core, rather than
- # doing select after + move selection.
-
- def selectBeforeCurrent(self, unused_action):
- pass
-
- def selectAfterCurrent(self, unused_action):
- ## helper function
- #def source_pos(ui_obj):
- # return ui_obj.comp.getSimpleSourcePosition(ui_obj.element)
-
- ## mapping from composition -> (source1, ... sourceN)
- #comps = dict()
- #for source in self._selected_sources:
- # if not source.comp in comps:
- # comps[source.comp] = []
- # comps[source.comp].append(source)
-
- ## find the latest source in each compostion, and all sources which
- ## occur after it. then select them.
- #to_select = set()
- #for comp, sources in comps.items():
- # # source positions start at 1, not 0.
- # latest = max((source_pos(source) for source in sources)) - 1
- # # widget is available in "widget" data member of object.
- # # we add the background of the widget, not the widget itself.
- # objs = [obj.get_data("widget").bg for obj in comp.condensed[latest:]]
- # to_select.update(set(objs))
- #set_selection(self, to_select)
- pass
-
- def _selection_changed_cb(self, selected, deselected):
- # TODO: filter this list for things other than sources, and put them
- # into appropriate lists
- for item in selected:
- item.props.fill_color_rgba = item.get_data("selected_color")
- parent = item.get_parent()
- self._selected_sources.append(parent)
- for item in deselected:
- item.props.fill_color_rgba = item.get_data("normal_color")
- parent = item.get_parent()
- self._selected_sources.remove(parent)
-
- def timelinePositionChanged(self, value, unused_frame):
- self._timeline_position = value
-
-## Zoomable Override
-
- def zoomChanged(self):
- instance.PiTiVi.current.timeline.setDeadband(self.pixelToNs(DEADBAND))
-
- def setChildZoomAdjustment(self, adj):
- for layer in self.layers:
- layer.setZoomAdjustment(adj)
-
-## LayerInfoList callbacks
-
- def _layerAddedCb(self, unused_infolist, layer, position):
- track = Track()
- track.setZoomAdjustment(self.getZoomAdjustment())
- track.set_composition(layer.composition)
- track.set_canvas(self)
- self.layers.insert_child(track, position)
- self.set_bounds(0, 0, self.layers.width, self.layers.height)
- self.set_size_request(int(self.layers.width), int(self.layers.height))
-
- def _layerRemovedCb(self, unused_layerInfoList, position):
- child = self.layers.item_at(position)
- self.layers.remove_child(child)
-#
# Complex Timeline Design v2 (08 Feb 2006)
#
#
@@ -361,7 +74,7 @@
# |
# +--gtk.ScrolledWindow
# |
-# +--CompositionLayers(goocanas.Canvas)
+# +--TimelineCanvas(goocanas.Canvas)
# | |
# | +--Track(SmartGroup)
# |
@@ -414,8 +127,8 @@
self.ruler.set_border_width(2)
self.pack_start(self.ruler, expand=False, fill=True)
- # List of CompositionLayers
- self.compositionLayers = CompositionLayers(self.layerInfoList)
+ # List of TimelineCanvas
+ self.compositionLayers = TimelineCanvas(self.layerInfoList)
self.compositionLayers.setZoomAdjustment(self._zoom_adj)
self.scrolledWindow = gtk.ScrolledWindow(self.hadj)
self.scrolledWindow.set_policy(gtk.POLICY_ALWAYS, gtk.POLICY_AUTOMATIC)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]