Exemplo n.º 1
0
    def _createUI(self):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(get_ui_dir(), "titleeditor.ui"))
        builder.connect_signals(self)
        self.widget = builder.get_object("box1")  # To be used by tabsmanager
        self.infobar = builder.get_object("infobar")
        fix_infobar(self.infobar)
        self.editing_box = builder.get_object("base_table")

        self.textarea = builder.get_object("textview")

        self.textbuffer = self.textarea.props.buffer
        self.textbuffer.connect("changed", self._textChangedCb)

        self.font_button = builder.get_object("fontbutton1")
        self.foreground_color_button = builder.get_object("fore_text_color")
        self.background_color_button = builder.get_object("back_color")

        self.color_picker_foreground_widget = ColorPickerButton()
        self.color_picker_foreground_widget.show()
        self.color_picker_foreground = builder.get_object(
            "color_picker_foreground")
        self.color_picker_foreground.add(self.color_picker_foreground_widget)
        self.color_picker_foreground_widget.connect(
            "value-changed", self._color_picker_value_changed_cb,
            self.foreground_color_button, "color")

        self.color_picker_background_widget = ColorPickerButton()
        self.color_picker_background_widget.show()
        self.background_color_picker = builder.get_object(
            "color_picker_background")
        self.background_color_picker.add(self.color_picker_background_widget)
        self.color_picker_background_widget.connect(
            "value-changed", self._color_picker_value_changed_cb,
            self.background_color_button, "foreground-color")

        settings = ["valignment", "halignment", "x-absolute", "y-absolute"]
        for setting in settings:
            self.settings[setting] = builder.get_object(setting)

        for n, en in list({
                _("Absolute"): "absolute",
                _("Top"): "top",
                _("Center"): "center",
                _("Bottom"): "bottom",
                _("Baseline"): "baseline"
        }.items()):
            self.settings["valignment"].append(en, n)

        for n, en in list({
                _("Absolute"): "absolute",
                _("Left"): "left",
                _("Center"): "center",
                _("Right"): "right"
        }.items()):
            self.settings["halignment"].append(en, n)
Exemplo n.º 2
0
    def _create_ui(self):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(get_ui_dir(), "titleeditor.ui"))
        builder.connect_signals(self)
        # Create UI
        self.add(builder.get_object("box1"))
        self.editing_box = builder.get_object("base_table")

        self.textarea = builder.get_object("textview")

        self.textbuffer = self.textarea.props.buffer
        self.textbuffer.connect("changed", self._text_changed_cb)

        self.font_button = builder.get_object("fontbutton1")
        self.foreground_color_button = builder.get_object("fore_text_color")
        self.background_color_button = builder.get_object("back_color")

        self.color_picker_foreground_widget = ColorPickerButton()
        self.color_picker_foreground_widget.show()
        self.color_picker_foreground = builder.get_object(
            "color_picker_foreground")
        self.color_picker_foreground.add(self.color_picker_foreground_widget)
        self.color_picker_foreground_widget.connect(
            "value-changed", self._color_picker_value_changed_cb,
            self.foreground_color_button, "color")

        self.color_picker_background_widget = ColorPickerButton()
        self.color_picker_background_widget.show()
        self.background_color_picker = builder.get_object(
            "color_picker_background")
        self.background_color_picker.add(self.color_picker_background_widget)
        self.color_picker_background_widget.connect(
            "value-changed", self._color_picker_value_changed_cb,
            self.background_color_button, "foreground-color")

        self.valignment_combo = builder.get_object("valignment")
        self.halignment_combo = builder.get_object("halignment")
        self.x_absolute_spin = builder.get_object("x-absolute")
        self.y_absolute_spin = builder.get_object("y-absolute")

        for value_id, text in (("absolute", _("Absolute")), ("top", _("Top")),
                               ("center", _("Center")),
                               ("bottom", _("Bottom")), ("baseline",
                                                         _("Baseline"))):
            self.valignment_combo.append(value_id, text)

        for value_id, text in (("absolute", _("Absolute")), ("left",
                                                             _("Left")),
                               ("center", _("Center")), ("right", _("Right"))):
            self.halignment_combo.append(value_id, text)

        self.show_all()
Exemplo n.º 3
0
    def _create_ui(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_file(os.path.join(get_ui_dir(), "clipcolor.ui"))
        self.builder.connect_signals(self)

        box = self.builder.get_object("color_box")
        self.add(box)

        self.color_button = self.builder.get_object("color_button")

        self.color_picker_button = ColorPickerButton()
        box.add(self.color_picker_button)
        self.color_picker_button.connect("value-changed",
                                         self._color_picker_value_changed_cb)

        self.show_all()
Exemplo n.º 4
0
    def _createUI(self):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(get_ui_dir(), "titleeditor.ui"))
        builder.connect_signals(self)
        self.widget = builder.get_object("box1")  # To be used by tabsmanager
        self.infobar = builder.get_object("infobar")
        fix_infobar(self.infobar)
        self.editing_box = builder.get_object("base_table")

        self.textarea = builder.get_object("textview")

        self.textbuffer = self.textarea.props.buffer
        self.textbuffer.connect("changed", self._textChangedCb)

        self.font_button = builder.get_object("fontbutton1")
        self.foreground_color_button = builder.get_object("fore_text_color")
        self.background_color_button = builder.get_object("back_color")

        self.color_picker_foreground_widget = ColorPickerButton()
        self.color_picker_foreground_widget.show()
        self.color_picker_foreground = builder.get_object("color_picker_foreground")
        self.color_picker_foreground.add(self.color_picker_foreground_widget)
        self.color_picker_foreground_widget.connect("value-changed", self._color_picker_value_changed_cb, self.foreground_color_button, "color")

        self.color_picker_background_widget = ColorPickerButton()
        self.color_picker_background_widget.show()
        self.background_color_picker = builder.get_object("color_picker_background")
        self.background_color_picker.add(self.color_picker_background_widget)
        self.color_picker_background_widget.connect("value-changed", self._color_picker_value_changed_cb, self.background_color_button, "foreground-color")

        settings = ["valignment", "halignment", "x-absolute", "y-absolute"]
        for setting in settings:
            self.settings[setting] = builder.get_object(setting)

        for n, en in list({_("Absolute"): "absolute",
                           _("Top"): "top",
                           _("Center"): "center",
                           _("Bottom"): "bottom",
                           _("Baseline"): "baseline"}.items()):
            self.settings["valignment"].append(en, n)

        for n, en in list({_("Absolute"): "absolute",
                           _("Left"): "left",
                           _("Center"): "center",
                           _("Right"): "right"}.items()):
            self.settings["halignment"].append(en, n)
