def __init__(self, meters_count): w = SLOT_W * meters_count h = METER_SLOT_H self.widget = CairoDrawableArea(w, h, self._draw) self.audio_meters = [] # displays both l_Value and r_value for i in range(0, meters_count): meter = AudioMeter(METER_HEIGHT) if i != meters_count - 1: meter.right_channel.draw_dB = True self.audio_meters.append(meter)
def __init__(self): self.meter = AudioMeter(METER_HEIGHT + 40) self.meter.x_pad_l = 6 self.meter.x_pad_r = 14 self.meter.right_channel.draw_dB = True self.meter.right_channel.dB_x_pad = -14 self.meter.meter_width = 5 self.top_pad = 14 self.meter.right_channel.y_top_pad = self.top_pad self.meter.left_channel.y_top_pad = self.top_pad w = SLOT_W - 40 h = METER_SLOT_H + 2 + 40 self.canvas = CairoDrawableArea(w, h, self._draw) self.widget = gtk.VBox(False, 0) self.widget.pack_start(self.canvas, False, False, 0)
def __init__(self, edit_listener, width=260, height=260): self.W = width self.H = height self.widget = CairoDrawableArea(self.W, self.H, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self.X_PAD = 12 self.Y_PAD = 12 self.CIRCLE_HALF = 8 self.cursor_x = self.X_PAD self.cursor_y = self.H - self.Y_PAD self.edit_listener = edit_listener self.hue = 0.0 self.saturation = 0.0 self.draw_saturation_gradient = True self.selection_cursor = SELECT_CIRCLE
def __init__(self, edit_listener): self.widget = CairoDrawableArea(260, 260, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self.X_PAD = 3 self.Y_PAD = 3 self.CENTER_X = 130 self.CENTER_Y = 130 self.MAX_DIST = 123 self.twelwe_p = (self.CENTER_X , self.CENTER_Y - self.MAX_DIST) self.CIRCLE_HALF = 6 self.cursor_x = self.CENTER_X self.cursor_y = self.CENTER_Y self.WHEEL_IMG = gtk.gdk.pixbuf_new_from_file(respaths.IMAGE_PATH + "color_wheel.png") self.edit_listener = edit_listener self.angle = 0.0 self.distance = 0.0
def __init__(self): self.widget = CairoDrawableArea(BAR_WIDTH, BAR_HEIGHT, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self._pos = END_PAD # in display pixels self.mark_in_norm = -1.0 # program length normalized self.mark_out_norm = -1.0 self.disabled = False self.mouse_release_listener = None # when used in tools (Tiler ate.) this used to update bg image if editorpersistance.prefs.dark_theme == True: global LINE_COLOR, BG_COLOR, DISABLED_BG_COLOR, SELECTED_RANGE_COLOR, MARK_COLOR LINE_COLOR = DARK_LINE_COLOR BG_COLOR = DARK_BG_COLOR DISABLED_BG_COLOR = DARK_DISABLED_BG_COLOR SELECTED_RANGE_COLOR = DARK_SELECTED_RANGE_COLOR MARK_COLOR = DARK_MARK_COLOR
def __init__(self, pix_size, curve, edit_listener): BoxEditor.__init__(self, pix_size) self.curve = curve # lutfilter.CRCurve global BOX_LINE_COLOR, CURVE_COLOR self.curve_color = CURVE_COLOR self.edit_listener = edit_listener # Needs to implement "curve_edit_done()" self.widget = CairoDrawableArea(self.pix_size + 2, self.pix_size + 2, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self.last_point = None self.edit_on = False if editorpersistance.prefs.dark_theme == True: BOX_LINE_COLOR = (0.8, 0.8, 0.8) CURVE_COLOR = (0.8, 0.8, 0.8) self.curve_color = CURVE_COLOR
def __init__(self, button_width, button_height, button_y, widget_width, widget_height): # Create widget and connect listeners self.widget = CairoDrawableArea(widget_width, widget_height, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self.pressed_callback_funcs = None # set later self.released_callback_funcs = None # set later self.pressed_button = -1 self.degrees = M_PI / 180.0 self.button_width = button_width self.button_height = button_height self.button_y = button_y self.button_x = 0 # set when first allocation known by extending class self.icons = [] self.image_x = [] self.image_y = [] self.sensitive = [] if editorpersistance.prefs.buttons_style == editorpersistance.GLASS_STYLE: self.glass_style = True else: self.glass_style = False # Dark theme comes with flat buttons self.dark_theme = False if editorpersistance.prefs.dark_theme == True: self.glass_style = False self.dark_theme = True self.draw_button_gradients = True # set False at object creation site to kill all gradients
class CurvesBoxEditor(BoxEditor): def __init__(self, pix_size, curve, edit_listener): BoxEditor.__init__(self, pix_size) self.curve = curve # lutfilter.CRCurve global BOX_LINE_COLOR, CURVE_COLOR self.curve_color = CURVE_COLOR self.edit_listener = edit_listener # Needs to implement "curve_edit_done()" self.widget = CairoDrawableArea(self.pix_size + 2, self.pix_size + 2, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self.last_point = None self.edit_on = False if editorpersistance.prefs.dark_theme == True: BOX_LINE_COLOR = (0.8, 0.8, 0.8) CURVE_COLOR = (0.8, 0.8, 0.8) self.curve_color = CURVE_COLOR def set_curve(self, curve, curve_color): self.curve = curve self.curve_color = curve_color self.widget.queue_draw() def _press_event(self, event): vx, vy = BoxEditor.get_box_val_point(self, event.x, event.y) p = lutfilter.CurvePoint(int(round(vx * 255)), int(round(vy * 255))) self.last_point = p self.edit_on = True self.curve.remove_range(self.last_point.x - 3, self.last_point.x + 3 ) self.curve.set_curve_point(p) self.widget.queue_draw() def _motion_notify_event(self, x, y, state): if self.edit_on == False: return vx, vy = BoxEditor.get_box_val_point(self, x, y) p = lutfilter.CurvePoint(int(round(vx * 255)), int(round(vy * 255))) self.curve.remove_range(self.last_point.x, p.x) self.curve.set_curve_point(p) self.last_point = p self.widget.queue_draw() def _release_event(self, event): if self.edit_on == False: return vx, vy = BoxEditor.get_box_val_point(self, event.x, event.y) p = lutfilter.CurvePoint(int(round(vx * 255)),int(round(vy * 255))) self.curve.remove_range(self.last_point.x, p.x) self.curve.set_curve_point(p) self.edit_on = False self.edit_listener.curve_edit_done() self.widget.queue_draw() def _draw(self, event, cr, allocation): # bg box BoxEditor.draw_box(self, cr, allocation) x, y, w, h = allocation # curve cr.set_source_rgb(*self.curve_color)# seg.setColor( CURVE_COLOR ); cr.set_line_width(1.5) cp = self.curve.get_curve(True) #we get 256 values px, py = BoxEditor.get_box_panel_point(self, 0, cp[0], 255) cr.move_to(px, py) for i in range(1, len(cp)): #int i = 0; i < cp.length - 1; i++ ) px, py = BoxEditor.get_box_panel_point(self, i, cp[i], 255.0) cr.line_to(px, py) cr.stroke() cr.rectangle(1, 1, w - 3, h - 3) cr.clip() # edit points for p in self.curve.points: px, py = BoxEditor.get_box_panel_point(self, p.x, p.y, 255.0) _draw_select_circle(cr, px, py, (1,1,1), 4, 2, 0, -4, -4)
class ColorBox: def __init__(self, edit_listener, width=260, height=260): self.W = width self.H = height self.widget = CairoDrawableArea(self.W, self.H, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self.X_PAD = 12 self.Y_PAD = 12 self.CIRCLE_HALF = 8 self.cursor_x = self.X_PAD self.cursor_y = self.H - self.Y_PAD self.edit_listener = edit_listener self.hue = 0.0 self.saturation = 0.0 self.draw_saturation_gradient = True self.selection_cursor = SELECT_CIRCLE def get_hue_saturation(self): return (self.hue, self.saturation) def _save_values(self): self.hue = float((self.cursor_x - self.X_PAD)) / float((self.W - 2 * self.X_PAD)) self.saturation = float(abs(self.cursor_y - self.H + self.Y_PAD)) / float((self.H - 2 * self.Y_PAD)) def set_cursor(self, hue, saturation): self.cursor_x = self._x_for_hue(hue) self.cursor_y = self._y_for_saturation(saturation) self._save_values() def _x_for_hue(self, hue): return self.X_PAD + hue * (self.W - self.X_PAD * 2) def _y_for_saturation(self, saturation): return self.Y_PAD + (1.0 - saturation) * (self.H - self.Y_PAD *2) def _press_event(self, event): self.cursor_x, self.cursor_y = self._get_legal_point(event.x, event.y) self._save_values() self.edit_listener() self.widget.queue_draw() def _motion_notify_event(self, x, y, state): self.cursor_x, self.cursor_y = self._get_legal_point(x, y) self._save_values() self.edit_listener() self.widget.queue_draw() def _release_event(self, event): self.cursor_x, self.cursor_y = self._get_legal_point(event.x, event.y) self._save_values() self.edit_listener() self.widget.queue_draw() def _get_legal_point(self, x, y): if x < self.X_PAD: x = self.X_PAD elif x > self.W - self.X_PAD: x = self.W - self.X_PAD if y < self.Y_PAD: y = self.Y_PAD elif y > self.H - self.Y_PAD: y = self.H - self.Y_PAD return (x, y) def _draw(self, event, cr, allocation): """ Callback for repaint from CairoDrawableArea. We get cairo context and allocation. """ x, y, w, h = allocation # Draw bg cr.set_source_rgb(*(gui.bg_color_tuple)) cr.rectangle(0, 0, w, h) cr.fill() x_in = self.X_PAD x_out = self.W - self.X_PAD y_in = self.Y_PAD y_out = self.H - self.Y_PAD grad = cairo.LinearGradient (x_in, 0, x_out, 0) grad.add_color_stop_rgba(*RED_STOP) grad.add_color_stop_rgba(*YELLOW_STOP) grad.add_color_stop_rgba(*GREEN_STOP) grad.add_color_stop_rgba(*CYAN_STOP) grad.add_color_stop_rgba(*MAGENTA_STOP) grad.add_color_stop_rgba(*RED_STOP_END) cr.set_source(grad) cr.rectangle(self.X_PAD, self.Y_PAD, x_out - x_in, y_out - y_in) cr.fill() if self.draw_saturation_gradient == True: grey_grad = cairo.LinearGradient (0, y_in, 0, y_out) grey_grad.add_color_stop_rgba(*GREY_GRAD_1) grey_grad.add_color_stop_rgba(*GREY_GRAD_2) cr.set_source(grey_grad) cr.rectangle(self.X_PAD, self.Y_PAD, x_out - x_in, y_out - y_in) cr.fill() if self.selection_cursor == SELECT_CIRCLE: _draw_select_circle(cr, self.cursor_x - self.CIRCLE_HALF, self.cursor_y - self.CIRCLE_HALF, (1, 1, 1), 8, 6, 8) else: _draw_select_line(cr, self.cursor_x, y_out)
class AbstractColorWheel: def __init__(self, edit_listener): self.widget = CairoDrawableArea(260, 260, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self.X_PAD = 3 self.Y_PAD = 3 self.CENTER_X = 130 self.CENTER_Y = 130 self.MAX_DIST = 123 self.twelwe_p = (self.CENTER_X , self.CENTER_Y - self.MAX_DIST) self.CIRCLE_HALF = 6 self.cursor_x = self.CENTER_X self.cursor_y = self.CENTER_Y self.WHEEL_IMG = gtk.gdk.pixbuf_new_from_file(respaths.IMAGE_PATH + "color_wheel.png") self.edit_listener = edit_listener self.angle = 0.0 self.distance = 0.0 def _press_event(self, event): """ Mouse button callback """ self.cursor_x, self.cursor_y = self._get_legal_point(event.x, event.y) self._save_point() self.widget.queue_draw() def _motion_notify_event(self, x, y, state): """ Mouse move callback """ self.cursor_x, self.cursor_y = self._get_legal_point(x, y) self._save_point() self.widget.queue_draw() def _release_event(self, event): self.cursor_x, self.cursor_y = self._get_legal_point(event.x, event.y) self._save_point() self.edit_listener() self.widget.queue_draw() def _get_legal_point(self, x, y): vec = viewgeom.get_vec_for_points((self.CENTER_X, self.CENTER_Y), (x, y)) dist = vec.get_length() if dist < self.MAX_DIST: return (x, y) new_vec = vec.get_multiplied_vec(self.MAX_DIST / dist ) return new_vec.end_point def get_angle(self, p): angle = viewgeom.get_angle_in_deg(self.twelwe_p, (self.CENTER_X, self.CENTER_Y), p) clockwise = viewgeom.points_clockwise(self.twelwe_p, (self.CENTER_X, self.CENTER_Y), p) if clockwise: angle = 360.0 - angle; # Color circle starts from 11 o'clock angle = angle - 30.0 if angle < 0.0: angle = angle + 360.0 return angle def get_distance(self, p): vec = viewgeom.get_vec_for_points((self.CENTER_X, self.CENTER_Y), p) dist = vec.get_length() return dist/self.MAX_DIST def _save_point(self): print "_save_point not implemented" pass def get_angle_and_distance(self): if self.band == SHADOW: x = self.shadow_x y = self.shadow_y elif self.band == MID: x = self.mid_x y = self.mid_y else: x = self.hi_x y = self.hi_y p = (x, y) angle = self._get_angle(p) distance = self._get_distance(p) return (angle, distance) def _draw(self, event, cr, allocation): """ Callback for repaint from CairoDrawableArea. We get cairo context and allocation. """ x, y, w, h = allocation # Draw bg cr.set_source_rgb(*(gui.bg_color_tuple)) cr.rectangle(0, 0, w, h) cr.fill() cr.set_source_pixbuf(self.WHEEL_IMG, self.X_PAD, self.Y_PAD) cr.paint()
class PositionBar: """ GUI component used to set/display position in clip/timeline """ def __init__(self): self.widget = CairoDrawableArea(BAR_WIDTH, BAR_HEIGHT, self._draw) self.widget.press_func = self._press_event self.widget.motion_notify_func = self._motion_notify_event self.widget.release_func = self._release_event self._pos = END_PAD # in display pixels self.mark_in_norm = -1.0 # program length normalized self.mark_out_norm = -1.0 self.disabled = False self.mouse_release_listener = None # when used in tools (Tiler ate.) this used to update bg image if editorpersistance.prefs.dark_theme == True: global LINE_COLOR, BG_COLOR, DISABLED_BG_COLOR, SELECTED_RANGE_COLOR, MARK_COLOR LINE_COLOR = DARK_LINE_COLOR BG_COLOR = DARK_BG_COLOR DISABLED_BG_COLOR = DARK_DISABLED_BG_COLOR SELECTED_RANGE_COLOR = DARK_SELECTED_RANGE_COLOR MARK_COLOR = DARK_MARK_COLOR def set_listener(self, listener): self.position_listener = listener def set_normalized_pos(self, norm_pos): """ Sets position in range 0 - 1 """ self._pos = self._get_panel_pos(norm_pos) self.widget.queue_draw() def update_display_from_producer(self, producer): self.producer = producer length = producer.get_length() # Get from MLT try: self.mark_in_norm = float(producer.mark_in) / length self.mark_out_norm = float(producer.mark_out) / length frame_pos = producer.frame() norm_pos = float(frame_pos) / length self._pos = self._get_panel_pos(norm_pos) except ZeroDivisionError: self.mark_in_norm = 0 self.mark_out_norm = 0 self._pos = self._get_panel_pos(0) self.widget.queue_draw() def _get_panel_pos(self, norm_pos): return END_PAD + int(norm_pos * (self.widget.allocation.width - 2 * END_PAD)) def _draw(self, event, cr, allocation): """ Callback for repaint from CairoDrawableArea. We get cairo contect and allocation. """ x, y, w, h = allocation # Draw bb draw_color = BG_COLOR if self.disabled: draw_color = DISABLED_BG_COLOR cr.set_source_rgb(*draw_color) cr.rectangle(0,0,w,h) cr.fill() # Draw selected area if marks set if self.mark_in_norm >= 0 and self.mark_out_norm >= 0: cr.set_source_rgb(*SELECTED_RANGE_COLOR) m_in = self._get_panel_pos(self.mark_in_norm) m_out = self._get_panel_pos(self.mark_out_norm) cr.rectangle(m_in, 0, m_out - m_in, h) cr.fill() # Get area between end pads active_width = w - 2 * END_PAD # Draw lines cr.set_line_width(1.0) x_step = float(active_width) / (LINE_COUNT) for i in range(LINE_COUNT + 1): cr.move_to(int((i) * x_step) + END_PAD + 0.5, -0.5) cr.line_to(int((i) * x_step) + END_PAD + 0.5, LINE_HEIGHT + 0.5) for i in range(LINE_COUNT + 1): cr.move_to(int((i) * x_step) + END_PAD + 0.5, BAR_HEIGHT) cr.line_to(int((i) * x_step) + END_PAD + 0.5, BAR_HEIGHT - LINE_HEIGHT + 0.5) cr.set_source_rgb(*LINE_COLOR) cr.stroke() # Draw mark in and mark out self.draw_mark_in(cr, h) self.draw_mark_out(cr, h) # Draw position pointer if self.disabled: return cr.set_line_width(2.0) cr.set_source_rgb(*POINTER_COLOR) cr.move_to(self._pos + 0.5, 0) cr.line_to(self._pos + 0.5, BAR_HEIGHT) cr.stroke() speed = editorstate.PLAYER().producer.get_speed() if speed != 1.0 and speed != 0.0: cr.set_source_rgb(*SPEED_TEST_COLOR) cr.select_font_face ("sans-serif", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(11) disp_str = str(speed) + "x" tx, ty, twidth, theight, dx, dy = cr.text_extents(disp_str) cr.move_to( w/2 - twidth/2, 13) cr.show_text(disp_str) def draw_mark_in(self, cr, h): """ Draws mark in graphic if set. """ if self.mark_in_norm < 0: return x = self._get_panel_pos(self.mark_in_norm) cr.move_to (x, MARK_PAD) cr.line_to (x, h - MARK_PAD) cr.line_to (x - 2 * MARK_LINE_WIDTH, h - MARK_PAD) cr.line_to (x - 2 * MARK_LINE_WIDTH, h - MARK_LINE_WIDTH - MARK_PAD) cr.line_to (x - MARK_LINE_WIDTH, h - MARK_LINE_WIDTH - MARK_PAD ) cr.line_to (x - MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD) cr.line_to (x - 2 * MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD ) cr.line_to (x - 2 * MARK_LINE_WIDTH, MARK_PAD) cr.close_path(); cr.set_source_rgb(*MARK_COLOR) cr.fill() def draw_mark_out(self, cr, h): """ Draws mark out graphic if set. """ if self.mark_out_norm < 0: return x = self._get_panel_pos(self.mark_out_norm) cr.move_to (x, MARK_PAD) cr.line_to (x, h - MARK_PAD) cr.line_to (x + 2 * MARK_LINE_WIDTH, h - MARK_PAD) cr.line_to (x + 2 * MARK_LINE_WIDTH, h - MARK_LINE_WIDTH - MARK_PAD) cr.line_to (x + MARK_LINE_WIDTH, h - MARK_LINE_WIDTH - MARK_PAD ) cr.line_to (x + MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD) cr.line_to (x + 2 * MARK_LINE_WIDTH, MARK_LINE_WIDTH + MARK_PAD ) cr.line_to (x + 2 * MARK_LINE_WIDTH, MARK_PAD) cr.close_path(); cr.set_source_rgb(*MARK_COLOR) cr.fill() def _press_event(self, event): """ Mouse button callback """ if self.disabled: return if editorstate.timeline_visible(): trimmodes.set_no_edit_trim_mode() if((event.button == 1) or(event.button == 3)): # Set pos to in active range to get normalized pos self._pos = self._legalize_x(event.x) # Listener calls self.set_normalized_pos() # _pos gets actually set twice # Listener also updates other frame displayers self.position_listener(self.normalized_pos(), self.producer.get_length()) def _motion_notify_event(self, x, y, state): """ Mouse move callback """ if self.disabled: return if((state & gtk.gdk.BUTTON1_MASK) or (state & gtk.gdk.BUTTON3_MASK)): self._pos = self._legalize_x(x) # Listener calls self.set_normalized_pos() self.position_listener(self.normalized_pos(), self.producer.get_length()) def _release_event(self, event): """ Mouse release callback. """ if self.disabled: return self._pos = self._legalize_x(event.x) # Listener calls self.set_normalized_pos() self.position_listener(self.normalized_pos(), self.producer.get_length()) if self.mouse_release_listener != None: self.mouse_release_listener(self.normalized_pos(), self.producer.get_length()) def _legalize_x(self, x): """ Get x in pixel range corresponding normalized position 0.0 - 1.0. This is needed because of end pads. """ w = self.widget.allocation.width if x < END_PAD: return END_PAD elif x > w - END_PAD: return w - END_PAD else: return x def normalized_pos(self): return float(self._pos - END_PAD) / \ (self.widget.allocation.width - END_PAD * 2)