Commit b6e72e2f authored by Suhas's avatar Suhas Committed by Alexandru Băluț

Add a custom user interface for chroma keying with the Alpha filter

Co-authored-by: Jean-François Fortin Tam's avatarJean-François Fortin Tam <nekohayo@gmail.com>
Co-authored-by: 's avatarThibault Saunier <thibault.saunier@collabora.com>

Differential Revision: https://phabricator.freedesktop.org/D1745
parent 00ab81d3
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkAdjustment" id="alpha_adjustment">
<property name="upper">1</property>
<property name="value">1</property>
<property name="step_increment">0.01</property>
<property name="page_increment">0.10000000000000001</property>
</object>
<object class="GtkAdjustment" id="angle_adjustment">
<property name="upper">90</property>
<property name="value">20</property>
<property name="step_increment">0.10000000000000001</property>
<property name="page_increment">1</property>
</object>
<object class="GtkAdjustment" id="black_sens_adjustment">
<property name="upper">128</property>
<property name="value">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="blue_color_adjustment">
<property name="upper">255</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="green_color_adjustment">
<property name="upper">255</property>
<property name="value">255</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">edit-clear-all-symbolic</property>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">edit-clear-all-symbolic</property>
</object>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">edit-clear-all-symbolic</property>
</object>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">edit-clear-all-symbolic</property>
</object>
<object class="GtkImage" id="image5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">edit-clear-all-symbolic</property>
</object>
<object class="GtkListStore" id="liststore1"/>
<object class="GtkAdjustment" id="noise_adjustment">
<property name="upper">64</property>
<property name="value">2</property>
<property name="step_increment">0.10000000000000001</property>
<property name="page_increment">1</property>
</object>
<object class="GtkAdjustment" id="red_color_adjustment">
<property name="upper">255</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="white_sens_adjustment">
<property name="upper">128</property>
<property name="value">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkGrid" id="base_table">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="row_spacing">8</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkButton" id="GstAlpha::angle::reset">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image1</property>
<property name="relief">none</property>
<property name="image_position">top</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="GstAlpha::noise-level::reset">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image2</property>
<property name="relief">none</property>
<property name="image_position">top</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="GstAlpha::white-sensitivity::reset">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image3</property>
<property name="relief">none</property>
<property name="image_position">top</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="GstAlpha::black-sensitivity::reset">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image4</property>
<property name="relief">none</property>
<property name="image_position">top</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Angle:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Noise level:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">White sensitivity:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Black sensitivity:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkScale" id="GstAlpha::angle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">angle_adjustment</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">1</property>
<property name="round_digits">2</property>
<property name="value_pos">left</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkScale" id="GstAlpha::noise-level">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">noise_adjustment</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">1</property>
<property name="round_digits">2</property>
<property name="value_pos">left</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkScale" id="GstAlpha::white-sensitivity">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">white_sens_adjustment</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">1</property>
<property name="round_digits">2</property>
<property name="digits">0</property>
<property name="value_pos">left</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkScale" id="GstAlpha::black-sensitivity">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">black_sens_adjustment</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">1</property>
<property name="round_digits">2</property>
<property name="digits">0</property>
<property name="value_pos">left</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="GstAlpha::angle::keyframe">
<property name="label" translatable="yes"></property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<property name="image_position">top</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="GstAlpha::noise-level::keyframe">
<property name="label" translatable="yes"></property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="GstAlpha::white-sensitivity::keyframe">
<property name="label" translatable="yes"></property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="GstAlpha::black-sensitivity::keyframe">
<property name="label" translatable="yes"></property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkSeparator" id="separator2">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Alpha:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkScale" id="GstAlpha::alpha">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">alpha_adjustment</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">1</property>
<property name="round_digits">1</property>
<property name="digits">2</property>
<property name="value_pos">left</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Target chroma key:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Red</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">8</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Green</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">8</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="GstAlpha::target-b">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">blue_color_adjustment</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">7</property>
</packing>
</child>
<child>
<object class="GtkColorButton" id="colorbutton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="title" translatable="yes">Select a color</property>
<property name="rgba">rgb(0,255,0)</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">7</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Blue</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">8</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="GstAlpha::target-g">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">green_color_adjustment</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">7</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="GstAlpha::target-r">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">red_color_adjustment</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
</packing>
</child>
<child>
<object class="GtkButton" id="GstAlpha::alpha::reset">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image5</property>
<property name="relief">none</property>
<property name="image_position">top</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkAspectFrame" id="color_picker_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">7</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</interface>
......@@ -19,9 +19,12 @@
"""Utility methods for custom effect UI."""
import os
from gi.repository import Gdk
from gi.repository import Gtk
from pitivi import configure
from pitivi.utils.loggable import Loggable
from pitivi.utils.widgets import ColorPickerButton
CUSTOM_WIDGETS_DIR = os.path.join(configure.get_ui_dir(), "customwidgets")
......@@ -50,13 +53,18 @@ def create_custom_prop_widget_cb(unused_effect_prop_manager, effect_widget, effe
return create_custom_alpha_prop_widget(effect_widget, effect, prop, prop_value)
def create_custom_widget_cb(unused_effect_prop_manager, effect_widget, effect):
def create_custom_widget_cb(effect_prop_manager, effect_widget, effect):
"""Creates custom effect UI."""
effect_name = effect.get_property("bin-description")
path = os.path.join(CUSTOM_WIDGETS_DIR, effect_name + ".ui")
if not os.path.isfile(path):
return None
# Write individual effect callbacks here
if effect_name == "alpha":
widget = create_alpha_widget(effect_prop_manager, effect_widget, effect)
return widget
# Check if there is a UI file available as a glade file
# Assuming a GtkGrid called base_table exists
builder = setup_from_ui_file(effect_widget, path)
......@@ -64,10 +72,96 @@ def create_custom_widget_cb(unused_effect_prop_manager, effect_widget, effect):
return widget
def create_alpha_widget(unused_element_setting_widget, unused_element):
"""Not implemented yet."""
# Main alpha widget would go here
return None
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")
def create_custom_alpha_prop_widget(unused_element_setting_widget, unused_element, unused_prop, unused_prop_value):
......
......@@ -225,6 +225,7 @@ class NumericWidget(Gtk.Box, DynamicWidget):
self.set_spacing(SPACING)
self._type = None
self.spinner = None
self.handler_id = None
if adjustment:
self.adjustment = adjustment
......@@ -264,8 +265,14 @@ class NumericWidget(Gtk.Box, DynamicWidget):
self.spinner.show()
disable_scroll(self.spinner)
def block_signals(self):
self.adjustment.handler_block(self.handler_id)
def unblock_signals(self):
self.adjustment.handler_unblock(self.handler_id)
def connectValueChanged(self, callback, *args):
self.adjustment.connect("value-changed", callback, *args)
self.handler_id = self.adjustment.connect("value-changed", callback, *args)
def getWidgetValue(self):
if self._type:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment