def _drawTime(self, context, current, previous, millis): hour = int(current[0]) for index, (element, previous_element) in enumerate(zip(current, previous)): if index <= 1 and not hour: # Don't draw hour if 0. continue if millis: # Draw only the millis. if index < 5: continue else: # Don't draw the millis. if index == 5: break if element == previous_element: color = self._color_dimmed else: color = self._color_normal set_cairo_color(context, color) # Display the millis with a smaller font. small = index >= 5 if small: context.set_font_size(SMALL_FONT_SIZE) context.show_text(element) if small: context.set_font_size(NORMAL_FONT_SIZE)
def drawPosition(self, context): """Draws the top part of the playhead. This should be in sync with the playhead drawn by the timeline. See Timeline.__draw_playhead(). """ height = self.pixbuf.get_height() semi_width = 4 semi_height = int(semi_width * 1.61803) y = int(3 * height / 4) # Add 0.5 so that the line center is at the middle of the pixel, # without this the line appears blurry. xpos = self.nsToPixel(self.position) - self.pixbuf_offset + 0.5 set_cairo_color(context, PLAYHEAD_COLOR) context.set_line_width(PLAYHEAD_WIDTH) context.move_to(xpos, y) context.line_to(xpos, height) context.stroke() context.set_line_width(PLAYHEAD_WIDTH * 2) context.move_to(xpos, y) context.line_to(xpos + semi_width, y - semi_height) context.line_to(xpos, y - semi_height * 2) context.line_to(xpos - semi_width, y - semi_height) context.close_path() context.stroke()
def drawFrameBoundaries(self, context): """Draws the alternating rectangles that represent the project frames. These are drawn only at high zoom levels. These are based on the project's framerate settings, not the actual frames on the assets. """ frame_width = self.nsToPixel(self.ns_per_frame) if not frame_width >= FRAME_MIN_WIDTH_PIXELS: return offset = self.pixbuf_offset % frame_width height = context.get_target().get_height() y = int(height - FRAME_HEIGHT_PIXELS) frame_num = int( self.pixelToNs(self.pixbuf_offset) * float(self.frame_rate) / Gst.SECOND) paintpos = self.pixbuf_offset - offset max_pos = context.get_target().get_width() + self.pixbuf_offset while paintpos < max_pos: paintpos = self.nsToPixel(1 / float(self.frame_rate) * Gst.SECOND * frame_num) if frame_num % 2: set_cairo_color(context, self._color_frame) context.rectangle(0.5 + paintpos - self.pixbuf_offset, y, frame_width, height) context.fill() frame_num += 1
def drawTimes(self, context, offset, spacing, interval_seconds): # figure out what the optimal offset is interval = int(Gst.SECOND * interval_seconds) current_time = self.pixelToNs(self.pixbuf_offset) paintpos = TIMES_LEFT_MARGIN_PIXELS if offset > 0: current_time = current_time - (current_time % interval) + interval paintpos += spacing - offset set_cairo_color(context, self._color_normal) y_bearing = context.text_extents("0")[1] def split(x): # Seven elements: h : mm : ss . mmm # Using negative indices because the first element (hour) # can have a variable length. return x[:-10], x[-10], x[-9:-7], x[-7], x[-6:-4], x[-4], x[-3:] previous = split(time_to_string(max(0, current_time - interval))) width = context.get_target().get_width() while paintpos < width: context.move_to(int(paintpos), 1 - y_bearing) current = split(time_to_string(int(current_time))) millis = current_time % Gst.SECOND > 0 self._drawTime(context, current, previous, millis) previous = current paintpos += spacing current_time += interval
def drawFrameBoundaries(self, context): """ Draw the alternating rectangles that represent the project frames at high zoom levels. These are based on the framerate set in the project settings, not the actual frames on a video codec level. """ frame_width = self.nsToPixel(self.ns_per_frame) if not frame_width >= FRAME_MIN_WIDTH_PIXELS: return offset = self.pixbuf_offset % frame_width height = context.get_target().get_height() y = int(height - FRAME_HEIGHT_PIXELS) frame_num = int( self.pixelToNs(self.pixbuf_offset) * float(self.frame_rate) / Gst.SECOND) paintpos = self.pixbuf_offset - offset max_pos = context.get_target().get_width() + self.pixbuf_offset while paintpos < max_pos: paintpos = self.nsToPixel( 1 / float(self.frame_rate) * Gst.SECOND * frame_num) if frame_num % 2: set_cairo_color(context, self._color_frame) context.rectangle( 0.5 + paintpos - self.pixbuf_offset, y, frame_width, height) context.fill() frame_num += 1
def draw_frame_boundaries(self, context): """Draws the alternating rectangles that represent the project frames. These are drawn only at high zoom levels. These are based on the project's framerate settings, not the actual frames on the assets. """ if not self.ges_timeline: # Timeline not set yet return frame_width = self.zoom.ns_to_pixel( self.ges_timeline.get_frame_time(1)) if frame_width < FRAME_MIN_WIDTH_PIXELS: return offset = self.pixbuf_offset % frame_width height = context.get_target().get_height() y = int(height - FRAME_HEIGHT_PIXELS) frame_num = self.ges_timeline.get_frame_at( self.zoom.pixel_to_ns(self.pixbuf_offset)) paintpos = self.pixbuf_offset - offset max_pos = context.get_target().get_width() + self.pixbuf_offset while paintpos < max_pos: paintpos = self.zoom.ns_to_pixel( self.ges_timeline.get_frame_time(frame_num)) if frame_num % 2: set_cairo_color(context, self._color_frame) context.rectangle(0.5 + paintpos - self.pixbuf_offset, y, frame_width, height) context.fill() frame_num += 1
def drawFrameBoundaries(self, context): """ Draw the alternating rectangles that represent the project frames at high zoom levels. These are based on the framerate set in the project settings, not the actual frames on a video codec level. """ frame_width = self.nsToPixel(self.ns_per_frame) if not frame_width >= FRAME_MIN_WIDTH_PIXELS: return offset = self.pixbuf_offset % frame_width height = context.get_target().get_height() y = int(height - FRAME_HEIGHT_PIXELS) # INSENSITIVE is a dark shade of gray, but lacks contrast # SELECTED will be bright blue and more visible to represent frames style = self.get_style_context() states = [ style.get_background_color(Gtk.StateFlags.ACTIVE), style.get_background_color(Gtk.StateFlags.SELECTED) ] frame_num = int( self.pixelToNs(self.pixbuf_offset) * float(self.frame_rate) / Gst.SECOND) paintpos = self.pixbuf_offset - offset max_pos = context.get_target().get_width() + self.pixbuf_offset while paintpos < max_pos: paintpos = self.nsToPixel(1 / float(self.frame_rate) * Gst.SECOND * frame_num) set_cairo_color(context, states[(frame_num + 1) % 2]) context.rectangle(0.5 + paintpos - self.pixbuf_offset, y, frame_width, height) context.fill() frame_num += 1
def drawFrameBoundaries(self, context): """ Draw the alternating rectangles that represent the project frames at high zoom levels. These are based on the framerate set in the project settings, not the actual frames on a video codec level. """ frame_width = self.nsToPixel(self.ns_per_frame) if not frame_width >= FRAME_MIN_WIDTH_PIXELS: return offset = self.pixbuf_offset % frame_width height = context.get_target().get_height() y = int(height - FRAME_HEIGHT_PIXELS) # INSENSITIVE is a dark shade of gray, but lacks contrast # SELECTED will be bright blue and more visible to represent frames style = self.get_style_context() states = [style.get_background_color(Gtk.StateFlags.ACTIVE), style.get_background_color(Gtk.StateFlags.SELECTED)] frame_num = int(self.pixelToNs(self.pixbuf_offset) * float(self.frame_rate) / Gst.SECOND) paintpos = self.pixbuf_offset - offset max_pos = context.get_target().get_width() + self.pixbuf_offset while paintpos < max_pos: paintpos = self.nsToPixel(1 / float(self.frame_rate) * Gst.SECOND * frame_num) set_cairo_color(context, states[(frame_num + 1) % 2]) context.rectangle(0.5 + paintpos - self.pixbuf_offset, y, frame_width, height) context.fill() frame_num += 1
def drawPosition(self, context): # Add 0.5 so that the line center is at the middle of the pixel, # without this the line appears blurry. xpos = self.nsToPixel(self.position) - self.pixbuf_offset + 0.5 context.set_line_width(PLAYHEAD_WIDTH + 2) set_cairo_color(context, PLAYHEAD_COLOR) context.move_to(xpos, 0) context.line_to(xpos, context.get_target().get_height()) context.stroke()
def drawTicks(self, context, offset, spacing): for count_per_interval, height_ratio in TICK_TYPES: space = float(spacing) / count_per_interval if space < MIN_TICK_SPACING_PIXELS: break paintpos = 0.5 - offset set_cairo_color(context, self._color_normal) while paintpos < context.get_target().get_width(): self._drawTick(context, paintpos, height_ratio) paintpos += space
def drawTicks(self, context, offset, spacing, interval_seconds, ticks): for tick_interval, height_ratio in ticks: count_per_interval = interval_seconds / tick_interval space = spacing / count_per_interval if space < MIN_TICK_SPACING_PIXELS: break paintpos = 0.5 - offset set_cairo_color(context, self._color_normal) while paintpos < context.get_target().get_width(): self._drawTick(context, paintpos, height_ratio) paintpos += space
def drawBackground(self, context): style = self.get_style_context() set_cairo_color(context, self._background_color) width = context.get_target().get_width() height = context.get_target().get_height() context.rectangle(0, 0, width, height) context.fill() offset = int(self.nsToPixel(Gst.CLOCK_TIME_NONE)) - self.pixbuf_offset if offset > 0: set_cairo_color(context, style.get_background_color(Gtk.StateFlags.ACTIVE)) context.rectangle(0, 0, int(offset), context.get_target().get_height()) context.fill()
def drawPosition(self, context): height = self.pixbuf.get_height() # Add 0.5 so that the line center is at the middle of the pixel, # without this the line appears blurry. xpos = self.nsToPixel(self.position) - self.pixbuf_offset + 0.5 context.set_line_width(PLAYHEAD_WIDTH) set_cairo_color(context, (255, 0, 0)) context.move_to(xpos, height / 2) context.line_to(xpos, height) context.stroke() playhead_width = self.playhead_pixbuf.props.width playhead_height = self.playhead_pixbuf.props.height xpos -= playhead_width / 2 ypos = (height - playhead_height) / 2 Gdk.cairo_set_source_pixbuf(context, self.playhead_pixbuf, xpos, ypos) context.rectangle(xpos, ypos, playhead_width, playhead_height) context.fill()