Exemple #1
0
    def render_cairo(self, cr, bounds, element, hscroll_pos, y1):
        if not self._view:
            return
        # The idea is to conceptually divide the clip into a sequence of
        # rectangles beginning at the start of the file, and
        # pixelsToNs(twidth) nanoseconds long. The thumbnail within the
        # rectangle is the frame produced from the timestamp corresponding to
        # rectangle's left edge. We speed things up by only drawing the
        # rectangles which intersect the given bounds.  FIXME: how would we
        # handle timestretch?
        height = bounds.y2 - bounds.y1
        width = bounds.x2 - bounds.x1

        # we actually draw the rectangles just to the left of the clip's in
        # point and just to the right of the clip's out-point, so we need to
        # mask off the actual bounds.
        cr.rectangle(bounds.x1, bounds.y1, width, height)
        cr.clip()

        # tdur = duration in ns of thumbnail
        # sof  = start of file in pixel coordinates
        x1 = bounds.x1
        sof = Zoomable.nsToPixel(element.get_start() - element.get_inpoint()) +\
            hscroll_pos

        # i = left edge of thumbnail to be drawn. We start with x1 and
        # subtract the distance to the nearest leftward rectangle.
        # Justification of the following:
        #                i = sof + k * twidth
        #                i = x1 - delta
        # sof + k * twidth = x1 - delta
        #           i * tw = (x1 - sof) - delta
        #    <=>     delta = x1 - sof (mod twidth).
        # Fortunately for us, % works on floats in python.

        i = x1 - ((x1 - sof) % (self.twidth + self._spacing()))

        # j = timestamp *within the element* of thumbnail to be drawn. we want
        # timestamps to be numerically stable, but in practice this seems to
        # give good enough results. It might be possible to improve this
        # further, which would result in fewer thumbnails needing to be
        # generated.
        j = Zoomable.pixelToNs(i - sof)
        istep = self.twidth + self._spacing()
        jstep = self.tdur + Zoomable.pixelToNs(self.spacing)

        while i < bounds.x2:
            self._thumbForTime(cr, j, i, y1)
            cr.rectangle(i - 1, y1, self.twidth + 2, self.theight)
            i += istep
            j += jstep
            cr.fill()
Exemple #2
0
    def zoomChanged(self):
        if self._settings and self.bTimeline:
            # zoomChanged might be called various times before the UI is ready
            self.bTimeline.props.snapping_distance = \
                Zoomable.pixelToNs(self._settings.edgeSnapDeadband)

        self.updateHScrollAdjustments()
Exemple #3
0
    def convertGhostClips(self):
        for ghostCouple in self.ghostClips:
            ghostclip = ghostCouple[0]
            if not ghostclip:
                ghostclip = ghostCouple[1]

            layer = None
            target = None

            if ghostclip.shouldCreateLayer:
                layer = self.insertLayer(ghostclip)
                target = layer
            else:
                for layer in self.bTimeline.get_layers():
                    if layer.get_priority() == ghostclip.priority:
                        target = layer
                        break

            if target is None:
                layer = self.bTimeline.append_layer()

            layer.add_asset(ghostclip.asset,
                            Zoomable.pixelToNs(ghostclip.props.x),
                            0,
                            ghostclip.asset.get_duration(),
                            ghostclip.asset.get_supported_formats())
Exemple #4
0
    def updateValue(self, delta_x, delta_y):
        newTs = self.tsStart + Zoomable.pixelToNs(delta_x)
        newValue = self.valueStart - (delta_y / EXPANDED_SIZE)

        # Don't overlap first and last keyframes.
        newTs = min(max(newTs, self.inpoint + 1), self.duration + self.inpoint - 1)

        newValue = min(max(newValue, 0.0), 1.0)

        if not self.has_changeable_time:
            newTs = self.lastTs

        self.timelineElement.source.unset(self.lastTs)
        if (self.timelineElement.source.set(newTs, newValue)):
            self.value = Gst.TimedValue()
            self.value.timestamp = newTs
            self.value.value = newValue
            self.lastTs = newTs

            self.timelineElement.setKeyframePosition(self, self.value)
            # Resort the keyframes list each time. Should be cheap as there should never be too much keyframes,
            # if optimization is needed, check if resorting is needed, should not be in 99 % of the cases.
            self.timelineElement.keyframes = sorted(self.timelineElement.keyframes, key=lambda keyframe: keyframe.value.timestamp)
            self.timelineElement.drawLines(self.line)
            # This will update the viewer. nifty.
            if not self.line:
                self.timelineElement.timeline._container.seekInPosition(newTs + self.start)