Exemplo n.º 5
0
def create_alpha_widget(effect_prop_manager, element_setting_widget, element):
    """Creates the UI for the `alpha` effect."""
    builder = setup_from_ui_file(element_setting_widget,
                                 os.path.join(CUSTOM_WIDGETS_DIR, "alpha.ui"))

    color_picker = ColorPickerButton(0, 255, 0)
    color_picker_frame = builder.get_object("color_picker_frame")
    color_picker_frame.add(color_picker)

    # Additional Setup

    # All modes other than custom RGB chroma keying are useless to us.
    # "ALPHA_METHOD_CUSTOM" corresponds to "3"
    Loggable().debug("Setting alpha's method to 3 (custom RGB chroma keying)")
    element.set_child_property("method", 3)

    # Color button and picker has to be connected manually!

    def get_current_rgba():
        """Gets the color used by the effect."""
        color = Gdk.RGBA()
        res, red = element.get_child_property("target-r")
        assert res
        res, green = element.get_child_property("target-g")
        assert res
        res, blue = element.get_child_property("target-b")
        assert res
        color.red = red / 255
        color.green = green / 255
        color.blue = blue / 255
        return color

    def color_button_color_set_cb(color_button):
        """Handles the selection of a color with the color button."""
        color = color_button.get_rgba()
        red = int(color.red * 255)
        green = int(color.green * 255)
        blue = int(color.blue * 255)
        from pitivi.undo.timeline import CommitTimelineFinalizingAction
        pipeline = effect_prop_manager.app.project_manager.current_project.pipeline
        action_log = effect_prop_manager.app.action_log
        with action_log.started(
                "Effect property change",
                finalizing_action=CommitTimelineFinalizingAction(pipeline),
                toplevel=True):
            element.set_child_property("target-r", red)
            element.set_child_property("target-g", green)
            element.set_child_property("target-b", blue)

    color_button = builder.get_object("colorbutton")
    color_button.connect("color-set", color_button_color_set_cb)

    def color_picker_value_changed_cb(unused_color_picker_button):
        """Handles the selection of a color with the color picker button."""
        from pitivi.undo.timeline import CommitTimelineFinalizingAction
        pipeline = effect_prop_manager.app.project_manager.current_project.pipeline
        action_log = effect_prop_manager.app.action_log
        with action_log.started(
                "Color Picker Change",
                finalizing_action=CommitTimelineFinalizingAction(pipeline),
                toplevel=True):
            element.set_child_property("target-r", color_picker.color_r)
            element.set_child_property("target-g", color_picker.color_g)
            element.set_child_property("target-b", color_picker.color_b)

    color_picker.connect("value-changed", color_picker_value_changed_cb)

    def property_changed_cb(unused_effect, gst_element, pspec):
        """Handles the change of a GObject property."""
        if gst_element.get_control_binding(pspec.name):
            Loggable().log("%s controlled, not displaying value", pspec.name)
            return

        widget = element_setting_widget.properties.get(pspec)
        if not widget:
            return

        res, value = element_setting_widget.element.get_child_property(
            pspec.name)
        assert res

        if pspec.name in ("target-r", "target-g", "target-b"):
            color_button.set_rgba(get_current_rgba())
            widget.block_signals()
            try:
                widget.setWidgetValue(value)
            finally:
                widget.unblock_signals()
        else:
            widget.setWidgetValue(value)

    element.connect("deep-notify", property_changed_cb)

    return builder.get_object("base_table")
