Example #1
0
    class Controller(TrackElementController):

        _cursor = RIGHT_SIDE

        def drag_start(self, item, target, event):
            self.debug("Trim end %s" % target)
            TrackElementController.drag_start(self, item, target, event)

            if self._view.element.is_locked():
                elem = self._view.element.get_clip()
            else:
                elem = self._view.element
            self._context = EditingContext(elem, self._view.timeline,
                GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_END, set([]),
                self.app.settings)
            self._context.connect("clip-trim", self.clipTrimCb)
            self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)
            self._view.app.action_log.begin("trim object")

        def clipTrimCb(self, unused_TrimStartContext, tl_obj, position):
            # While a clip is being trimmed, ask the viewer to preview it
            self._view.app.gui.viewer.clipTrimPreview(tl_obj, position)

        def clipTrimFinishedCb(self, unused_TrimStartContext):
            # When a clip has finished trimming, tell the viewer to reset itself
            self._view.app.gui.viewer.clipTrimPreviewFinished()
Example #2
0
    def _dragProgressCb(self, action, actor, delta_x, delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        if not self.gotDragged:
            self.gotDragged = True
            self._context = EditingContext(self.bElement,
                                           self.timeline.bTimeline,
                                           None,
                                           GES.Edge.EDGE_NONE,
                                           None,
                                           self.timeline._container.app.action_log)

        mode = self.timeline._container.getEditionMode()
        self._context.setMode(mode)

        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        delta_y = coords[1] - self.dragBeginStartY
        y = coords[1] + self.timeline._container.point.y
        priority = self._getLayerForY(y)
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)

        self.ghostclip.props.x = max(0, self.nsToPixel(self._dragBeginStart) + delta_x)
        self.ghostclip.update(priority, y, False)
        if self.brother:
            self.brother.ghostclip.props.x = max(0, self.nsToPixel(self._dragBeginStart) + delta_x)
            self.brother.ghostclip.update(priority, y, True)

        if not self.ghostclip.props.visible:
            self._context.editTo(new_start, self.bElement.get_parent().get_layer().get_priority())
        else:
            self._context.editTo(self._dragBeginStart, self.bElement.get_parent().get_layer().get_priority())

        self.timeline._updateSize(self.ghostclip)
        return False
Example #3
0
    def _dragProgressCb(self, action, actor, delta_x, delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        if not self.gotDragged:
            self.gotDragged = True
            self._context = EditingContext(self.bElement,
                                           self.timeline.bTimeline,
                                           None,
                                           GES.Edge.EDGE_NONE,
                                           None,
                                           self.timeline._container.app.action_log)

        mode = self.timeline._container.getEditionMode()
        self._context.setMode(mode)

        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        delta_y = coords[1] - self.dragBeginStartY
        y = coords[1] + self.timeline._container.point.y
        priority = self._getLayerForY(y)
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)

        self.ghostclip.props.x = max(0, self.nsToPixel(self._dragBeginStart) + delta_x)
        self.ghostclip.update(priority, y, False)
        if self.brother:
            self.brother.ghostclip.props.x = max(0, self.nsToPixel(self._dragBeginStart) + delta_x)
            self.brother.ghostclip.update(priority, y, True)

        if not self.ghostclip.props.visible:
            self._context.editTo(new_start, self.bElement.get_parent().get_layer().get_priority())
        else:
            self._context.editTo(self._dragBeginStart, self.bElement.get_parent().get_layer().get_priority())

        self.timeline._updateSize(self.ghostclip)
        return False
Example #4
0
    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        mode = self.timeline._container.getEditionMode()
        self._context = EditingContext(
            self.bElement, self.timeline.bTimeline, mode, GES.Edge.EDGE_NONE,
            self.timeline.selection.getSelectedTrackElements(), None)
        # This can't change during a drag, so we can safely compute it now for drag events.
        nbrLayers = len(self.timeline.bTimeline.get_layers())
        self.brother = self.timeline.findBrother(self.bElement)
        self._dragBeginStart = self.bElement.get_start()
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y

        self.nbrLayers = nbrLayers
        self.ghostclip.setNbrLayers(nbrLayers)
        self.ghostclip.setWidth(self.props.width)
        if self.brother:
            self.brother.ghostclip.setWidth(self.props.width)
            self.brother.ghostclip.setNbrLayers(nbrLayers)

        # We can also safely find if the object has a brother element
        self.setDragged(True)
Example #5
0
    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y
        elem = self.timelineElement.bElement.get_parent()
        self.timelineElement.setDragged(True)

        if self.isLeft:
            edge = GES.Edge.EDGE_START
            self._dragBeginStart = self.timelineElement.bElement.get_parent(
            ).get_start()
        else:
            edge = GES.Edge.EDGE_END
            self._dragBeginStart = self.timelineElement.bElement.get_parent().get_duration() + \
                self.timelineElement.bElement.get_parent().get_start()

        self._context = EditingContext(elem,
                                       self.timelineElement.timeline.bTimeline,
                                       GES.EditMode.EDIT_TRIM, edge, set([]),
                                       None)

        self._context.connect("clip-trim", self.clipTrimCb)
        self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)
Example #6
0
        def drag_start(self, item, target, event):
            self.debug("Trim end %s" % target)
            TrackElementController.drag_start(self, item, target, event)

            if self._view.element.is_locked():
                elem = self._view.element.get_clip()
            else:
                elem = self._view.element
            self._context = EditingContext(elem, self._view.timeline,
                GES.EditMode.EDIT_TRIM, GES.Edge.EDGE_END, set([]),
                self.app.settings)
            self._context.connect("clip-trim", self.clipTrimCb)
            self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)
            self._view.app.action_log.begin("trim object")