Exemple #5
0
    def updateValue(self, delta_x, delta_y):
        newTs = self.tsStart + Zoomable.pixelToNs(delta_x)
        newValue = self.valueStart - (delta_y / EXPANDED_SIZE)

        # Don't overlap first and last keyframes.
        newTs = min(max(newTs, self.inpoint + 1),
                    self.duration + self.inpoint - 1)

        newValue = min(max(newValue, 0.0), 1.0)

        if not self.has_changeable_time:
            newTs = self.lastTs

        updating = self.timelineElement.updating_keyframes
        self.timelineElement.updating_keyframes = True
        self.timelineElement.source.unset(self.lastTs)
        if (self.timelineElement.source.set(newTs, newValue)):
            self.value = Gst.TimedValue()
            self.value.timestamp = newTs
            self.value.value = newValue
            self.lastTs = newTs

            self.timelineElement.setKeyframePosition(self, self.value)
            # Resort the keyframes list each time. Should be cheap as there should never be too much keyframes,
            # if optimization is needed, check if resorting is needed, should
            # not be in 99 % of the cases.
            self.timelineElement.keyframes = sorted(
                self.timelineElement.keyframes, key=lambda keyframe: keyframe.value.timestamp)
            self.timelineElement.drawLines(self.line)
            # This will update the viewer. nifty.
            if not self.line:
                self.timelineElement.timeline._container.seekInPosition(
                    newTs + self.start)

        self.timelineElement.updating_keyframes = updating
 def _clickedCb(self, unused_actor, event):
     if self.gotDragged:
         self.gotDragged = False
         return
     x, unused_y = self.transposeXY(event.x, event.y)
     timestamp = Zoomable.pixelToNs(x)
     value = self._valueAtTimestamp(timestamp)
     self.timelineElement.addKeyframe(value, timestamp)
Exemple #7
0
 def _clickedCb(self, unused_actor, event):
     if self.gotDragged:
         self.gotDragged = False
         return
     x, unused_y = self.transposeXY(event.x, event.y)
     timestamp = Zoomable.pixelToNs(x)
     value = self._valueAtTimestamp(timestamp)
     self.timelineElement.addKeyframe(value, timestamp)
Exemple #8
0
 def _get_thumb_duration(self):
     thumb_duration_tmp = Zoomable.pixelToNs(self.thumb_width + THUMB_MARGIN_PX)
     # quantize thumb length to thumb_period
     thumb_duration = quantize(thumb_duration_tmp, self.thumb_period)
     # make sure that the thumb duration after the quantization isn't smaller than before
     if thumb_duration < thumb_duration_tmp:
         thumb_duration += self.thumb_period
     # make sure that we don't show thumbnails more often than thumb_period
     return max(thumb_duration, self.thumb_period)
Exemple #9
0
 def _get_thumb_duration(self):
     thumb_duration_tmp = Zoomable.pixelToNs(self.thumb_width + self.thumb_margin)
     # quantize thumb length to thumb_period
     thumb_duration = quantize(thumb_duration_tmp, self.thumb_period)
     # make sure that the thumb duration after the quantization isn't smaller than before
     if thumb_duration < thumb_duration_tmp:
         thumb_duration += self.thumb_period
     # make sure that we don't show thumbnails more often than thumb_period
     return max(thumb_duration, self.thumb_period)
Exemple #10
0
    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
Exemple #11
0
    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
Exemple #12
0
    def _updateScrollPosition(self, adjustment):
        self._scroll_pos_ns = Zoomable.pixelToNs(self.hadj.get_value())
        point = Clutter.Point()
        point.x = self.hadj.get_value()
        point.y = self.vadj.get_value()
        self.point = point

        self.timeline.scroll_to_point(point)
        point.x = 0
        self.controls.scroll_to_point(point)
