def _addVisibleThumbnails(self, rect): """Gets the thumbnails for the currently visible clip portion.""" if self.thumb_width is None: return False self.thumbs = {} self.wishlist = [] thumb_duration = self._get_thumb_duration() element_left = self.pixelToNs(rect.x) + self.ges_elem.props.in_point element_right = element_left + self.pixelToNs(rect.width) element_left = quantize(element_left, thumb_duration) for current_time in range(element_left, element_right, thumb_duration): thumb = Thumbnail(self.thumb_width, self.thumb_height) x = Zoomable.nsToPixel(current_time) - self.nsToPixel(self.ges_elem.props.in_point) y = (self.props.height_request - self.thumb_height) / 2 self.put(thumb, x, y) self.thumbs[current_time] = thumb if self.__image_pixbuf: thumb.set_from_pixbuf(self.__image_pixbuf) thumb.set_visible(True) elif current_time in self.thumb_cache: pixbuf = self.thumb_cache[current_time] thumb.set_from_pixbuf(pixbuf) thumb.set_visible(True) else: self.wishlist.append(current_time) return True
def _addVisibleThumbnails(self, rect): """Gets the thumbnails for the currently visible clip portion.""" if self.thumb_width is None: return False self.thumbs = {} self.wishlist = [] thumb_duration = self._get_thumb_duration() element_left = self.pixelToNs(rect.x) + self.ges_elem.props.in_point element_right = element_left + self.pixelToNs(rect.width) element_left = quantize(element_left, thumb_duration) for current_time in range(element_left, element_right, thumb_duration): thumb = Thumbnail(self.thumb_width, self.thumb_height) x = Zoomable.nsToPixel(current_time) - self.nsToPixel( self.ges_elem.props.in_point) y = (self.props.height_request - self.thumb_height) / 2 self.put(thumb, x, y) self.thumbs[current_time] = thumb if self.__image_pixbuf: thumb.set_from_pixbuf(self.__image_pixbuf) thumb.set_visible(True) elif current_time in self.thumb_cache: pixbuf = self.thumb_cache[current_time] thumb.set_from_pixbuf(pixbuf) thumb.set_visible(True) else: self.wishlist.append(current_time) return True
def do_simple_update(self, cr): cr.identity_matrix() if issubclass(self.previewer.__class__, RandomAccessPreviewer): border_width = self.previewer._spacing() self.bounds = goocanvas.Bounds(border_width, 4, max(0, Zoomable.nsToPixel(self.element.get_duration()) - border_width), self.height)
def _addVisibleThumbnails(self): """ Get the thumbnails to be displayed in the currently visible clip portion """ self.remove_all_children() old_thumbs = self.thumbs self.thumbs = {} self.wishlist = [] thumb_duration = self._get_thumb_duration() element_left, element_right = self._get_visible_range() element_left = quantize(element_left, thumb_duration) for current_time in range(element_left, element_right, thumb_duration): thumb = Thumbnail(self.thumb_width, self.thumb_height) thumb.set_position(Zoomable.nsToPixel(current_time), THUMB_MARGIN_PX) 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) self._allAnimated = False
def _addVisibleThumbnails(self): """ Get the thumbnails to be displayed in the currently visible clip portion """ self.remove_all_children() old_thumbs = self.thumbs self.thumbs = {} self.wishlist = [] thumb_duration = self._get_thumb_duration() element_left, element_right = self._get_visible_range() element_left = quantize(element_left, thumb_duration) for current_time in range(element_left, element_right, thumb_duration): 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) self._allAnimated = False
def _createGhostclip(self, trackType, asset): ghostclip = Ghostclip(trackType) ghostclip.asset = asset ghostclip.setNbrLayers(len(self.bTimeline.get_layers())) ghostclip.setWidth(Zoomable.nsToPixel(asset.get_duration())) self.add_child(ghostclip) return ghostclip
def _update_thumbnails(self): """Updates the thumbnail widgets for the clip at the current zoom.""" if not self.thumb_width: # The __image_pixbuf is not ready yet. return thumbs = {} interval = self.thumb_interval(self.thumb_width) element_left = quantize(self.ges_elem.props.in_point, interval) element_right = self.ges_elem.props.in_point + self.ges_elem.props.duration y = (self.props.height_request - self.thumb_height) / 2 for position in range(element_left, element_right, interval): x = Zoomable.nsToPixel(position) - self.nsToPixel( self.ges_elem.props.in_point) try: thumb = self.thumbs.pop(position) self.move(thumb, x, y) except KeyError: thumb = Thumbnail(self.thumb_width, self.thumb_height) self.put(thumb, x, y) thumbs[position] = thumb thumb.set_from_pixbuf(self.__image_pixbuf) thumb.set_visible(True) for thumb in self.thumbs.values(): self.remove(thumb) self.thumbs = thumbs
def _startThumbnailing(self): if not self.pipeline: # Can happen if stopGeneration is called because the clip has been # removed from the timeline after the PreviewGeneratorManager # started this job. return self.debug('Now generating thumbnails for: %s', filename_from_uri(self.uri)) query_success, duration = self.pipeline.query_duration(Gst.Format.TIME) if not query_success or duration == -1: self.debug("Could not determine duration of: %s", self.uri) duration = self.duration else: self.duration = duration self.queue = list(range(0, duration, self.thumb_period)) self._checkCPU() if self.bElement.props.in_point != 0: position = Clutter.Point() position.x = Zoomable.nsToPixel(self.bElement.props.in_point) self.scroll_to_point(position) self._addVisibleThumbnails() # Save periodically to avoid the common situation where the user exits # the app before a long clip has been fully thumbnailed. # Spread timeouts between 30-80 secs to avoid concurrent disk writes. random_time = randrange(30, 80) GLib.timeout_add_seconds(random_time, self._autosave) # Remove the GSource return False
def _addVisibleThumbnails(self, rect): """ Get the thumbnails to be displayed in the currently visible clip portion """ if self.thumb_width is None: return False self.thumbs = {} self.wishlist = [] thumb_duration = self._get_thumb_duration() element_left = self.pixelToNs(rect.x) + self.bElement.props.in_point element_right = element_left + self.bElement.props.duration element_left = quantize(element_left, thumb_duration) for current_time in range(element_left, element_right, thumb_duration): thumb = Thumbnail(self.thumb_width, self.thumb_height) self.put(thumb, Zoomable.nsToPixel(current_time) - self.nsToPixel(self.bElement.props.in_point), (self.props.height_request - self.thumb_height) / 2) self.thumbs[current_time] = thumb if current_time in self.thumb_cache: gdkpixbuf = self.thumb_cache[current_time] self.thumbs[current_time].set_from_pixbuf(gdkpixbuf) self.thumbs[current_time].set_visible(True) else: self.wishlist.append(current_time) return True
def _startThumbnailing(self): if not self.pipeline: # Can happen if stopGeneration is called because the clip has been # removed from the timeline after the PreviewGeneratorManager # started this job. return # self.props.width_request = self.nsToPixel(self.ges_elem.get_asset().get_filesource_asset().props.duration) # self.props.width = self.nsToPixel(self.ges_elem.get_asset().get_filesource_asset().props.duration) self.debug( 'Now generating thumbnails for: %s', filename_from_uri(self.uri)) query_success, duration = self.pipeline.query_duration(Gst.Format.TIME) if not query_success or duration == -1: self.debug("Could not determine duration of: %s", self.uri) duration = self.ges_elem.props.duration self.queue = list(range(0, duration, self.thumb_period)) self._checkCPU() if self.ges_elem.props.in_point != 0: adj = self.get_hadjustment() adj.props.page_size = 1.0 adj.props.value = Zoomable.nsToPixel(self.ges_elem.props.in_point) # self._addVisibleThumbnails() # Save periodically to avoid the common situation where the user exits # the app before a long clip has been fully thumbnailed. # Spread timeouts between 30-80 secs to avoid concurrent disk writes. random_time = random.randrange(30, 80) GLib.timeout_add_seconds(random_time, self._autosave) # Remove the GSource return False
def do_draw(self, cr): if self._changed: self._children.sort(key=lambda clip: clip.z_order) for child in self._children: if isinstance(child, elements.TransitionClip): window = child.get_window() window.raise_() self._changed = False self.props.width = max(self.timeline.layout.get_allocation().width, Zoomable.nsToPixel(self.timeline.ges_timeline.props.duration)) self.props.width_request = max(self.timeline.layout.get_allocation().width, Zoomable.nsToPixel(self.timeline.ges_timeline.props.duration)) for child in self._children: self.propagate_draw(child, cr)
def do_simple_update(self, cr): cr.identity_matrix() if issubclass(self.previewer.__class__, RandomAccessPreviewer): border_width = self.previewer._spacing() self.boundz = GooCanvas.CanvasBounds() self.boundz.x1 = border_width self.boundz.x2 = max(0, Zoomable.nsToPixel(self.element.get_duration())) self.boundz.y1 = 4 self.boundz.y2 = self.height
def _snapCb(self, unused_timeline, obj1, obj2, position): """ Display or hide a snapping indicator line """ if position == 0: self._snapEndedCb() else: height = len(self.bTimeline.get_layers()) * (EXPANDED_SIZE + SPACING) * 2 self._snap_indicator.props.height = height self._snap_indicator.props.x = Zoomable.nsToPixel(position) self._snap_indicator.props.visible = True
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()
def _scrollToPlayhead(self): #self.ruler._maybeUpdate() if self.ruler.pressed or self.pressed: self.pressed = False return canvas_size = self.embed.get_allocation().width - CONTROL_WIDTH try: new_pos = Zoomable.nsToPixel(self.app.current.pipeline.getPosition()) except PipelineError: return except AttributeError: # Standalone, no pipeline. return scroll_pos = self.hadj.get_value() self.scrollToPosition(min(new_pos - canvas_size / 2, self.hadj.props.upper - canvas_size - 1))
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
def __init__(self, instance, element, track, timeline, utrack): goocanvas.Group.__init__(self) View.__init__(self, instance) Zoomable.__init__(self) Loggable.__init__(self) self.ref = Zoomable.nsToPixel(10000000000) self.app = instance self.track = track self.utrack = utrack self.timeline = timeline self.namewidth = 0 self.nameheight = 0 self._element = None self._settings = None self.movable = True self.bg = goocanvas.Rect(height=self.height, line_width=1) self.name = goocanvas.Text( x=NAME_HOFFSET + NAME_PADDING, y=NAME_VOFFSET + NAME_PADDING, operator=cairo.OPERATOR_ADD, alignment=pango.ALIGN_LEFT) self.namebg = goocanvas.Rect( radius_x=2, radius_y=2, x=NAME_HOFFSET, y=NAME_VOFFSET, line_width=0) self.start_handle = StartHandle(self.app, element, timeline, height=self.height) self.end_handle = EndHandle(self.app, element, timeline, height=self.height) self._selec_indic = goocanvas.Rect( visibility=goocanvas.ITEM_INVISIBLE, line_width=0.0, height=self.height) self.element = element element.selected = Selected() element.selected.connect("selected-changed", self.selectedChangedCb) obj = self.element.get_timeline_object() self.settings = instance.settings self.unfocus()
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
def _update_thumbnails(self): """Updates the thumbnail widgets for the clip at the current zoom.""" if not self.thumb_width: # The thumb_width will be available when pipeline has been started # or the __image_pixbuf is ready. return thumbs = {} queue = [] interval = self.thumb_interval element_left = quantize(self.ges_elem.props.in_point, interval) element_right = self.ges_elem.props.in_point + self.ges_elem.props.duration y = (self.props.height_request - self.thumb_height) / 2 for position in range(element_left, element_right, interval): x = Zoomable.nsToPixel(position) - self.nsToPixel( self.ges_elem.props.in_point) try: thumb = self.thumbs.pop(position) self.move(thumb, x, y) except KeyError: thumb = Thumbnail(self.thumb_width, self.thumb_height) self.put(thumb, x, y) thumbs[position] = thumb if isinstance(self.ges_elem, GES.ImageSource): thumb.set_from_pixbuf(self.__image_pixbuf) thumb.set_visible(True) elif position in self.thumb_cache: pixbuf = self.thumb_cache[position] thumb.set_from_pixbuf(pixbuf) thumb.set_visible(True) else: if position not in self.failures and position != self.position: queue.append(position) for thumb in self.thumbs.values(): self.remove(thumb) self.thumbs = thumbs self.queue = queue if queue: self.become_controlled()
def updateHScrollAdjustments(self): """ Recalculate the horizontal scrollbar depending on the timeline duration. """ timeline_ui_width = self.embed.get_allocation().width controls_width = 0 scrollbar_width = 0 contents_size = Zoomable.nsToPixel(self.bTimeline.props.duration) widgets_width = controls_width + scrollbar_width end_padding = CONTROL_WIDTH + 250 # Provide some space for clip insertion at the end self.hadj.props.lower = 0 self.hadj.props.upper = contents_size + widgets_width + end_padding self.hadj.props.page_size = timeline_ui_width self.hadj.props.page_increment = contents_size * 0.9 self.hadj.props.step_increment = contents_size * 0.1 if contents_size + widgets_width <= timeline_ui_width: # We're zoomed out completely, re-enable automatic zoom fitting # when adding new clips. self.zoomed_fitted = True
def _update_thumbnails(self): """Updates the thumbnails for the currently visible clip portion.""" if self.thumb_width is None: return False thumbs = {} self.wishlist = [] thumb_duration = self._get_thumb_duration() element_left = quantize(self.ges_elem.props.in_point, thumb_duration) element_right = self.ges_elem.props.in_point + self.ges_elem.props.duration for position in range(element_left, element_right, thumb_duration): x = Zoomable.nsToPixel(position) - self.nsToPixel( self.ges_elem.props.in_point) y = (self.props.height_request - self.thumb_height) / 2 try: thumb = self.thumbs.pop(position) self.move(thumb, x, y) except KeyError: thumb = Thumbnail(self.thumb_width, self.thumb_height) self.put(thumb, x, y) thumbs[position] = thumb if self.__image_pixbuf: # The thumbnail is fixed, probably it's an image clip. thumb.set_from_pixbuf(self.__image_pixbuf) thumb.set_visible(True) elif position in self.thumb_cache: pixbuf = self.thumb_cache[position] thumb.set_from_pixbuf(pixbuf) thumb.set_visible(True) else: self.wishlist.append(position) for thumb in self.thumbs.values(): self.remove(thumb) self.thumbs = thumbs return True
def _update_thumbnails(self): """Updates the thumbnails for the currently visible clip portion.""" if self.thumb_width is None: return False thumbs = {} self.wishlist = [] thumb_duration = self._get_thumb_duration() element_left = quantize(self.ges_elem.props.in_point, thumb_duration) element_right = self.ges_elem.props.in_point + self.ges_elem.props.duration for position in range(element_left, element_right, thumb_duration): x = Zoomable.nsToPixel(position) - self.nsToPixel(self.ges_elem.props.in_point) y = (self.props.height_request - self.thumb_height) / 2 try: thumb = self.thumbs.pop(position) self.move(thumb, x, y) except KeyError: thumb = Thumbnail(self.thumb_width, self.thumb_height) self.put(thumb, x, y) thumbs[position] = thumb if self.__image_pixbuf: # The thumbnail is fixed, probably it's an image clip. thumb.set_from_pixbuf(self.__image_pixbuf) thumb.set_visible(True) elif position in self.thumb_cache: pixbuf = self.thumb_cache[position] thumb.set_from_pixbuf(pixbuf) thumb.set_visible(True) else: self.wishlist.append(position) for thumb in self.thumbs.values(): self.remove(thumb) self.thumbs = thumbs return True
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)
def _inpointChangedCb(self, unused_bElement, unused_value): position = Clutter.Point() position.x = Zoomable.nsToPixel(self.bElement.props.in_point) self.scroll_to_point(position) self._update()
def transposeXY(self, x, y): x -= self.timelineElement.props.x + CONTROL_WIDTH - \ self.timelineElement.timeline._scroll_point.x x += Zoomable.nsToPixel(self.timelineElement.bElement.props.in_point) y -= self.timelineElement.props.y return x, y
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)
def twidth(self): return Zoomable.nsToPixel(self.tdur)
def _inpointChangedCb(self, unused_b_element, unused_value): self.get_hadjustment().set_value( Zoomable.nsToPixel(self.ges_elem.props.in_point))
def _inpointChangedCb(self, unused_b_element, unused_value): self.get_hadjustment().set_value(Zoomable.nsToPixel( self.ges_elem.props.in_point))