Example #7
0
        def drag_start(self, item, target, event):
            self.debug("Trim start %s" % target)
            TrackObjectController.drag_start(self, item, target, event)

            if self._view.element.is_locked():
                elem = self._view.element.get_timeline_object()
            else:
                elem = self._view.element

            self._context = EditingContext(elem, self._view.timeline,
                ges.EDIT_MODE_TRIM, ges.EDGE_START, set([]),
                self.app.settings)
            self._context.connect("clip-trim", self.clipTrimCb)
            self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)

            self._view.app.action_log.begin("trim object")
Example #8
0
    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y
        elem = self.timelineElement.bElement.get_parent()
        self.timelineElement.setDragged(True)

        if self.isLeft:
            edge = GES.Edge.EDGE_START
            self._dragBeginStart = self.timelineElement.bElement.get_parent().get_start()
        else:
            edge = GES.Edge.EDGE_END
            self._dragBeginStart = self.timelineElement.bElement.get_parent().get_duration() + \
                self.timelineElement.bElement.get_parent().get_start()

        self._context = EditingContext(elem,
                                       self.timelineElement.timeline.bTimeline,
                                       GES.EditMode.EDIT_TRIM,
                                       edge,
                                       None)

        self._context.connect("clip-trim", self.clipTrimCb)
        self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)
Example #9
0
    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        mode = self.timeline._container.getEditionMode()
        self._context = EditingContext(self.bElement,
                                       self.timeline.bTimeline,
                                       mode,
                                       GES.Edge.EDGE_NONE,
                                       None)
        # This can't change during a drag, so we can safely compute it now for drag events.
        nbrLayers = len(self.timeline.bTimeline.get_layers())
        self.brother = self.timeline.findBrother(self.bElement)
        self._dragBeginStart = self.bElement.get_start()
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y

        self.nbrLayers = nbrLayers
        self.ghostclip.setNbrLayers(nbrLayers)
        self.ghostclip.setWidth(self.props.width)
        if self.brother:
            self.brother.ghostclip.setWidth(self.props.width)
            self.brother.ghostclip.setNbrLayers(nbrLayers)

        # We can also safely find if the object has a brother element
        self.setDragged(True)
Example #10
0
 def __check_with_video(self, clip, expected):
     context = EditingContext(clip, None, None, None, None, None)
     if expected:
         self.assertTrue(context.with_video)
     else:
         self.assertFalse(context.with_video)