Exemple #13
0
 def xyToTimeValue(self, pos):
     view = self._view
     interpolator = view.interpolator
     bounds = view.bounds
     time = (Zoomable.pixelToNs(pos[0] - bounds.x1) +
         view.element.in_point)
     value = ((1 - (pos[1] - KW_LABEL_Y_OVERFLOW - bounds.y1 -
         view._min) / view._range) *
             interpolator.range) + interpolator.lower
     return time, value
Exemple #14
0
 def xyToTimeValue(self, pos):
     view = self._view
     interpolator = view.interpolator
     bounds = view.bounds
     time = (Zoomable.pixelToNs(pos[0] - bounds.x1) +
         view.element.in_point)
     value = ((1 - (pos[1] - KW_LABEL_Y_OVERFLOW - bounds.y1 -
         view._min) / view._range) *
             interpolator.range) + interpolator.lower
     return time, value
Exemple #15
0
 def _clickedCb(self, actor, event):
     if self.gotDragged:
         self.gotDragged = False
         return
     x, y = self.transposeXY(event.x, event.y)
     value = 1.0 - (y / EXPANDED_SIZE)
     value = max(0.0, value)
     value = min(1.0, value)
     timestamp = Zoomable.pixelToNs(x)
     self.timelineElement.addKeyframe(value, timestamp)
Exemple #16
0
    def drag_start(self, item, target, event):
        """
            Start draging an element in the Track
        """
        self.debug("Drag started")

        if not self._view.element.selected:
            self._view.timeline.selection.setToObj(self._view.element, SELECT)

        if self.previous_x is not None:
            ratio = float(self.ref / Zoomable.pixelToNs(10000000000))
            self.previous_x = self.previous_x * ratio

        self.ref = Zoomable.pixelToNs(10000000000)
        tx = self._view.props.parent.get_simple_transform()

        # store y offset for later priority calculation
        self._y_offset = tx[4]
        # zero y component of mousdown coordiante
        self._mousedown = Point(self._mousedown[0], 0)
Exemple #17
0
 def _sliderTooltipCb(self, unused_slider, unused_x, unused_y, unused_keyboard_mode, tooltip):
     # We assume the width of the ruler is exactly the width of the timeline.
     width_px = self.timeline.ruler.get_allocated_width()
     timeline_width_ns = Zoomable.pixelToNs(width_px)
     if timeline_width_ns >= Gst.SECOND:
         # Translators: %s represents a duration, for example "10 minutes"
         tip = _("%s displayed") % beautify_length(timeline_width_ns)
     else:
         # Translators: This is a tooltip
         tip = _("%d nanoseconds displayed, because we can") % timeline_width_ns
     tooltip.set_text(tip)
     return True
Exemple #18
0
    def set_pos(self, item, pos):
        if not self._view.movable:
            return
        x, y = pos
        x = x + self._hadj.get_value()

        position = Zoomable.pixelToNs(x)
        priority = self.app.gui.timeline_ui.controls.getPriorityForY(
            y - self._y_offset + self._vadj.get_value())

        self._context.setMode(self._getMode())
        self.debug("Setting position")
        self._context.editTo(position, priority)
Exemple #19
0
    def _get_visible_timeline_range(self):
        # determine the visible left edge of the timeline
        # TODO: isn't there some easier way to get the scroll point of the ScrollActor?
        # timeline_left = -(self.timeline.get_transform().xw - self.timeline.props.x)
        timeline_left = self.timeline.get_scroll_point().x

        # determine the width of the pipeline
        # by intersecting the timeline's and the stage's allocation
        timeline_allocation = self.timeline.props.allocation
        stage_allocation = self.timeline.get_stage().props.allocation

        timeline_rect = Clutter.Rect()
        timeline_rect.init(timeline_allocation.x1,
                           timeline_allocation.y1,
                           timeline_allocation.x2 - timeline_allocation.x1,
                           timeline_allocation.y2 - timeline_allocation.y1)

        stage_rect = Clutter.Rect()
        stage_rect.init(stage_allocation.x1,
                        stage_allocation.y1,
                        stage_allocation.x2 - stage_allocation.x1,
                        stage_allocation.y2 - stage_allocation.y1)

        has_intersection, intersection = timeline_rect.intersection(stage_rect)

        if not has_intersection:
            return (0, 0)

        timeline_width = intersection.size.width

        # determine the visible right edge of the timeline
        timeline_right = timeline_left + timeline_width

        # convert to nanoseconds
        time_left = Zoomable.pixelToNs(timeline_left)
        time_right = Zoomable.pixelToNs(timeline_right)

        return (time_left, time_right)