Exemplo n.º 6
0
def create_3point_color_balance_widget(effect_prop_manager,
                                       element_setting_widget, element):
    """Creates a widget for the `frei0r-filter-3-point-color-balance` effect."""
    ui_path = os.path.join(CUSTOM_WIDGETS_DIR,
                           "frei0r-filter-3-point-color-balance.ui")
    builder = setup_from_ui_file(element_setting_widget, ui_path)
    element_setting_widget.mapBuilder(builder)
    color_balance_grid = builder.get_object("base_table")

    shadows_wheel = Gtk.HSV()
    midtones_wheel = Gtk.HSV()
    highlights_wheel = Gtk.HSV()

    color_balance_grid.attach(shadows_wheel, 1, 1, 1, 1)
    color_balance_grid.attach(midtones_wheel, 2, 1, 1, 1)
    color_balance_grid.attach(highlights_wheel, 3, 1, 1, 1)

    shadows_color_picker_button = ColorPickerButton()
    midtones_color_picker_button = ColorPickerButton()
    highlights_color_picker_button = ColorPickerButton()

    shadows_color_picker_frame = builder.get_object(
        "shadows_color_picker_frame")
    midtones_color_picker_frame = builder.get_object(
        "midtones_color_picker_frame")
    highlights_color_picker_frame = builder.get_object(
        "highlights_color_picker_frame")

    shadows_color_picker_frame.add(shadows_color_picker_button)
    midtones_color_picker_frame.add(midtones_color_picker_button)
    highlights_color_picker_frame.add(highlights_color_picker_button)

    # Manually handle the custom part of the UI.
    # 1) Connecting the color wheel widgets
    # 2) Scale values between to be shown on the UI vs
    #    the actual property values (RGB values here).

    black_r = element_setting_widget.get_widget_of_prop("black-color-r")
    black_g = element_setting_widget.get_widget_of_prop("black-color-g")
    black_b = element_setting_widget.get_widget_of_prop("black-color-b")

    gray_r = element_setting_widget.get_widget_of_prop("gray-color-r")
    gray_g = element_setting_widget.get_widget_of_prop("gray-color-g")
    gray_b = element_setting_widget.get_widget_of_prop("gray-color-b")

    white_r = element_setting_widget.get_widget_of_prop("white-color-r")
    white_g = element_setting_widget.get_widget_of_prop("white-color-g")
    white_b = element_setting_widget.get_widget_of_prop("white-color-b")

    # The UI widget values need to be scaled back to the property.
    # Since for RGB values, 0-255 format is used in the UI
    # where as the property values are actually between 0-1.

    def get_widget_scaled_value(self):
        """Gets the color value for the GES element property."""
        return self.adjustment.get_value() / 255

    black_r.getWidgetValue = MethodType(get_widget_scaled_value, black_r)
    black_g.getWidgetValue = MethodType(get_widget_scaled_value, black_g)
    black_b.getWidgetValue = MethodType(get_widget_scaled_value, black_b)

    gray_r.getWidgetValue = MethodType(get_widget_scaled_value, gray_r)
    gray_g.getWidgetValue = MethodType(get_widget_scaled_value, gray_g)
    gray_b.getWidgetValue = MethodType(get_widget_scaled_value, gray_b)

    white_r.getWidgetValue = MethodType(get_widget_scaled_value, white_r)
    white_b.getWidgetValue = MethodType(get_widget_scaled_value, white_b)
    white_g.getWidgetValue = MethodType(get_widget_scaled_value, white_g)

    # Update underlying GObject color properties when the color widgets change.

    def color_wheel_changed_cb(color_wheel, prop_r, prop_g, prop_b):
        """Handles the selection of a color with a color wheel."""
        hsv_color = color_wheel.get_color()
        rgb_color = color_wheel.to_rgb(hsv_color.h, hsv_color.s, hsv_color.v)
        from pitivi.undo.timeline import CommitTimelineFinalizingAction
        pipeline = effect_prop_manager.app.project_manager.current_project.pipeline
        action_log = effect_prop_manager.app.action_log
        with action_log.started(
                "Effect property change",
                finalizing_action=CommitTimelineFinalizingAction(pipeline),
                toplevel=False):
            element.set_child_property(prop_r, rgb_color.r)
            element.set_child_property(prop_g, rgb_color.g)
            element.set_child_property(prop_b, rgb_color.b)

    shadows_wheel.connect("changed", color_wheel_changed_cb, "black-color-r",
                          "black-color-g", "black-color-b")
    midtones_wheel.connect("changed", color_wheel_changed_cb, "gray-color-r",
                           "gray-color-g", "gray-color-b")
    highlights_wheel.connect("changed", color_wheel_changed_cb,
                             "white-color-r", "white-color-g", "white-color-b")

    def color_picker_value_changed_cb(color_picker_button, prop_r, prop_g,
                                      prop_b):
        """Handles the selection of a color with the color picker button."""
        from pitivi.undo.timeline import CommitTimelineFinalizingAction
        pipeline = effect_prop_manager.app.project_manager.current_project.pipeline
        action_log = effect_prop_manager.app.action_log
        with action_log.started(
                "Effect property change",
                finalizing_action=CommitTimelineFinalizingAction(pipeline),
                toplevel=True):
            element.set_child_property(prop_r,
                                       color_picker_button.color_r / 255)
            element.set_child_property(prop_g,
                                       color_picker_button.color_g / 255)
            element.set_child_property(prop_b,
                                       color_picker_button.color_b / 255)

    shadows_color_picker_button.connect("value-changed",
                                        color_picker_value_changed_cb,
                                        "black-color-r", "black-color-g",
                                        "black-color-b")
    midtones_color_picker_button.connect("value-changed",
                                         color_picker_value_changed_cb,
                                         "gray-color-r", "gray-color-g",
                                         "gray-color-b")
    highlights_color_picker_button.connect("value-changed",
                                           color_picker_value_changed_cb,
                                           "white-color-r", "white-color-g",
                                           "white-color-b")

    def update_wheel(prop_r, prop_g, prop_b, wheel, numeric_widget, value):
        """Updates the widgets with the value from the Gst element."""
        _, r = element_setting_widget.element.get_child_property(prop_r)
        _, g = element_setting_widget.element.get_child_property(prop_g)
        _, b = element_setting_widget.element.get_child_property(prop_b)
        new_hsv = rgb_to_hsv(r, g, b)
        # GtkHSV always emits `changed` signal when set_color is used.
        # But we need to only emit it when the color has actually changed!
        current_hsv = wheel.get_color()
        if current_hsv != new_hsv:
            wheel.set_color(*new_hsv)
        numeric_widget.block_signals()
        try:
            numeric_widget.setWidgetValue(round(value * 255))
        finally:
            numeric_widget.unblock_signals()

    def property_changed_cb(unused_effect, gst_element, pspec):
        """Handles the change of a GObject property."""
        if gst_element.get_control_binding(pspec.name):
            Loggable().log("%s controlled, not displaying value", pspec.name)
            return

        widget = element_setting_widget.properties.get(pspec)
        if not widget:
            return

        res, value = element_setting_widget.element.get_child_property(
            pspec.name)
        assert res

        if pspec.name in ("black-color-r", "black-color-g", "black-color-b"):
            update_wheel("black-color-r", "black-color-g", "black-color-b",
                         shadows_wheel, widget, value)
        elif pspec.name in ("gray-color-r", "gray-color-g", "gray-color-b"):
            update_wheel("gray-color-r", "gray-color-g", "gray-color-b",
                         midtones_wheel, widget, value)
        elif pspec.name in ("white-color-r", "white-color-g", "white-color-b"):
            update_wheel("white-color-r", "white-color-g", "white-color-b",
                         highlights_wheel, widget, value)
        else:
            widget.setWidgetValue(value)

    element.connect("deep-notify", property_changed_cb)

    shadows_reset_button = builder.get_object("shadows_reset_button")
    midtones_reset_button = builder.get_object("midtones_reset_button")
    highlights_reset_button = builder.get_object("highlights_reset_button")

    def reset_wheel_cb(unused_arg, wheel, value):
        """Handles the click of a reset button."""
        wheel.set_color(0, 0, value)

    shadows_reset_button.connect("clicked", reset_wheel_cb, shadows_wheel, 0)
    midtones_reset_button.connect("clicked", reset_wheel_cb, midtones_wheel,
                                  0.5)
    highlights_reset_button.connect("clicked", reset_wheel_cb,
                                    highlights_wheel, 1)

    # Initialize the wheels with the correct values

    shadows_wheel.set_color(0, 0, 0)
    midtones_wheel.set_color(0, 0, 0.5)
    highlights_wheel.set_color(0, 0, 1)

    return color_balance_grid