Example #11
0
class TrimHandle(Clutter.Texture):
    def __init__(self, timelineElement, isLeft):
        Clutter.Texture.__init__(self)

        self.isLeft = isLeft
        self.timelineElement = weakref.proxy(timelineElement)
        self.dragAction = Clutter.DragAction()

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.set_size(-1, EXPANDED_SIZE)
        self.hide()
        self.set_reactive(True)

        self.add_action(self.dragAction)
        self.dragAction.connect("drag-begin", self._dragBeginCb)
        self.dragAction.connect("drag-end", self._dragEndCb)
        self.dragAction.connect("drag-progress", self._dragProgressCb)

        self.connect("enter-event", self._enterEventCb)
        self.connect("leave-event", self._leaveEventCb)

        self.timelineElement.connect("enter-event", self._elementEnterEventCb)
        self.timelineElement.connect("leave-event", self._elementLeaveEventCb)

    def cleanup(self):
        self.disconnect_by_func(self._enterEventCb)
        self.disconnect_by_func(self._leaveEventCb)
        self.timelineElement.disconnect_by_func(self._elementEnterEventCb)
        self.timelineElement.disconnect_by_func(self._elementLeaveEventCb)

    # Callbacks

    def _enterEventCb(self, unused_actor, unused_event):
        self.timelineElement.set_reactive(False)
        for elem in self.timelineElement.get_children():
            elem.set_reactive(False)
        self.set_reactive(True)

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-focused.png"))
        if self.isLeft:
            self.timelineElement.timeline._container.embed.get_window(
            ).set_cursor(DRAG_LEFT_HANDLEBAR_CURSOR)
        else:
            self.timelineElement.timeline._container.embed.get_window(
            ).set_cursor(DRAG_RIGHT_HANDLEBAR_CURSOR)

    def _leaveEventCb(self, unused_actor, event):
        self.timelineElement.set_reactive(True)
        children = self.timelineElement.get_children()

        other_actor = self.timelineElement.timeline._container.stage.get_actor_at_pos(
            Clutter.PickMode.ALL, event.x, event.y)
        if other_actor not in children:
            self.timelineElement.hideHandles()

        for elem in children:
            elem.set_reactive(True)
        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.timelineElement.timeline._container.embed.get_window().set_cursor(
            NORMAL_CURSOR)

    def _elementEnterEventCb(self, unused_actor, unused_event):
        self.show()

    def _elementLeaveEventCb(self, unused_actor, unused_event):
        self.hide()

    def _dragBeginCb(self, unused_action, unused_actor, event_x, event_y,
                     unused_modifiers):
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y
        elem = self.timelineElement.bElement.get_parent()
        self.timelineElement.setDragged(True)

        if self.isLeft:
            edge = GES.Edge.EDGE_START
            self._dragBeginStart = self.timelineElement.bElement.get_parent(
            ).get_start()
        else:
            edge = GES.Edge.EDGE_END
            self._dragBeginStart = self.timelineElement.bElement.get_parent().get_duration() + \
                self.timelineElement.bElement.get_parent().get_start()

        self._context = EditingContext(
            elem, self.timelineElement.timeline.bTimeline,
            GES.EditMode.EDIT_TRIM, edge, None,
            self.timelineElement.timeline._container.app.action_log)

        self._context.connect("clip-trim", self.clipTrimCb)
        self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)

    def _dragProgressCb(self, unused_action, unused_actor, delta_x,
                        unused_delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        new_start = self._dragBeginStart + Zoomable.pixelToNs(delta_x)

        self._context.setMode(
            self.timelineElement.timeline._container.getEditionMode(
                isAHandle=True))
        self._context.editTo(
            new_start,
            self.timelineElement.bElement.get_parent().get_layer().
            get_priority())
        return False

    def _dragEndCb(self, unused_action, unused_actor, unused_event_x,
                   unused_event_y, unused_modifiers):
        self.timelineElement.setDragged(False)
        self._context.finish()

        self.timelineElement.set_reactive(True)
        for elem in self.timelineElement.get_children():
            elem.set_reactive(True)

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.timelineElement.timeline._container.embed.get_window().set_cursor(
            NORMAL_CURSOR)

    def clipTrimCb(self, unused_TrimStartContext, tl_obj, position):
        # While a clip is being trimmed, ask the viewer to preview it
        self.timelineElement.timeline._container.app.gui.viewer.clipTrimPreview(
            tl_obj, position)

    def clipTrimFinishedCb(self, unused_TrimStartContext):
        # When a clip has finished trimming, tell the viewer to reset itself
        self.timelineElement.timeline._container.app.gui.viewer.clipTrimPreviewFinished(
        )
Example #12
0
class URISourceElement(TimelineElement):
    def __init__(self, bElement, timeline):
        TimelineElement.__init__(self, bElement, timeline)
        self.gotDragged = False

    # public API

    def hideHandles(self):
        self.rightHandle.hide()
        self.leftHandle.hide()

    # private API

    def _createGhostclip(self):
        self.ghostclip = Ghostclip(self.track_type, self.bElement)
        self.timeline.add_child(self.ghostclip)

    def _createHandles(self):
        self.leftHandle = TrimHandle(self, True)
        self.rightHandle = TrimHandle(self, False)

        self.leftHandle.set_position(0, 0)

        self.add_child(self.leftHandle)
        self.add_child(self.rightHandle)

    def _createBackground(self):
        if self.track_type == GES.TrackType.AUDIO:
            # Audio clips go from dark green to light green
            # (27, 46, 14, 255) to (73, 108, 33, 255)
            background = Gradient(27, 46, 14, 73, 108, 33)
        else:
            # Video clips go from almost black to gray
            # (15, 15, 15, 255) to (45, 45, 45, 255)
            background = Gradient(15, 15, 15, 45, 45, 45)
        background.bElement = self.bElement
        return background

    # Callbacks
    def _clickedCb(self, unused_action, unused_actor):
        # TODO : Let's be more specific, masks etc ..
        mode = SELECT
        if self.timeline._container._controlMask:
            if not self.bElement.selected:
                mode = SELECT_ADD
                self.timeline.current_group.add(
                    self.bElement.get_toplevel_parent())
            else:
                self.timeline.current_group.remove(
                    self.bElement.get_toplevel_parent())
                mode = UNSELECT
        elif not self.bElement.selected:
            GES.Container.ungroup(self.timeline.current_group, False)
            self.timeline.createSelectionGroup()
            self.timeline.current_group.add(
                self.bElement.get_toplevel_parent())
            self.timeline._container.gui.switchContextTab(self.bElement)

        children = self.bElement.get_toplevel_parent().get_children(True)
        selection = [elem for elem in children if isinstance(elem, GES.Source)]

        self.timeline.selection.setSelection(selection, mode)

        if self.keyframedElement:
            self.showKeyframes(self.keyframedElement, self.prop)

        return False

    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        self.gotDragged = False
        mode = self.timeline._container.getEditionMode()

        # This can't change during a drag, so we can safely compute it now for
        # drag events.
        nbrLayers = len(self.timeline.bTimeline.get_layers())
        self.brother = self.timeline.findBrother(self.bElement)
        self._dragBeginStart = self.bElement.get_start()
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y

        self.nbrLayers = nbrLayers
        self.ghostclip.setNbrLayers(nbrLayers)
        self.ghostclip.setWidth(self.props.width)
        if self.brother:
            self.brother.ghostclip.setWidth(self.props.width)
            self.brother.ghostclip.setNbrLayers(nbrLayers)

        # We can also safely find if the object has a brother element
        self.setDragged(True)

    def _dragProgressCb(self, action, actor, delta_x, delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        if not self.gotDragged:
            self.gotDragged = True
            self._context = EditingContext(
                self.bElement, self.timeline.bTimeline, None,
                GES.Edge.EDGE_NONE, None,
                self.timeline._container.app.action_log)

        mode = self.timeline._container.getEditionMode()
        self._context.setMode(mode)

        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        delta_y = coords[1] - self.dragBeginStartY
        y = coords[1] + self.timeline._container.point.y
        priority = self._getLayerForY(y)
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)

        self.ghostclip.props.x = max(
            0,
            self.nsToPixel(self._dragBeginStart) + delta_x)
        self.ghostclip.update(priority, y, False)
        if self.brother:
            self.brother.ghostclip.props.x = max(
                0,
                self.nsToPixel(self._dragBeginStart) + delta_x)
            self.brother.ghostclip.update(priority, y, True)

        if not self.ghostclip.props.visible:
            self._context.editTo(
                new_start,
                self.bElement.get_parent().get_layer().get_priority())
        else:
            self._context.editTo(
                self._dragBeginStart,
                self.bElement.get_parent().get_layer().get_priority())

        self.timeline._updateSize(self.ghostclip)
        return False

    def _dragEndCb(self, action, actor, event_x, event_y, modifiers):
        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)
        priority = self._getLayerForY(coords[1] +
                                      self.timeline._container.point.y)
        priority = min(priority, len(self.timeline.bTimeline.get_layers()))
        priority = max(0, priority)

        self.timeline._snapEndedCb()
        self.setDragged(False)

        self.ghostclip.props.visible = False
        if self.brother:
            self.brother.ghostclip.props.visible = False

        if self.ghostclip.shouldCreateLayer:
            self.timeline.createLayerForGhostClip(self.ghostclip)

        if self.gotDragged:
            self._context.editTo(new_start, priority)
            self._context.finish()

    def cleanup(self):
        if self.preview and not type(self.preview) is Clutter.Actor:
            self.preview.cleanup()
        self.leftHandle.cleanup()
        self.leftHandle = None
        self.rightHandle.cleanup()
        self.rightHandle = None
        TimelineElement.cleanup(self)
Example #13
0
class URISourceElement(TimelineElement):
    def __init__(self, bElement, track, timeline):
        TimelineElement.__init__(self, bElement, track, timeline)

    # public API

    def hideHandles(self):
        self.rightHandle.hide()
        self.leftHandle.hide()

    # private API

    def _createGhostclip(self):
        self.ghostclip = Ghostclip(self.track_type, self.bElement)
        self.timeline.add_child(self.ghostclip)

    def _createHandles(self):
        self.leftHandle = TrimHandle(self, True)
        self.rightHandle = TrimHandle(self, False)

        self.leftHandle.set_position(0, 0)

        self.add_child(self.leftHandle)
        self.add_child(self.rightHandle)

    def _createBackground(self, track):
        if track.type == GES.TrackType.AUDIO:
            # Audio clips go from dark green to light green
            # (27, 46, 14, 255) to (73, 108, 33, 255)
            self.background = Gradient(27, 46, 14, 73, 108, 33)
        else:
            # Video clips go from almost black to gray
            # (15, 15, 15, 255) to (45, 45, 45, 255)
            self.background = Gradient(15, 15, 15, 45, 45, 45)

        self.background.bElement = self.bElement

        self.add_child(self.background)
        self.background.set_position(0, 0)

    # Callbacks
    def _clickedCb(self, action, actor):
        #TODO : Let's be more specific, masks etc ..
        self.timeline.selection.setToObj(self.bElement, SELECT)

    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        mode = self.timeline._container.getEditionMode()
        self._context = EditingContext(
            self.bElement, self.timeline.bTimeline, mode, GES.Edge.EDGE_NONE,
            self.timeline.selection.getSelectedTrackElements(), None)
        # This can't change during a drag, so we can safely compute it now for drag events.
        nbrLayers = len(self.timeline.bTimeline.get_layers())
        self.brother = self.timeline.findBrother(self.bElement)
        self._dragBeginStart = self.bElement.get_start()
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y

        self.nbrLayers = nbrLayers
        self.ghostclip.setNbrLayers(nbrLayers)
        self.ghostclip.setWidth(self.props.width)
        if self.brother:
            self.brother.ghostclip.setWidth(self.props.width)
            self.brother.ghostclip.setNbrLayers(nbrLayers)

        # We can also safely find if the object has a brother element
        self.setDragged(True)

    def _dragProgressCb(self, action, actor, delta_x, delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        mode = self.timeline._container.getEditionMode()
        self._context.setMode(mode)

        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        delta_y = coords[1] - self.dragBeginStartY
        y = coords[1] + self.timeline._container.point.y
        priority = self._getLayerForY(y)
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)

        self.ghostclip.props.x = max(
            0,
            self.nsToPixel(self._dragBeginStart) + delta_x)
        self.ghostclip.update(priority, y, False)
        if self.brother:
            self.brother.ghostclip.props.x = max(
                0,
                self.nsToPixel(self._dragBeginStart) + delta_x)
            self.brother.ghostclip.update(priority, y, True)

        if not self.ghostclip.props.visible:
            self._context.editTo(
                new_start,
                self.bElement.get_parent().get_layer().get_priority())
        else:
            self._context.editTo(
                self._dragBeginStart,
                self.bElement.get_parent().get_layer().get_priority())

        self.timeline._updateSize(self.ghostclip)
        return False

    def _dragEndCb(self, action, actor, event_x, event_y, modifiers):
        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)
        priority = self._getLayerForY(coords[1] +
                                      self.timeline._container.point.y)
        priority = min(priority, len(self.timeline.bTimeline.get_layers()))
        priority = max(0, priority)

        self.timeline._snapEndedCb()
        self.setDragged(False)

        self.ghostclip.props.visible = False
        if self.brother:
            self.brother.ghostclip.props.visible = False

        if self.ghostclip.shouldCreateLayer:
            self.timeline.insertLayer(self.ghostclip)

        self._context.editTo(new_start, priority)
        self._context.finish()

    def _selectedChangedCb(self, selected, isSelected):
        self.marquee.props.visible = isSelected