Exemple #20
0
    def _get_visible_timeline_range(self):
        # determine the visible left edge of the timeline
        # TODO: isn't there some easier way to get the scroll point of the ScrollActor?
        # timeline_left = -(self.timeline.get_transform().xw - self.timeline.props.x)
        timeline_left = self.timeline.get_scroll_point().x

        # determine the width of the pipeline
        # by intersecting the timeline's and the stage's allocation
        timeline_allocation = self.timeline.props.allocation
        stage_allocation = self.timeline.get_stage().props.allocation

        timeline_rect = Clutter.Rect()
        timeline_rect.init(timeline_allocation.x1,
                           timeline_allocation.y1,
                           timeline_allocation.x2 - timeline_allocation.x1,
                           timeline_allocation.y2 - timeline_allocation.y1)

        stage_rect = Clutter.Rect()
        stage_rect.init(stage_allocation.x1,
                        stage_allocation.y1,
                        stage_allocation.x2 - stage_allocation.x1,
                        stage_allocation.y2 - stage_allocation.y1)

        has_intersection, intersection = timeline_rect.intersection(stage_rect)

        if not has_intersection:
            return (0, 0)

        timeline_width = intersection.size.width

        # determine the visible right edge of the timeline
        timeline_right = timeline_left + timeline_width

        # convert to nanoseconds
        time_left = Zoomable.pixelToNs(timeline_left)
        time_right = Zoomable.pixelToNs(timeline_right)

        return (time_left, time_right)
Exemple #21
0
 def _sliderTooltipCb(self, unused_slider, unused_x, unused_y, unused_keyboard_mode, tooltip):
     # We assume the width of the ruler is exactly the width of the
     # timeline.
     width_px = self.timeline.ruler.get_allocated_width()
     timeline_width_ns = Zoomable.pixelToNs(width_px)
     if timeline_width_ns >= Gst.SECOND:
         # Translators: %s represents a duration, for example "10 minutes"
         tip = _("%s displayed") % beautify_length(timeline_width_ns)
     else:
         # Translators: This is a tooltip
         tip = _(
             "%d nanoseconds displayed, because we can") % timeline_width_ns
     tooltip.set_text(tip)
     return True
Exemple #22
0
    def thumb_interval(self):
        """Gets the interval for which a thumbnail is displayed.

        Returns:
            int: a duration in nanos, multiple of THUMB_PERIOD.
        """
        interval = Zoomable.pixelToNs(self.thumb_width + THUMB_MARGIN_PX)
        # Make sure the thumb interval is a multiple of THUMB_PERIOD.
        quantized = quantize(interval, THUMB_PERIOD)
        # Make sure the quantized thumb interval fits
        # the thumb and the margin.
        if quantized < interval:
            quantized += THUMB_PERIOD
        # Make sure we don't show thumbs more often than THUMB_PERIOD.
        return max(THUMB_PERIOD, quantized)
Exemple #23
0
 def click(self, pos):
     timeline = self._view.timeline
     element = self._view.element
     if self._last_event.get_state()[1] & Gdk.ModifierType.SHIFT_MASK:
         timeline.selection.setToObj(element, SELECT_BETWEEN)
     elif self._last_event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK:
         if element.selected:
             mode = UNSELECT
         else:
             mode = SELECT_ADD
         timeline.selection.setToObj(element, mode)
     else:
         x, y = pos
         x += self._hadj.get_value()
         self._view.app.current.seeker.seek(Zoomable.pixelToNs(x))
         timeline.selection.setToObj(element, SELECT)