Exemplo n.º 7
0
class TitleEditor(Loggable):
    """Widget for configuring a title.

    Attributes:
        app (Pitivi): The app.
        _project (Project): The project.
    """
    def __init__(self, app):
        Loggable.__init__(self)
        self.app = app
        self.settings = {}
        self.source = None
        self._project = None
        self._selection = None

        self._setting_props = False
        self._children_props_handler = None

        self._createUI()
        # Updates the UI.
        self.set_source(None)

        self.app.project_manager.connect_after("new-project-loaded",
                                               self._newProjectLoadedCb)

    def _createUI(self):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(get_ui_dir(), "titleeditor.ui"))
        builder.connect_signals(self)
        self.widget = builder.get_object("box1")  # To be used by tabsmanager
        self.infobar = builder.get_object("infobar")
        fix_infobar(self.infobar)
        self.editing_box = builder.get_object("base_table")

        self.textarea = builder.get_object("textview")

        self.textbuffer = self.textarea.props.buffer
        self.textbuffer.connect("changed", self._textChangedCb)

        self.font_button = builder.get_object("fontbutton1")
        self.foreground_color_button = builder.get_object("fore_text_color")
        self.background_color_button = builder.get_object("back_color")

        self.color_picker_foreground_widget = ColorPickerButton()
        self.color_picker_foreground_widget.show()
        self.color_picker_foreground = builder.get_object(
            "color_picker_foreground")
        self.color_picker_foreground.add(self.color_picker_foreground_widget)
        self.color_picker_foreground_widget.connect(
            "value-changed", self._color_picker_value_changed_cb,
            self.foreground_color_button, "color")

        self.color_picker_background_widget = ColorPickerButton()
        self.color_picker_background_widget.show()
        self.background_color_picker = builder.get_object(
            "color_picker_background")
        self.background_color_picker.add(self.color_picker_background_widget)
        self.color_picker_background_widget.connect(
            "value-changed", self._color_picker_value_changed_cb,
            self.background_color_button, "foreground-color")

        settings = ["valignment", "halignment", "x-absolute", "y-absolute"]
        for setting in settings:
            self.settings[setting] = builder.get_object(setting)

        for n, en in list({
                _("Absolute"): "absolute",
                _("Top"): "top",
                _("Center"): "center",
                _("Bottom"): "bottom",
                _("Baseline"): "baseline"
        }.items()):
            self.settings["valignment"].append(en, n)

        for n, en in list({
                _("Absolute"): "absolute",
                _("Left"): "left",
                _("Center"): "center",
                _("Right"): "right"
        }.items()):
            self.settings["halignment"].append(en, n)

    def _setChildProperty(self, name, value):
        with self.app.action_log.started("Title change property",
                                         toplevel=True):
            self._setting_props = True
            try:
                res = self.source.set_child_property(name, value)
                assert res
            finally:
                self._setting_props = False

    def _color_picker_value_changed_cb(self, widget, colorButton, colorLayer):
        argb = 0
        argb += (1 * 255) * 256**3
        argb += float(widget.color_r) * 256**2
        argb += float(widget.color_g) * 256**1
        argb += float(widget.color_b) * 256**0
        self.debug("Setting text %s to %x", colorLayer, argb)
        self._setChildProperty(colorLayer, argb)
        rgba = argb_to_gdk_rgba(argb)
        colorButton.set_rgba(rgba)

    def _backgroundColorButtonCb(self, widget):
        color = gdk_rgba_to_argb(widget.get_rgba())
        self.debug("Setting title background color to %x", color)
        self._setChildProperty("foreground-color", color)

    def _frontTextColorButtonCb(self, widget):
        color = gdk_rgba_to_argb(widget.get_rgba())
        self.debug("Setting title foreground color to %x", color)
        # TODO: Use set_text_color when we work with TitleSources instead of
        # TitleClips
        self._setChildProperty("color", color)

    def _fontButtonCb(self, widget):
        font_desc = widget.get_font_desc().to_string()
        self.debug("Setting font desc to %s", font_desc)
        self._setChildProperty("font-desc", font_desc)

    def _updateFromSource(self, source):
        self.textbuffer.set_text(source.get_child_property("text")[1] or "")
        self.settings['x-absolute'].set_value(
            source.get_child_property("x-absolute")[1])
        self.settings['y-absolute'].set_value(
            source.get_child_property("y-absolute")[1])
        self.settings['valignment'].set_active_id(
            source.get_child_property("valignment")[1].value_name)
        self.settings['halignment'].set_active_id(
            source.get_child_property("halignment")[1].value_name)
        self._updateWidgetsVisibility()

        font_desc = Pango.FontDescription.from_string(
            source.get_child_property("font-desc")[1])
        self.font_button.set_font_desc(font_desc)

        color = argb_to_gdk_rgba(source.get_child_property("color")[1])
        self.foreground_color_button.set_rgba(color)

        color = argb_to_gdk_rgba(
            source.get_child_property("foreground-color")[1])
        self.background_color_button.set_rgba(color)

    def _textChangedCb(self, unused_updated_obj):
        if not self.source:
            # Nothing to update.
            return

        text = self.textbuffer.props.text
        self.log("Source text updated to %s", text)
        self._setChildProperty("text", text)

    def _update_source_cb(self, updated_obj):
        """Handles changes in the advanced property widgets at the bottom."""
        if not self.source:
            # Nothing to update.
            return

        for name, obj in list(self.settings.items()):
            if obj == updated_obj:
                if name == "valignment":
                    value = obj.get_active_id()
                    self._updateWidgetsVisibility()
                elif name == "halignment":
                    value = obj.get_active_id()
                    self._updateWidgetsVisibility()
                else:
                    value = obj.get_value()
                self._setChildProperty(name, value)
                return

    def _updateWidgetsVisibility(self):
        visible = self.settings["valignment"].get_active_id() == "absolute"
        self.settings["y-absolute"].set_visible(visible)
        visible = self.settings["halignment"].get_active_id() == "absolute"
        self.settings["x-absolute"].set_visible(visible)

    def set_source(self, source):
        """Sets the clip to be edited with this editor.

        Args:
            source (GES.TitleSource): The source of the clip.
        """
        self.debug("Source set to %s", source)
        if self._children_props_handler is not None:
            self.source.disconnect(self._children_props_handler)
            self._children_props_handler = None
        self.source = None
        if source:
            assert isinstance(source, GES.TextOverlay) or \
                isinstance(source, GES.TitleSource)
            self._updateFromSource(source)
            self.source = source
            self.infobar.hide()
            self.editing_box.show()
            self._children_props_handler = self.source.connect(
                'deep-notify', self._propertyChangedCb)
        else:
            self.infobar.show()
            self.editing_box.hide()

    def _createCb(self, unused_button):
        title_clip = GES.TitleClip()
        duration = self.app.settings.titleClipLength * Gst.MSECOND
        title_clip.set_duration(duration)
        self.app.gui.editor.timeline_ui.insert_clips_on_first_layer(
            [title_clip])
        # Now that the clip is inserted in the timeline, it has a source which
        # can be used to set its properties.
        source = title_clip.get_children(False)[0]
        properties = {
            "text": "",
            "foreground-color": BACKGROUND_DEFAULT_COLOR,
            "color": FOREGROUND_DEFAULT_COLOR,
            "font-desc": DEFAULT_FONT_DESCRIPTION,
            "valignment": DEFAULT_VALIGNMENT,
            "halignment": DEFAULT_HALIGNMENT
        }
        for prop, value in properties.items():
            res = source.set_child_property(prop, value)
            assert res
        # Select it so the Title editor becomes active.
        self._selection.setSelection([title_clip], SELECT)

    def _propertyChangedCb(self, source, unused_gstelement, pspec):
        if self._setting_props:
            self._project.pipeline.commit_timeline()
            return

        control_binding = self.source.get_control_binding(pspec.name)
        if control_binding:
            self.debug("Not handling %s as it is being interpollated",
                       pspec.name)
            return

        value = self.source.get_child_property(pspec.name)[1]
        if pspec.name == "text":
            value = value or ""
            if self.textbuffer.props.text == value:
                return
            self.textbuffer.props.text = value
        elif pspec.name in ["x-absolute", "y-absolute"]:
            if self.settings[pspec.name].get_value() == value:
                return
            self.settings[pspec.name].set_value(value)
        elif pspec.name in ["valignment", "halignment"]:
            value = value.value_name
            if self.settings[pspec.name].get_active_id() == value:
                return
            self.settings[pspec.name].set_active_id(value)
        elif pspec.name == "font-desc":
            if self.font_button.get_font_desc() == value:
                return
            font_desc = Pango.FontDescription.from_string(value)
            self.font_button.set_font_desc(font_desc)
        elif pspec.name == "color":
            color = argb_to_gdk_rgba(value)
            if color == self.foreground_color_button.get_rgba():
                return
            self.foreground_color_button.set_rgba(color)
        elif pspec.name == "foreground-color":
            color = argb_to_gdk_rgba(value)
            if color == self.background_color_button.get_rgba():
                return
            self.background_color_button.set_rgba(color)

        self._project.pipeline.commit_timeline()

    def _newProjectLoadedCb(self, unused_project_manager, project):
        if self._selection is not None:
            self._selection.disconnect_by_func(self._selectionChangedCb)
            self._selection = None
        if project:
            self._selection = project.ges_timeline.ui.selection
            self._selection.connect('selection-changed',
                                    self._selectionChangedCb)
        self._project = project

    def _selectionChangedCb(self, selection):
        selected_clip = selection.getSingleClip(GES.TitleClip)
        source = None
        if selected_clip:
            for child in selected_clip.get_children(False):
                if isinstance(child, GES.TitleSource):
                    source = child
                    break

        self.set_source(source)
Exemplo n.º 8
0
class TitleProperties(Gtk.Expander, Loggable):
    """Widget for configuring a title.

    Attributes:
        app (Pitivi): The app.
    """
    def __init__(self, app):
        Loggable.__init__(self)
        Gtk.Expander.__init__(self)
        self.set_label(_("Title"))
        self.set_expanded(True)
        self.app = app
        self.settings = {}
        self.source = None
        self._setting_props = False
        self._children_props_handler = None

        self._create_ui()

    def _create_ui(self):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(get_ui_dir(), "titleeditor.ui"))
        builder.connect_signals(self)
        # Create UI
        self.add(builder.get_object("box1"))
        self.editing_box = builder.get_object("base_table")

        self.textarea = builder.get_object("textview")

        self.textbuffer = self.textarea.props.buffer
        self.textbuffer.connect("changed", self._text_changed_cb)

        self.font_button = builder.get_object("fontbutton1")
        self.foreground_color_button = builder.get_object("fore_text_color")
        self.background_color_button = builder.get_object("back_color")

        self.color_picker_foreground_widget = ColorPickerButton()
        self.color_picker_foreground_widget.show()
        self.color_picker_foreground = builder.get_object(
            "color_picker_foreground")
        self.color_picker_foreground.add(self.color_picker_foreground_widget)
        self.color_picker_foreground_widget.connect(
            "value-changed", self._color_picker_value_changed_cb,
            self.foreground_color_button, "color")

        self.color_picker_background_widget = ColorPickerButton()
        self.color_picker_background_widget.show()
        self.background_color_picker = builder.get_object(
            "color_picker_background")
        self.background_color_picker.add(self.color_picker_background_widget)
        self.color_picker_background_widget.connect(
            "value-changed", self._color_picker_value_changed_cb,
            self.background_color_button, "foreground-color")

        for widget_id in ("valignment", "halignment", "x-absolute",
                          "y-absolute"):
            self.settings[widget_id] = builder.get_object(widget_id)

        for value_id, text in (("absolute", _("Absolute")), ("top", _("Top")),
                               ("center", _("Center")),
                               ("bottom", _("Bottom")), ("baseline",
                                                         _("Baseline"))):
            self.settings["valignment"].append(value_id, text)

        for value_id, text in (("absolute", _("Absolute")), ("left",
                                                             _("Left")),
                               ("center", _("Center")), ("right", _("Right"))):
            self.settings["halignment"].append(value_id, text)

        self.show_all()

    def _set_child_property(self, name, value):
        with self.app.action_log.started("Title change property",
                                         toplevel=True):
            self._setting_props = True
            try:
                res = self.source.set_child_property(name, value)
                assert res
            finally:
                self._setting_props = False

    def _color_picker_value_changed_cb(self, widget, color_button,
                                       color_layer):
        argb = widget.calculate_argb()
        self.debug("Setting text %s to %x", color_layer, argb)
        self._set_child_property(color_layer, argb)
        rgba = argb_to_gdk_rgba(argb)
        color_button.set_rgba(rgba)

    def _background_color_button_cb(self, widget):
        color = gdk_rgba_to_argb(widget.get_rgba())
        self.debug("Setting title background color to %x", color)
        self._set_child_property("foreground-color", color)

    def _front_text_color_button_cb(self, widget):
        color = gdk_rgba_to_argb(widget.get_rgba())
        self.debug("Setting title foreground color to %x", color)
        # TODO: Use set_text_color when we work with TitleSources instead of
        # TitleClips
        self._set_child_property("color", color)

    def _font_button_cb(self, widget):
        font_desc = widget.get_font_desc().to_string()
        self.debug("Setting font desc to %s", font_desc)
        self._set_child_property("font-desc", font_desc)

    def _update_from_source(self, source):
        self.textbuffer.props.text = html.unescape(
            source.get_child_property("text")[1] or "")
        self.settings["x-absolute"].set_value(
            source.get_child_property("x-absolute")[1])
        self.settings["y-absolute"].set_value(
            source.get_child_property("y-absolute")[1])
        self.settings["valignment"].set_active_id(
            source.get_child_property("valignment")[1].value_name)
        self.settings["halignment"].set_active_id(
            source.get_child_property("halignment")[1].value_name)
        self._update_widgets_visibility()

        font_desc = Pango.FontDescription.from_string(
            source.get_child_property("font-desc")[1])
        self.font_button.set_font_desc(font_desc)

        color = argb_to_gdk_rgba(source.get_child_property("color")[1])
        self.foreground_color_button.set_rgba(color)

        color = argb_to_gdk_rgba(
            source.get_child_property("foreground-color")[1])
        self.background_color_button.set_rgba(color)

    def _text_changed_cb(self, unused_updated_obj):
        if not self.source:
            # Nothing to update.
            return

        escaped_text = html.escape(self.textbuffer.props.text)
        self.log("Source text updated to %s", escaped_text)
        self._set_child_property("text", escaped_text)

    def _update_source_cb(self, updated_obj):
        """Handles changes in the advanced property widgets at the bottom."""
        if not self.source:
            # Nothing to update.
            return

        for name, obj in list(self.settings.items()):
            if obj == updated_obj:
                if name == "valignment":
                    value = obj.get_active_id()
                    self._update_widgets_visibility()
                elif name == "halignment":
                    value = obj.get_active_id()
                    self._update_widgets_visibility()
                else:
                    value = obj.get_value()
                self._set_child_property(name, value)
                return

    def _update_widgets_visibility(self):
        visible = self.settings["valignment"].get_active_id() == "absolute"
        self.settings["y-absolute"].set_visible(visible)
        visible = self.settings["halignment"].get_active_id() == "absolute"
        self.settings["x-absolute"].set_visible(visible)

    def set_source(self, source):
        """Sets the clip to be edited with this editor.

        Args:
            source (GES.TitleSource): The source of the clip.
        """
        self.debug("Setting source to %s", source)
        if self.source:
            self.source.disconnect(self._children_props_handler)
            self._children_props_handler = None

        self.source = source

        if source:
            assert isinstance(source, (GES.TextOverlay, GES.TitleSource))
            self._update_from_source(source)
            self._children_props_handler = self.source.connect(
                "deep-notify", self._source_deep_notify_cb)
        self.set_visible(bool(self.source))

    def _source_deep_notify_cb(self, source, unused_gstelement, pspec):
        """Handles updates in the TitleSource backing the current TitleClip."""
        if self._setting_props:
            self.app.project_manager.current_project.pipeline.commit_timeline()
            return

        control_binding = self.source.get_control_binding(pspec.name)
        if control_binding:
            self.debug("Not handling %s as it is being interpolated",
                       pspec.name)
            return

        if pspec.name == "text":
            res, escaped_text = self.source.get_child_property(pspec.name)
            assert res, pspec.name
            text = html.unescape(escaped_text)
            if self.textbuffer.props.text == text or "":
                return
            self.textbuffer.props.text = text
        elif pspec.name in ["x-absolute", "y-absolute"]:
            res, value = self.source.get_child_property(pspec.name)
            assert res, pspec.name
            if self.settings[pspec.name].get_value() == value:
                return
            self.settings[pspec.name].set_value(value)
        elif pspec.name in ["valignment", "halignment"]:
            res, value = self.source.get_child_property(pspec.name)
            assert res, pspec.name
            value = value.value_name
            if self.settings[pspec.name].get_active_id() == value:
                return
            self.settings[pspec.name].set_active_id(value)
        elif pspec.name == "font-desc":
            res, value = self.source.get_child_property(pspec.name)
            assert res, pspec.name
            if self.font_button.get_font_desc() == value:
                return
            font_desc = Pango.FontDescription.from_string(value)
            self.font_button.set_font_desc(font_desc)
        elif pspec.name == "color":
            res, value = self.source.get_child_property(pspec.name)
            assert res, pspec.name
            color = argb_to_gdk_rgba(value)
            if color == self.foreground_color_button.get_rgba():
                return
            self.foreground_color_button.set_rgba(color)
        elif pspec.name == "foreground-color":
            res, value = self.source.get_child_property(pspec.name)
            assert res, pspec.name
            color = argb_to_gdk_rgba(value)
            if color == self.background_color_button.get_rgba():
                return
            self.background_color_button.set_rgba(color)

        self.app.project_manager.current_project.pipeline.commit_timeline()
Exemplo n.º 9
0
class TitleEditor(Loggable):
    """Widget for configuring a title.

    Attributes:
        app (Pitivi): The app.
        _project (Project): The project.
    """

    def __init__(self, app):
        Loggable.__init__(self)
        self.app = app
        self.settings = {}
        self.source = None
        self._project = None
        self._selection = None

        self._setting_props = False
        self._children_props_handler = None

        self._createUI()
        # Updates the UI.
        self.set_source(None)

        self.app.project_manager.connect_after(
            "new-project-loaded", self._newProjectLoadedCb)

    def _createUI(self):
        builder = Gtk.Builder()
        builder.add_from_file(os.path.join(get_ui_dir(), "titleeditor.ui"))
        builder.connect_signals(self)
        self.widget = builder.get_object("box1")  # To be used by tabsmanager
        self.infobar = builder.get_object("infobar")
        fix_infobar(self.infobar)
        self.editing_box = builder.get_object("base_table")

        self.textarea = builder.get_object("textview")

        self.textbuffer = self.textarea.props.buffer
        self.textbuffer.connect("changed", self._textChangedCb)

        self.font_button = builder.get_object("fontbutton1")
        self.foreground_color_button = builder.get_object("fore_text_color")
        self.background_color_button = builder.get_object("back_color")

        self.color_picker_foreground_widget = ColorPickerButton()
        self.color_picker_foreground_widget.show()
        self.color_picker_foreground = builder.get_object("color_picker_foreground")
        self.color_picker_foreground.add(self.color_picker_foreground_widget)
        self.color_picker_foreground_widget.connect("value-changed", self._color_picker_value_changed_cb, self.foreground_color_button, "color")

        self.color_picker_background_widget = ColorPickerButton()
        self.color_picker_background_widget.show()
        self.background_color_picker = builder.get_object("color_picker_background")
        self.background_color_picker.add(self.color_picker_background_widget)
        self.color_picker_background_widget.connect("value-changed", self._color_picker_value_changed_cb, self.background_color_button, "foreground-color")

        settings = ["valignment", "halignment", "x-absolute", "y-absolute"]
        for setting in settings:
            self.settings[setting] = builder.get_object(setting)

        for n, en in list({_("Absolute"): "absolute",
                           _("Top"): "top",
                           _("Center"): "center",
                           _("Bottom"): "bottom",
                           _("Baseline"): "baseline"}.items()):
            self.settings["valignment"].append(en, n)

        for n, en in list({_("Absolute"): "absolute",
                           _("Left"): "left",
                           _("Center"): "center",
                           _("Right"): "right"}.items()):
            self.settings["halignment"].append(en, n)

    def _setChildProperty(self, name, value):
        with self.app.action_log.started("Title change property",
                                         toplevel=True):
            self._setting_props = True
            try:
                res = self.source.set_child_property(name, value)
                assert res
            finally:
                self._setting_props = False

    def _color_picker_value_changed_cb(self, widget, colorButton, colorLayer):
        argb = 0
        argb += (1 * 255) * 256 ** 3
        argb += float(widget.color_r) * 256 ** 2
        argb += float(widget.color_g) * 256 ** 1
        argb += float(widget.color_b) * 256 ** 0
        self.debug("Setting text %s to %x", colorLayer, argb)
        self._setChildProperty(colorLayer, argb)
        rgba = argb_to_gdk_rgba(argb)
        colorButton.set_rgba(rgba)

    def _backgroundColorButtonCb(self, widget):
        color = gdk_rgba_to_argb(widget.get_rgba())
        self.debug("Setting title background color to %x", color)
        self._setChildProperty("foreground-color", color)

    def _frontTextColorButtonCb(self, widget):
        color = gdk_rgba_to_argb(widget.get_rgba())
        self.debug("Setting title foreground color to %x", color)
        # TODO: Use set_text_color when we work with TitleSources instead of
        # TitleClips
        self._setChildProperty("color", color)

    def _fontButtonCb(self, widget):
        font_desc = widget.get_font_desc().to_string()
        self.debug("Setting font desc to %s", font_desc)
        self._setChildProperty("font-desc", font_desc)

    def _updateFromSource(self, source):
        self.textbuffer.set_text(source.get_child_property("text")[1] or "")
        self.settings['x-absolute'].set_value(source.get_child_property("x-absolute")[1])
        self.settings['y-absolute'].set_value(source.get_child_property("y-absolute")[1])
        self.settings['valignment'].set_active_id(
            source.get_child_property("valignment")[1].value_name)
        self.settings['halignment'].set_active_id(
            source.get_child_property("halignment")[1].value_name)
        self._updateWidgetsVisibility()

        font_desc = Pango.FontDescription.from_string(
            source.get_child_property("font-desc")[1])
        self.font_button.set_font_desc(font_desc)

        color = argb_to_gdk_rgba(source.get_child_property("color")[1])
        self.foreground_color_button.set_rgba(color)

        color = argb_to_gdk_rgba(source.get_child_property("foreground-color")[1])
        self.background_color_button.set_rgba(color)

    def _textChangedCb(self, unused_updated_obj):
        if not self.source:
            # Nothing to update.
            return

        text = self.textbuffer.props.text
        self.log("Source text updated to %s", text)
        self._setChildProperty("text", text)

    def _update_source_cb(self, updated_obj):
        """Handles changes in the advanced property widgets at the bottom."""
        if not self.source:
            # Nothing to update.
            return

        for name, obj in list(self.settings.items()):
            if obj == updated_obj:
                if name == "valignment":
                    value = obj.get_active_id()
                    self._updateWidgetsVisibility()
                elif name == "halignment":
                    value = obj.get_active_id()
                    self._updateWidgetsVisibility()
                else:
                    value = obj.get_value()
                self._setChildProperty(name, value)
                return

    def _updateWidgetsVisibility(self):
        visible = self.settings["valignment"].get_active_id() == "absolute"
        self.settings["y-absolute"].set_visible(visible)
        visible = self.settings["halignment"].get_active_id() == "absolute"
        self.settings["x-absolute"].set_visible(visible)

    def set_source(self, source):
        """Sets the clip to be edited with this editor.

        Args:
            source (GES.TitleSource): The source of the clip.
        """
        self.debug("Source set to %s", source)
        if self._children_props_handler is not None:
            self.source.disconnect(self._children_props_handler)
            self._children_props_handler = None
        self.source = None
        if source:
            assert isinstance(source, GES.TextOverlay) or \
                isinstance(source, GES.TitleSource)
            self._updateFromSource(source)
            self.source = source
            self.infobar.hide()
            self.editing_box.show()
            self._children_props_handler = self.source.connect('deep-notify',
                                                               self._propertyChangedCb)
        else:
            self.infobar.show()
            self.editing_box.hide()

    def _createCb(self, unused_button):
        title_clip = GES.TitleClip()
        duration = self.app.settings.titleClipLength * Gst.MSECOND
        title_clip.set_duration(duration)
        self.app.gui.editor.timeline_ui.insert_clips_on_first_layer([title_clip])
        # Now that the clip is inserted in the timeline, it has a source which
        # can be used to set its properties.
        source = title_clip.get_children(False)[0]
        properties = {"text": "",
                      "foreground-color": BACKGROUND_DEFAULT_COLOR,
                      "color": FOREGROUND_DEFAULT_COLOR,
                      "font-desc": DEFAULT_FONT_DESCRIPTION,
                      "valignment": DEFAULT_VALIGNMENT,
                      "halignment": DEFAULT_HALIGNMENT}
        for prop, value in properties.items():
            res = source.set_child_property(prop, value)
            assert res
        # Select it so the Title editor becomes active.
        self._selection.setSelection([title_clip], SELECT)
        self.app.gui.editor.timeline_ui.timeline.resetSelectionGroup()
        self.app.gui.editor.timeline_ui.timeline.current_group.add(title_clip)

    def _propertyChangedCb(self, source, unused_gstelement, pspec):
        if self._setting_props:
            self._project.pipeline.commit_timeline()
            return

        control_binding = self.source.get_control_binding(pspec.name)
        if control_binding:
            self.debug("Not handling %s as it is being interpollated",
                       pspec.name)
            return

        value = self.source.get_child_property(pspec.name)[1]
        if pspec.name == "text":
            value = value or ""
            if self.textbuffer.props.text == value:
                return
            self.textbuffer.props.text = value
        elif pspec.name in ["x-absolute", "y-absolute"]:
            if self.settings[pspec.name].get_value() == value:
                return
            self.settings[pspec.name].set_value(value)
        elif pspec.name in ["valignment", "halignment"]:
            value = value.value_name
            if self.settings[pspec.name].get_active_id() == value:
                return
            self.settings[pspec.name].set_active_id(value)
        elif pspec.name == "font-desc":
            if self.font_button.get_font_desc() == value:
                return
            font_desc = Pango.FontDescription.from_string(value)
            self.font_button.set_font_desc(font_desc)
        elif pspec.name == "color":
            color = argb_to_gdk_rgba(value)
            if color == self.foreground_color_button.get_rgba():
                return
            self.foreground_color_button.set_rgba(color)
        elif pspec.name == "foreground-color":
            color = argb_to_gdk_rgba(value)
            if color == self.background_color_button.get_rgba():
                return
            self.background_color_button.set_rgba(color)

        self._project.pipeline.commit_timeline()

    def _newProjectLoadedCb(self, app, project):
        if self._selection is not None:
            self._selection.disconnect_by_func(self._selectionChangedCb)
            self._selection = None
        if project:
            self._selection = project.ges_timeline.ui.selection
            self._selection.connect('selection-changed', self._selectionChangedCb)
        self._project = project

    def _selectionChangedCb(self, selection):
        selected_clip = selection.getSingleClip(GES.TitleClip)
        source = None
        if selected_clip:
            for child in selected_clip.get_children(False):
                if isinstance(child, GES.TitleSource):
                    source = child
                    break

        self.set_source(source)