Example #14
0
class TrimHandle(Clutter.Texture):
    def __init__(self, timelineElement, isLeft):
        Clutter.Texture.__init__(self)

        self.isLeft = isLeft
        self.isSelected = False
        self.timelineElement = timelineElement
        self.dragAction = Clutter.DragAction()

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.set_size(-1, EXPANDED_SIZE)
        self.hide()
        self.set_reactive(True)

        self.add_action(self.dragAction)

        self.dragAction.connect("drag-begin", self._dragBeginCb)
        self.dragAction.connect("drag-end", self._dragEndCb)
        self.dragAction.connect("drag-progress", self._dragProgressCb)

        self.connect("enter-event", self._enterEventCb)
        self.connect("leave-event", self._leaveEventCb)

        self.timelineElement.connect("enter-event", self._elementEnterEventCb)
        self.timelineElement.connect("leave-event", self._elementLeaveEventCb)
        self.timelineElement.bElement.selected.connect("selected-changed",
                                                       self._selectedChangedCb)

    #Callbacks

    def _enterEventCb(self, actor, event):
        self.timelineElement.set_reactive(False)
        for elem in self.timelineElement.get_children():
            elem.set_reactive(False)
        self.set_reactive(True)

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-focused.png"))
        if self.isLeft:
            self.timelineElement.timeline._container.embed.get_window(
            ).set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_SIDE))
        else:
            self.timelineElement.timeline._container.embed.get_window(
            ).set_cursor(Gdk.Cursor.new(Gdk.CursorType.RIGHT_SIDE))

    def _leaveEventCb(self, actor, event):
        self.timelineElement.set_reactive(True)

        actor = self.timelineElement.timeline._container.stage.get_actor_at_pos(
            Clutter.PickMode.ALL, event.x, event.y)
        try:
            element = actor.bElement
            if element != self.timelineElement.bELement and not self.isSelected:
                self.timelineElement.hideHandles()
        except AttributeError:
            if not self.isSelected:
                self.timelineElement.hideHandles()

        for elem in self.timelineElement.get_children():
            elem.set_reactive(True)
        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.timelineElement.timeline._container.embed.get_window().set_cursor(
            Gdk.Cursor.new(Gdk.CursorType.ARROW))

    def _elementEnterEventCb(self, actor, event):
        self.show()

    def _elementLeaveEventCb(self, actor, event):
        if not self.isSelected:
            self.hide()

    def _selectedChangedCb(self, selected, isSelected):
        self.isSelected = isSelected
        self.props.visible = isSelected

    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y
        elem = self.timelineElement.bElement.get_parent()
        self.timelineElement.setDragged(True)

        if self.isLeft:
            edge = GES.Edge.EDGE_START
            self._dragBeginStart = self.timelineElement.bElement.get_parent(
            ).get_start()
        else:
            edge = GES.Edge.EDGE_END
            self._dragBeginStart = self.timelineElement.bElement.get_parent().get_duration() + \
                self.timelineElement.bElement.get_parent().get_start()

        self._context = EditingContext(elem,
                                       self.timelineElement.timeline.bTimeline,
                                       GES.EditMode.EDIT_TRIM, edge, set([]),
                                       None)

        self._context.connect("clip-trim", self.clipTrimCb)
        self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)

    def _dragProgressCb(self, action, actor, delta_x, delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        new_start = self._dragBeginStart + Zoomable.pixelToNs(delta_x)

        self._context.setMode(
            self.timelineElement.timeline._container.getEditionMode(
                isAHandle=True))
        self._context.editTo(
            new_start,
            self.timelineElement.bElement.get_parent().get_layer().
            get_priority())
        return False

    def _dragEndCb(self, action, actor, event_x, event_y, modifiers):
        self.timelineElement.setDragged(False)
        self._context.finish()

        self.timelineElement.set_reactive(True)
        for elem in self.timelineElement.get_children():
            elem.set_reactive(True)

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.timelineElement.timeline._container.embed.get_window().set_cursor(
            Gdk.Cursor.new(Gdk.CursorType.ARROW))

    def clipTrimCb(self, unused_TrimStartContext, tl_obj, position):
        # While a clip is being trimmed, ask the viewer to preview it
        self.timelineElement.timeline._container.app.gui.viewer.clipTrimPreview(
            tl_obj, position)

    def clipTrimFinishedCb(self, unused_TrimStartContext):
        # When a clip has finished trimming, tell the viewer to reset itself
        self.timelineElement.timeline._container.app.gui.viewer.clipTrimPreviewFinished(
        )
Example #15
0
class TrimHandle(Clutter.Texture):
    def __init__(self, timelineElement, isLeft):
        Clutter.Texture.__init__(self)

        self.isLeft = isLeft
        self.isSelected = False
        self.timelineElement = timelineElement
        self.dragAction = Clutter.DragAction()

        self.set_from_file(os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.set_size(-1, EXPANDED_SIZE)
        self.hide()
        self.set_reactive(True)

        self.add_action(self.dragAction)

        self.dragAction.connect("drag-begin", self._dragBeginCb)
        self.dragAction.connect("drag-end", self._dragEndCb)
        self.dragAction.connect("drag-progress", self._dragProgressCb)

        self.connect("enter-event", self._enterEventCb)
        self.connect("leave-event", self._leaveEventCb)

        self.timelineElement.connect("enter-event", self._elementEnterEventCb)
        self.timelineElement.connect("leave-event", self._elementLeaveEventCb)
        self.timelineElement.bElement.selected.connect("selected-changed", self._selectedChangedCb)

    #Callbacks

    def _enterEventCb(self, actor, event):
        self.timelineElement.set_reactive(False)
        for elem in self.timelineElement.get_children():
            elem.set_reactive(False)
        self.set_reactive(True)

        self.set_from_file(os.path.join(configure.get_pixmap_dir(), "trimbar-focused.png"))
        if self.isLeft:
            self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_SIDE))
        else:
            self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.RIGHT_SIDE))

    def _leaveEventCb(self, actor, event):
        self.timelineElement.set_reactive(True)

        actor = self.timelineElement.timeline._container.stage.get_actor_at_pos(Clutter.PickMode.ALL, event.x, event.y)
        try:
            element = actor.bElement
            if element != self.timelineElement.bELement and not self.isSelected:
                self.timelineElement.hideHandles()
        except AttributeError:
            if not self.isSelected:
                self.timelineElement.hideHandles()

        for elem in self.timelineElement.get_children():
            elem.set_reactive(True)
        self.set_from_file(os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))

    def _elementEnterEventCb(self, actor, event):
        self.show()

    def _elementLeaveEventCb(self, actor, event):
        if not self.isSelected:
            self.hide()

    def _selectedChangedCb(self, selected, isSelected):
        self.isSelected = isSelected
        self.props.visible = isSelected

    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y
        elem = self.timelineElement.bElement.get_parent()
        self.timelineElement.setDragged(True)

        if self.isLeft:
            edge = GES.Edge.EDGE_START
            self._dragBeginStart = self.timelineElement.bElement.get_parent().get_start()
        else:
            edge = GES.Edge.EDGE_END
            self._dragBeginStart = self.timelineElement.bElement.get_parent().get_duration() + \
                self.timelineElement.bElement.get_parent().get_start()

        self._context = EditingContext(elem,
                                       self.timelineElement.timeline.bTimeline,
                                       GES.EditMode.EDIT_TRIM,
                                       edge,
                                       None)

        self._context.connect("clip-trim", self.clipTrimCb)
        self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)

    def _dragProgressCb(self, action, actor, delta_x, delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        new_start = self._dragBeginStart + Zoomable.pixelToNs(delta_x)

        self._context.setMode(self.timelineElement.timeline._container.getEditionMode(isAHandle=True))
        self._context.editTo(new_start, self.timelineElement.bElement.get_parent().get_layer().get_priority())
        return False

    def _dragEndCb(self, action, actor, event_x, event_y, modifiers):
        self.timelineElement.setDragged(False)
        self._context.finish()

        self.timelineElement.set_reactive(True)
        for elem in self.timelineElement.get_children():
            elem.set_reactive(True)

        self.set_from_file(os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.timelineElement.timeline._container.embed.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.ARROW))

    def clipTrimCb(self, unused_TrimStartContext, tl_obj, position):
        # While a clip is being trimmed, ask the viewer to preview it
        self.timelineElement.timeline._container.app.gui.viewer.clipTrimPreview(tl_obj, position)

    def clipTrimFinishedCb(self, unused_TrimStartContext):
        # When a clip has finished trimming, tell the viewer to reset itself
        self.timelineElement.timeline._container.app.gui.viewer.clipTrimPreviewFinished()