Exemple #24
0
    def _addVisibleThumbnails(self):
        """
        Get the thumbnails to be displayed in the currently visible clip portion
        """
        self.remove_all_children()
        old_thumbs = self.thumbs.copy()
        self.thumbs = {}
        self.wishlist = []

        thumb_duration_tmp = Zoomable.pixelToNs(self.thumb_width +
                                                self.thumb_margin)

        # quantize thumb length to thumb_period
        # TODO: replace with a call to utils.misc.quantize:
        thumb_duration = (thumb_duration_tmp //
                          self.thumb_period) * self.thumb_period
        # make sure that the thumb duration after the quantization isn't smaller than before
        if thumb_duration < thumb_duration_tmp:
            thumb_duration += self.thumb_period

        # make sure that we don't show thumbnails more often than thumb_period
        thumb_duration = max(thumb_duration, self.thumb_period)

        element_left, element_right = self._get_visible_range()
        # TODO: replace with a call to utils.misc.quantize:
        element_left = (element_left // thumb_duration) * thumb_duration

        current_time = element_left
        while current_time < element_right:
            thumb = Thumbnail(self.thumb_width, self.thumb_height)
            thumb.set_position(Zoomable.nsToPixel(current_time),
                               self.thumb_margin)
            self.add_child(thumb)
            self.thumbs[current_time] = thumb
            if current_time in self.thumb_cache:
                gdkpixbuf = self.thumb_cache[current_time]
                if self._allAnimated or current_time not in old_thumbs:
                    self.thumbs[current_time].set_from_gdkpixbuf_animated(
                        gdkpixbuf)
                else:
                    self.thumbs[current_time].set_from_gdkpixbuf(gdkpixbuf)
            else:
                self.wishlist.append(current_time)
            current_time += thumb_duration
        self._allAnimated = False
Exemple #25
0
    def _addVisibleThumbnails(self):
        """
        Get the thumbnails to be displayed in the currently visible clip portion
        """
        self.remove_all_children()
        old_thumbs = self.thumbs.copy()
        self.thumbs = {}
        self.wishlist = []

        thumb_duration_tmp = Zoomable.pixelToNs(self.thumb_width + self.thumb_margin)

        # quantize thumb length to thumb_period
        # TODO: replace with a call to utils.misc.quantize:
        thumb_duration = (thumb_duration_tmp // self.thumb_period) * self.thumb_period
        # make sure that the thumb duration after the quantization isn't smaller than before
        if thumb_duration < thumb_duration_tmp:
            thumb_duration += self.thumb_period

        # make sure that we don't show thumbnails more often than thumb_period
        thumb_duration = max(thumb_duration, self.thumb_period)

        element_left, element_right = self._get_visible_range()
        # TODO: replace with a call to utils.misc.quantize:
        element_left = (element_left // thumb_duration) * thumb_duration

        current_time = element_left
        while current_time < element_right:
            thumb = Thumbnail(self.thumb_width, self.thumb_height)
            thumb.set_position(Zoomable.nsToPixel(current_time), self.thumb_margin)
            self.add_child(thumb)
            self.thumbs[current_time] = thumb
            if current_time in self.thumb_cache:
                gdkpixbuf = self.thumb_cache[current_time]
                if self._allAnimated or current_time not in old_thumbs:
                    self.thumbs[current_time].set_from_gdkpixbuf_animated(gdkpixbuf)
                else:
                    self.thumbs[current_time].set_from_gdkpixbuf(gdkpixbuf)
            else:
                self.wishlist.append(current_time)
            current_time += thumb_duration
        self._allAnimated = False
Exemple #26
0
    def _setBestZoomRatio(self):
        """
        Set the zoom level so that the entire timeline is in view.
        """
        ruler_width = self.ruler.get_allocation().width
        # Add Gst.SECOND - 1 to the timeline duration to make sure the
        # last second of the timeline will be in view.
        duration = self.timeline.bTimeline.get_duration()
        if duration == 0:
            return

        timeline_duration = duration + Gst.SECOND - 1
        timeline_duration_s = int(timeline_duration / Gst.SECOND)

        ideal_zoom_ratio = float(ruler_width) / timeline_duration_s
        nearest_zoom_level = Zoomable.computeZoomLevel(ideal_zoom_ratio)
        Zoomable.setZoomLevel(nearest_zoom_level)
        self.timeline.bTimeline.props.snapping_distance = \
            Zoomable.pixelToNs(self.app.settings.edgeSnapDeadband)

        # Only do this at the very end, after updating the other widgets.
        self.zoomed_fitted = True
Exemple #27
0
 def _dragDropCb(self, widget, context, x, y, time):
     target = widget.drag_dest_find_target(context, None)
     y -= self.ruler.get_allocation().height
     if target.name() == "text/uri-list":
         self.dropOccured = True
         widget.drag_get_data(context, target, time)
         if self.isDraggedClip:
             self.timeline.convertGhostClips()
             self.timeline.resetGhostClips()
             if self.zoomed_fitted:
                 self._setBestZoomRatio()
             else:
                 x, y = self._transposeXY(x, y)
                 self.scrollToPosition(Zoomable.pixelToNs(x))
         else:
             actor = self.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y)
             try:
                 bElement = actor.bElement
                 self.app.gui.clipconfig.effect_expander.addEffectToClip(bElement.get_parent(), self.dropData[0])
             except AttributeError:
                 return False
         return True
     else:
         return False
Exemple #28
0
 def _snapDistanceChangedCb(self, settings):
     if self.bTimeline:
         self.bTimeline.props.snapping_distance = \
             Zoomable.pixelToNs(settings.edgeSnapDeadband)
Exemple #29
0
 def tdur(self):
     return Zoomable.pixelToNs(self.twidth)
    def check_keyframe_ui_toggle(self, ges_clip, timeline_container):
        """Checks keyframes toggling by click events."""
        timeline = timeline_container.timeline

        start = ges_clip.props.start
        start_px = Zoomable.nsToPixel(start)
        inpoint = ges_clip.props.in_point
        duration = ges_clip.props.duration
        duration_px = Zoomable.nsToPixel(duration)
        offsets_px = (1, int(duration_px / 2), int(duration_px) - 1)
        timeline.selection.select([ges_clip])

        ges_video_source = ges_clip.find_track_element(None, GES.VideoSource)
        binding = ges_video_source.get_control_binding("alpha")
        control_source = binding.props.control_source
        keyframe_curve = ges_video_source.ui.keyframe_curve

        values = [item.timestamp for item in control_source.get_all()]
        self.assertEqual(values, [inpoint, inpoint + duration])

        # Add keyframes by simulating mouse clicks.
        for offset_px in offsets_px:
            offset = Zoomable.pixelToNs(start_px + offset_px) - start
            xdata, ydata = inpoint + offset, 1
            x, y = keyframe_curve._ax.transData.transform((xdata, ydata))

            event = MouseEvent(
                name="button_press_event",
                canvas=keyframe_curve,
                x=x,
                y=y,
                button=1
            )
            keyframe_curve.translate_coordinates = \
                mock.Mock(return_value=(start_px+offset_px, None))

            with mock.patch.object(Gtk, "get_event_widget") as get_event_widget:
                get_event_widget.return_value = keyframe_curve
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_PRESS)
                keyframe_curve._mpl_button_press_event_cb(event)
                event.name = "button_release_event"
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_RELEASE)
                keyframe_curve._mpl_button_release_event_cb(event)

            values = [item.timestamp for item in control_source.get_all()]
            self.assertIn(inpoint + offset, values)

        # Remove keyframes by simulating mouse double-clicks.
        for offset_px in offsets_px:
            offset = Zoomable.pixelToNs(start_px + offset_px) - start
            xdata, ydata = inpoint + offset, 1
            x, y = keyframe_curve._ax.transData.transform((xdata, ydata))

            event = MouseEvent(
                name="button_press_event",
                canvas=keyframe_curve,
                x=x,
                y=y,
                button=1
            )
            keyframe_curve.translate_coordinates = \
                mock.Mock(return_value=(start_px + offset_px, None))
            with mock.patch.object(Gtk, "get_event_widget") as get_event_widget:
                get_event_widget.return_value = keyframe_curve
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_PRESS)
                keyframe_curve._mpl_button_press_event_cb(event)
                event.name = "button_release_event"
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_RELEASE)
                keyframe_curve._mpl_button_release_event_cb(event)
                event.name = "button_press_event"
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_PRESS)
                keyframe_curve._mpl_button_press_event_cb(event)
                event.guiEvent = Gdk.Event.new(Gdk.EventType._2BUTTON_PRESS)
                keyframe_curve._mpl_button_press_event_cb(event)
                event.name = "button_release_event"
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_RELEASE)
                keyframe_curve._mpl_button_release_event_cb(event)

            values = [item.timestamp for item in control_source.get_all()]
            self.assertNotIn(inpoint + offset, values)
Exemple #31
0
    def check_keyframe_ui_toggle(self, ges_clip, timeline_container):
        """Checks keyframes toggling by click events."""
        timeline = timeline_container.timeline

        start = ges_clip.props.start
        start_px = Zoomable.nsToPixel(start)
        inpoint = ges_clip.props.in_point
        duration = ges_clip.props.duration
        duration_px = Zoomable.nsToPixel(duration)
        offsets_px = (1, int(duration_px / 2), int(duration_px) - 1)
        timeline.selection.select([ges_clip])

        ges_video_source = ges_clip.find_track_element(None, GES.VideoSource)
        binding = ges_video_source.get_control_binding("alpha")
        control_source = binding.props.control_source
        keyframe_curve = ges_video_source.ui.keyframe_curve

        values = [item.timestamp for item in control_source.get_all()]
        self.assertEqual(values, [inpoint, inpoint + duration])

        # Add keyframes by simulating mouse clicks.
        for offset_px in offsets_px:
            offset = Zoomable.pixelToNs(start_px + offset_px) - start
            xdata, ydata = inpoint + offset, 1
            x, y = keyframe_curve._ax.transData.transform((xdata, ydata))

            event = MouseEvent(name="button_press_event",
                               canvas=keyframe_curve,
                               x=x,
                               y=y,
                               button=1)
            keyframe_curve.translate_coordinates = \
                mock.Mock(return_value=(start_px + offset_px, None))

            with mock.patch.object(Gtk,
                                   "get_event_widget") as get_event_widget:
                get_event_widget.return_value = keyframe_curve
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_PRESS)
                keyframe_curve._mpl_button_press_event_cb(event)
                event.name = "button_release_event"
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_RELEASE)
                keyframe_curve._mpl_button_release_event_cb(event)

            values = [item.timestamp for item in control_source.get_all()]
            self.assertIn(inpoint + offset, values)

        # Remove keyframes by simulating mouse double-clicks.
        for offset_px in offsets_px:
            offset = Zoomable.pixelToNs(start_px + offset_px) - start
            xdata, ydata = inpoint + offset, 1
            x, y = keyframe_curve._ax.transData.transform((xdata, ydata))

            event = MouseEvent(name="button_press_event",
                               canvas=keyframe_curve,
                               x=x,
                               y=y,
                               button=1)
            keyframe_curve.translate_coordinates = \
                mock.Mock(return_value=(start_px + offset_px, None))
            with mock.patch.object(Gtk,
                                   "get_event_widget") as get_event_widget:
                get_event_widget.return_value = keyframe_curve
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_PRESS)
                keyframe_curve._mpl_button_press_event_cb(event)
                event.name = "button_release_event"
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_RELEASE)
                keyframe_curve._mpl_button_release_event_cb(event)
                event.name = "button_press_event"
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_PRESS)
                keyframe_curve._mpl_button_press_event_cb(event)
                event.guiEvent = Gdk.Event.new(Gdk.EventType._2BUTTON_PRESS)
                keyframe_curve._mpl_button_press_event_cb(event)
                event.name = "button_release_event"
                event.guiEvent = Gdk.Event.new(Gdk.EventType.BUTTON_RELEASE)
                keyframe_curve._mpl_button_release_event_cb(event)

            values = [item.timestamp for item in control_source.get_all()]
            self.assertNotIn(inpoint + offset, values)