Exemplo n.º 10
0
class ColorProperties(Gtk.Expander, Loggable):
    """Widget for configuring the properties of a color clip."""
    def __init__(self, app):
        Gtk.Expander.__init__(self)
        Loggable.__init__(self)

        self.app = app
        self.source = None
        self._children_props_handler = None

        self.set_label(_("Color"))
        self.set_expanded(True)

        self._create_ui()

    def _create_ui(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_file(os.path.join(get_ui_dir(), "clipcolor.ui"))
        self.builder.connect_signals(self)

        box = self.builder.get_object("color_box")
        self.add(box)

        self.color_button = self.builder.get_object("color_button")

        self.color_picker_button = ColorPickerButton()
        box.add(self.color_picker_button)
        self.color_picker_button.connect("value-changed",
                                         self._color_picker_value_changed_cb)

        self.show_all()

    def _set_child_property(self, name, value):
        with self.app.action_log.started(
                "Color change property",
                finalizing_action=CommitTimelineFinalizingAction(
                    self.app.project_manager.current_project.pipeline),
                toplevel=True):
            res = self.source.set_child_property(name, value)
            assert res

    def _color_picker_value_changed_cb(self, widget):
        argb = widget.calculate_argb()
        self._set_child_property("foreground-color", argb)

    def _color_button_cb(self, widget):
        argb = gdk_rgba_to_argb(widget.get_rgba())
        self._set_child_property("foreground-color", argb)

    def set_source(self, source):
        """Sets the clip source to be edited with this editor.

        Args:
            source (GES.VideoTestSource): The source of the clip.
        """
        self.debug("Source set to %s", source)
        if self._children_props_handler is not None:
            self.source.disconnect(self._children_props_handler)
            self._children_props_handler = None
        self.source = None
        if source:
            assert isinstance(source, GES.VideoTestSource)
            self.source = source
            self._update_color_button()
            self._children_props_handler = self.source.connect(
                "deep-notify", self._source_deep_notify_cb)
        self.set_visible(bool(self.source))

    def _source_deep_notify_cb(self, source, unused_gstelement, pspec):
        """Handles updates in the VideoTestSource backing the current TestClip."""
        if pspec.name == "foreground-color":
            self._update_color_button()

    def _update_color_button(self):
        res, argb = self.source.get_child_property("foreground-color")
        assert res
        color = argb_to_gdk_rgba(argb)
        self.color_button.set_rgba(color)
Exemplo n.º 11
0
def create_alpha_widget(effect_prop_manager, element_setting_widget, element):
    """Creates the UI for the `alpha` effect."""
    builder = setup_from_ui_file(element_setting_widget, os.path.join(CUSTOM_WIDGETS_DIR, "alpha.ui"))

    color_picker = ColorPickerButton(0, 255, 0)
    color_picker_frame = builder.get_object("color_picker_frame")
    color_picker_frame.add(color_picker)

    # Additional Setup

    # All modes other than custom RGB chroma keying are useless to us.
    # "ALPHA_METHOD_CUSTOM" corresponds to "3"
    Loggable().debug("Setting alpha's method to 3 (custom RGB chroma keying)")
    element.set_child_property("method", 3)

    # Color button and picker has to be connected manually!

    def get_current_rgba():
        """Gets the color used by the effect."""
        color = Gdk.RGBA()
        res, red = element.get_child_property("target-r")
        assert res
        res, green = element.get_child_property("target-g")
        assert res
        res, blue = element.get_child_property("target-b")
        assert res
        color.red = red / 255
        color.green = green / 255
        color.blue = blue / 255
        return color

    def color_button_color_set_cb(color_button):
        """Handles the selection of a color with the color button."""
        color = color_button.get_rgba()
        red = int(color.red * 255)
        green = int(color.green * 255)
        blue = int(color.blue * 255)
        from pitivi.undo.timeline import CommitTimelineFinalizingAction
        pipeline = effect_prop_manager.app.project_manager.current_project.pipeline
        action_log = effect_prop_manager.app.action_log
        with action_log.started("Effect property change",
                                finalizing_action=CommitTimelineFinalizingAction(pipeline),
                                toplevel=True):
            element.set_child_property("target-r", red)
            element.set_child_property("target-g", green)
            element.set_child_property("target-b", blue)

    color_button = builder.get_object("colorbutton")
    color_button.connect("color-set", color_button_color_set_cb)

    def color_picker_value_changed_cb(unused_color_picker_button):
        """Handles the selection of a color with the color picker button."""
        from pitivi.undo.timeline import CommitTimelineFinalizingAction
        pipeline = effect_prop_manager.app.project_manager.current_project.pipeline
        action_log = effect_prop_manager.app.action_log
        with action_log.started("Color Picker Change",
                                finalizing_action=CommitTimelineFinalizingAction(pipeline),
                                toplevel=True):
            element.set_child_property("target-r", color_picker.color_r)
            element.set_child_property("target-g", color_picker.color_g)
            element.set_child_property("target-b", color_picker.color_b)

    color_picker.connect("value-changed", color_picker_value_changed_cb)

    def property_changed_cb(unused_effect, gst_element, pspec):
        """Handles the change of a GObject property."""
        if gst_element.get_control_binding(pspec.name):
            Loggable().log("%s controlled, not displaying value", pspec.name)
            return

        widget = element_setting_widget.properties.get(pspec)
        if not widget:
            return

        res, value = element_setting_widget.element.get_child_property(pspec.name)
        assert res

        if pspec.name in ("target-r", "target-g", "target-b"):
            color_button.set_rgba(get_current_rgba())
            widget.block_signals()
            try:
                widget.setWidgetValue(value)
            finally:
                widget.unblock_signals()
        else:
            widget.setWidgetValue(value)

    element.connect("deep-notify", property_changed_cb)

    return builder.get_object("base_table")