Example #16
0
class URISourceElement(TimelineElement):

    def __init__(self, bElement, timeline):
        TimelineElement.__init__(self, bElement, timeline)
        self.gotDragged = False

    # public API

    def hideHandles(self):
        self.rightHandle.hide()
        self.leftHandle.hide()

    # private API

    def _createGhostclip(self):
        self.ghostclip = Ghostclip(self.track_type, self.bElement)
        self.timeline.add_child(self.ghostclip)

    def _createHandles(self):
        self.leftHandle = TrimHandle(self, True)
        self.rightHandle = TrimHandle(self, False)

        self.leftHandle.set_position(0, 0)

        self.add_child(self.leftHandle)
        self.add_child(self.rightHandle)

    def _createBackground(self):
        if self.track_type == GES.TrackType.AUDIO:
            # Audio clips go from dark green to light green
            # (27, 46, 14, 255) to (73, 108, 33, 255)
            background = Gradient(27, 46, 14, 73, 108, 33)
        else:
            # Video clips go from almost black to gray
            # (15, 15, 15, 255) to (45, 45, 45, 255)
            background = Gradient(15, 15, 15, 45, 45, 45)
        background.bElement = self.bElement
        return background

    # Callbacks
    def _clickedCb(self, unused_action, unused_actor):
        # TODO : Let's be more specific, masks etc ..
        mode = SELECT
        if self.timeline._container._controlMask:
            if not self.bElement.selected:
                mode = SELECT_ADD
                self.timeline.current_group.add(
                    self.bElement.get_toplevel_parent())
            else:
                self.timeline.current_group.remove(
                    self.bElement.get_toplevel_parent())
                mode = UNSELECT
        elif not self.bElement.selected:
            GES.Container.ungroup(self.timeline.current_group, False)
            self.timeline.createSelectionGroup()
            self.timeline.current_group.add(
                self.bElement.get_toplevel_parent())
            self.timeline._container.gui.switchContextTab(self.bElement)

        children = self.bElement.get_toplevel_parent().get_children(True)
        selection = [elem for elem in children if isinstance(elem, GES.Source)]

        self.timeline.selection.setSelection(selection, mode)

        if self.keyframedElement:
            self.showKeyframes(self.keyframedElement, self.prop)

        return False

    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        self.gotDragged = False
        mode = self.timeline._container.getEditionMode()

        # This can't change during a drag, so we can safely compute it now for
        # drag events.
        nbrLayers = len(self.timeline.bTimeline.get_layers())
        self.brother = self.timeline.findBrother(self.bElement)
        self._dragBeginStart = self.bElement.get_start()
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y

        self.nbrLayers = nbrLayers
        self.ghostclip.setNbrLayers(nbrLayers)
        self.ghostclip.setWidth(self.props.width)
        if self.brother:
            self.brother.ghostclip.setWidth(self.props.width)
            self.brother.ghostclip.setNbrLayers(nbrLayers)

        # We can also safely find if the object has a brother element
        self.setDragged(True)

    def _dragProgressCb(self, action, actor, delta_x, delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        if not self.gotDragged:
            self.gotDragged = True
            self._context = EditingContext(self.bElement,
                                           self.timeline.bTimeline,
                                           None,
                                           GES.Edge.EDGE_NONE,
                                           None,
                                           self.timeline._container.app.action_log)

        mode = self.timeline._container.getEditionMode()
        self._context.setMode(mode)

        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        delta_y = coords[1] - self.dragBeginStartY
        y = coords[1] + self.timeline._container.point.y
        priority = self._getLayerForY(y)
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)

        self.ghostclip.props.x = max(
            0, self.nsToPixel(self._dragBeginStart) + delta_x)
        self.ghostclip.update(priority, y, False)
        if self.brother:
            self.brother.ghostclip.props.x = max(
                0, self.nsToPixel(self._dragBeginStart) + delta_x)
            self.brother.ghostclip.update(priority, y, True)

        if not self.ghostclip.props.visible:
            self._context.editTo(
                new_start, self.bElement.get_parent().get_layer().get_priority())
        else:
            self._context.editTo(
                self._dragBeginStart, self.bElement.get_parent().get_layer().get_priority())

        self.timeline._updateSize(self.ghostclip)
        return False

    def _dragEndCb(self, action, actor, event_x, event_y, modifiers):
        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)
        priority = self._getLayerForY(
            coords[1] + self.timeline._container.point.y)
        priority = min(priority, len(self.timeline.bTimeline.get_layers()))
        priority = max(0, priority)

        self.timeline._snapEndedCb()
        self.setDragged(False)

        self.ghostclip.props.visible = False
        if self.brother:
            self.brother.ghostclip.props.visible = False

        if self.ghostclip.shouldCreateLayer:
            self.timeline.createLayerForGhostClip(self.ghostclip)

        if self.gotDragged:
            self._context.editTo(new_start, priority)
            self._context.finish()

    def cleanup(self):
        if self.preview and not type(self.preview) is Clutter.Actor:
            self.preview.cleanup()
        self.leftHandle.cleanup()
        self.leftHandle = None
        self.rightHandle.cleanup()
        self.rightHandle = None
        TimelineElement.cleanup(self)
Example #17
0
class TrimHandle(Clutter.Texture):

    def __init__(self, timelineElement, isLeft):
        Clutter.Texture.__init__(self)

        self.isLeft = isLeft
        self.timelineElement = weakref.proxy(timelineElement)
        self.dragAction = Clutter.DragAction()

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.set_size(-1, EXPANDED_SIZE)
        self.hide()
        self.set_reactive(True)

        self.add_action(self.dragAction)
        self.dragAction.connect("drag-begin", self._dragBeginCb)
        self.dragAction.connect("drag-end", self._dragEndCb)
        self.dragAction.connect("drag-progress", self._dragProgressCb)

        self.connect("enter-event", self._enterEventCb)
        self.connect("leave-event", self._leaveEventCb)

        self.timelineElement.connect("enter-event", self._elementEnterEventCb)
        self.timelineElement.connect("leave-event", self._elementLeaveEventCb)

    def cleanup(self):
        self.disconnect_by_func(self._enterEventCb)
        self.disconnect_by_func(self._leaveEventCb)
        self.timelineElement.disconnect_by_func(self._elementEnterEventCb)
        self.timelineElement.disconnect_by_func(self._elementLeaveEventCb)

    # Callbacks

    def _enterEventCb(self, unused_actor, unused_event):
        self.timelineElement.set_reactive(False)
        for elem in self.timelineElement.get_children():
            elem.set_reactive(False)
        self.set_reactive(True)

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-focused.png"))
        if self.isLeft:
            self.timelineElement.timeline._container.embed.get_window().set_cursor(
                DRAG_LEFT_HANDLEBAR_CURSOR)
        else:
            self.timelineElement.timeline._container.embed.get_window().set_cursor(
                DRAG_RIGHT_HANDLEBAR_CURSOR)

    def _leaveEventCb(self, unused_actor, event):
        self.timelineElement.set_reactive(True)
        children = self.timelineElement.get_children()

        other_actor = self.timelineElement.timeline._container.stage.get_actor_at_pos(
            Clutter.PickMode.ALL, event.x, event.y)
        if other_actor not in children:
            self.timelineElement.hideHandles()

        for elem in children:
            elem.set_reactive(True)
        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.timelineElement.timeline._container.embed.get_window().set_cursor(
            NORMAL_CURSOR)

    def _elementEnterEventCb(self, unused_actor, unused_event):
        self.show()

    def _elementLeaveEventCb(self, unused_actor, unused_event):
        self.hide()

    def _dragBeginCb(self, unused_action, unused_actor, event_x, event_y, unused_modifiers):
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y
        elem = self.timelineElement.bElement.get_parent()
        self.timelineElement.setDragged(True)

        if self.isLeft:
            edge = GES.Edge.EDGE_START
            self._dragBeginStart = self.timelineElement.bElement.get_parent(
            ).get_start()
        else:
            edge = GES.Edge.EDGE_END
            self._dragBeginStart = self.timelineElement.bElement.get_parent().get_duration() + \
                self.timelineElement.bElement.get_parent().get_start()

        self._context = EditingContext(elem,
                                       self.timelineElement.timeline.bTimeline,
                                       GES.EditMode.EDIT_TRIM,
                                       edge,
                                       None,
                                       self.timelineElement.timeline._container.app.action_log)

        self._context.connect("clip-trim", self.clipTrimCb)
        self._context.connect("clip-trim-finished", self.clipTrimFinishedCb)

    def _dragProgressCb(self, unused_action, unused_actor, delta_x, unused_delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        new_start = self._dragBeginStart + Zoomable.pixelToNs(delta_x)

        self._context.setMode(
            self.timelineElement.timeline._container.getEditionMode(isAHandle=True))
        self._context.editTo(
            new_start, self.timelineElement.bElement.get_parent().get_layer().get_priority())
        return False

    def _dragEndCb(self, unused_action, unused_actor, unused_event_x, unused_event_y, unused_modifiers):
        self.timelineElement.setDragged(False)
        self._context.finish()

        self.timelineElement.set_reactive(True)
        for elem in self.timelineElement.get_children():
            elem.set_reactive(True)

        self.set_from_file(
            os.path.join(configure.get_pixmap_dir(), "trimbar-normal.png"))
        self.timelineElement.timeline._container.embed.get_window().set_cursor(
            NORMAL_CURSOR)

    def clipTrimCb(self, unused_TrimStartContext, tl_obj, position):
        # While a clip is being trimmed, ask the viewer to preview it
        self.timelineElement.timeline._container.app.gui.viewer.clipTrimPreview(
            tl_obj, position)

    def clipTrimFinishedCb(self, unused_TrimStartContext):
        # When a clip has finished trimming, tell the viewer to reset itself
        self.timelineElement.timeline._container.app.gui.viewer.clipTrimPreviewFinished(
        )
Example #18
0
class URISourceElement(TimelineElement):
    def __init__(self, bElement, track, timeline):
        TimelineElement.__init__(self, bElement, track, timeline)

    # public API

    def hideHandles(self):
        self.rightHandle.hide()
        self.leftHandle.hide()

    # private API

    def _createGhostclip(self):
        self.ghostclip = Ghostclip(self.track_type, self.bElement)
        self.timeline.add_child(self.ghostclip)

    def _createHandles(self):
        self.leftHandle = TrimHandle(self, True)
        self.rightHandle = TrimHandle(self, False)

        self.leftHandle.set_position(0, 0)

        self.add_child(self.leftHandle)
        self.add_child(self.rightHandle)

    def _createBackground(self, track):
        if track.type == GES.TrackType.AUDIO:
            # Audio clips go from dark green to light green
            # (27, 46, 14, 255) to (73, 108, 33, 255)
            self.background = Gradient(27, 46, 14, 73, 108, 33)
        else:
            # Video clips go from almost black to gray
            # (15, 15, 15, 255) to (45, 45, 45, 255)
            self.background = Gradient(15, 15, 15, 45, 45, 45)

        self.background.bElement = self.bElement

        self.add_child(self.background)
        self.background.set_position(0, 0)

    # Callbacks
    def _clickedCb(self, action, actor):
        #TODO : Let's be more specific, masks etc ..
        self.timeline.selection.setToObj(self.bElement, SELECT)

    def _dragBeginCb(self, action, actor, event_x, event_y, modifiers):
        mode = self.timeline._container.getEditionMode()
        self._context = EditingContext(self.bElement,
                                       self.timeline.bTimeline,
                                       mode,
                                       GES.Edge.EDGE_NONE,
                                       self.timeline.selection.getSelectedTrackElements(),
                                       None)
        # This can't change during a drag, so we can safely compute it now for drag events.
        nbrLayers = len(self.timeline.bTimeline.get_layers())
        self.brother = self.timeline.findBrother(self.bElement)
        self._dragBeginStart = self.bElement.get_start()
        self.dragBeginStartX = event_x
        self.dragBeginStartY = event_y

        self.nbrLayers = nbrLayers
        self.ghostclip.setNbrLayers(nbrLayers)
        self.ghostclip.setWidth(self.props.width)
        if self.brother:
            self.brother.ghostclip.setWidth(self.props.width)
            self.brother.ghostclip.setNbrLayers(nbrLayers)

        # We can also safely find if the object has a brother element
        self.setDragged(True)

    def _dragProgressCb(self, action, actor, delta_x, delta_y):
        # We can't use delta_x here because it fluctuates weirdly.
        mode = self.timeline._container.getEditionMode()
        self._context.setMode(mode)

        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        delta_y = coords[1] - self.dragBeginStartY
        y = coords[1] + self.timeline._container.point.y
        priority = self._getLayerForY(y)
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)

        self.ghostclip.props.x = max(0, self.nsToPixel(self._dragBeginStart) + delta_x)
        self.ghostclip.update(priority, y, False)
        if self.brother:
            self.brother.ghostclip.props.x = max(0, self.nsToPixel(self._dragBeginStart) + delta_x)
            self.brother.ghostclip.update(priority, y, True)

        if not self.ghostclip.props.visible:
            self._context.editTo(new_start, self.bElement.get_parent().get_layer().get_priority())
        else:
            self._context.editTo(self._dragBeginStart, self.bElement.get_parent().get_layer().get_priority())

        self.timeline._updateSize(self.ghostclip)
        return False

    def _dragEndCb(self, action, actor, event_x, event_y, modifiers):
        coords = self.dragAction.get_motion_coords()
        delta_x = coords[0] - self.dragBeginStartX
        new_start = self._dragBeginStart + self.pixelToNs(delta_x)
        priority = self._getLayerForY(coords[1] + self.timeline._container.point.y)
        priority = min(priority, len(self.timeline.bTimeline.get_layers()))
        priority = max(0, priority)

        self.timeline._snapEndedCb()
        self.setDragged(False)

        self.ghostclip.props.visible = False
        if self.brother:
            self.brother.ghostclip.props.visible = False

        if self.ghostclip.shouldCreateLayer:
            self.timeline.insertLayer(self.ghostclip)

        self._context.editTo(new_start, priority)
        self._context.finish()

    def _selectedChangedCb(self, selected, isSelected):
        self.marquee.props.visible = isSelected