diff options
-rw-r--r-- | voctogui/lib/audioselector.py | 63 | ||||
-rw-r--r-- | voctogui/lib/toolbar/composition.py | 33 | ||||
-rw-r--r-- | voctogui/lib/ui.py | 32 | ||||
-rw-r--r-- | voctogui/lib/videopreviews.py | 86 | ||||
-rw-r--r-- | voctogui/ui/voctogui.ui | 40 |
5 files changed, 215 insertions, 39 deletions
diff --git a/voctogui/lib/audioselector.py b/voctogui/lib/audioselector.py new file mode 100644 index 0000000..8ad84e3 --- /dev/null +++ b/voctogui/lib/audioselector.py @@ -0,0 +1,63 @@ +import logging +from gi.repository import Gst, Gdk, GLib + +class AudioSelectorController(object): + """ Displays a Level-Meter of another VideoDisplay into a GtkWidget """ + + def __init__(self, drawing_area, win, uibuilder): + self.log = logging.getLogger('AudioSelectorController') + + self.drawing_area = drawing_area + self.win = win + + combo = uibuilder.find_widget_recursive(win, 'combo_audio') + combo.connect('changed', self.on_changed) + #combo.set_sensitive(True) + self.combo = combo + + eventbox = uibuilder.find_widget_recursive(win, 'combo_audio_events') + eventbox.connect('button_press_event', self.on_button_press_event) + eventbox.set_property('above_child', True) + self.eventbox = eventbox + + combo.remove_all() + combo.append('moobar', 'Moo Bar') + combo.append('moofar', 'Moo Far') + + combo.set_active_id('moobar') + + self.timer_iteration = 0 + + def on_button_press_event(self, combo, event): + if event.type != Gdk.EventType.DOUBLE_BUTTON_PRESS: + return + + self.log.debug('double-clicked, unlocking') + self.set_enabled(True) + GLib.timeout_add_seconds(5, self.on_disabled_timer, self.timer_iteration) + + def on_disabled_timer(self, timer_iteration): + if timer_iteration != self.timer_iteration: + self.log.debug('lock-timer fired late, ignoring') + return + + self.log.debug('lock-timer fired, locking') + self.set_enabled(False) + return False + + def set_enabled(self, enable): + self.combo.set_sensitive(enable) + self.eventbox.set_property('above_child', not enable) + + def is_enabled(self): + return self.combo.get_sensitive() + + def on_changed(self, combo): + if not self.is_enabled(): + return + + self.timer_iteration += 1 + + value = combo.get_active_text() + self.log.debug('changed to %s', value) + self.set_enabled(False) diff --git a/voctogui/lib/toolbar/composition.py b/voctogui/lib/toolbar/composition.py new file mode 100644 index 0000000..0185b7d --- /dev/null +++ b/voctogui/lib/toolbar/composition.py @@ -0,0 +1,33 @@ +import logging +from gi.repository import Gtk + +class CompositionToolbarController(object): + """ Manages Accelerators and Clicks on the Composition Toolbar-Buttons """ + + def __init__(self, drawing_area, win, uibuilder): + self.log = logging.getLogger('CompositionToolbarController') + + accelerators = Gtk.AccelGroup() + win.add_accel_group(accelerators) + + composites = [ + 'composite-fullscreen', + 'composite-picture-in-picture', + 'composite-side-by-side-equal', + 'composite-side-by-side-preview' + ] + + for idx, name in enumerate(composites): + key, mod = Gtk.accelerator_parse('F%u' % (idx+1)) + btn = uibuilder.find_widget_recursive(drawing_area, name) + btn.set_name(name) + + # Thanks to http://stackoverflow.com/a/19739855/1659732 + btn.get_child().add_accelerator('clicked', accelerators, key, mod, Gtk.AccelFlags.VISIBLE) + btn.connect('toggled', self.on_btn_toggled) + + def on_btn_toggled(self, btn): + if not btn.get_active(): + return + + self.log.info("on_btn_toggled: %s", btn.get_name()) diff --git a/voctogui/lib/ui.py b/voctogui/lib/ui.py index 134bc2c..9143e12 100644 --- a/voctogui/lib/ui.py +++ b/voctogui/lib/ui.py @@ -9,10 +9,10 @@ from lib.videodisplay import VideoDisplay from lib.audioleveldisplay import AudioLevelDisplay from lib.warningoverlay import VideoWarningOverlay -# from lib.videopreviews import VideoPreviewsController -# from lib.audioselector import AudioSelectorController +from lib.videopreviews import VideoPreviewsController +from lib.audioselector import AudioSelectorController -# from lib.toolbar.composition import CompositionToolbarController +from lib.toolbar.composition import CompositionToolbarController # from lib.toolbar.streamblank import StreamblankToolbarController # from lib.toolbar.specialfunctions import SpecialFunctionsToolbarController @@ -50,16 +50,22 @@ class Ui(UiBuilder): # Setup Preview Controller - # drawing_area = self.find_widget_recursive(self.win, 'box_left') - # self.video_previews_controller = VideoPreviewsController(drawing_area) - - # drawing_area = self.find_widget_recursive(self.win, 'combo_audio') - # self.audio_selector_controller = AudioSelectorController(drawing_area)# - - - # # Setup Toolbar Controllers - # toolbar = self.find_widget_recursive(self.win, 'toolbar') - # self.composition_toolbar_controller = CompositionToolbarController(toolbar) + drawing_area = self.find_widget_recursive(self.win, 'box_left') + self.video_previews_controller = VideoPreviewsController(drawing_area, + win=self.win, + uibuilder=self) + + drawing_area = self.find_widget_recursive(self.win, 'combo_audio') + self.audio_selector_controller = AudioSelectorController(drawing_area, + win=self.win, + uibuilder=self) + + + # Setup Toolbar Controllers + toolbar = self.find_widget_recursive(self.win, 'toolbar') + self.composition_toolbar_controller = CompositionToolbarController(toolbar, + win=self.win, + uibuilder=self) # self.streamblank_toolbar_controller = StreamblankToolbarController(toolbar, # warning_overlay=self.video_warning_overlay) diff --git a/voctogui/lib/videopreviews.py b/voctogui/lib/videopreviews.py new file mode 100644 index 0000000..d6a18ec --- /dev/null +++ b/voctogui/lib/videopreviews.py @@ -0,0 +1,86 @@ +import logging +from gi.repository import Gst, Gtk + +from lib.videodisplay import VideoDisplay + +class VideoPreviewsController(object): + """ Displays Video-Previews and selection Buttons for them """ + + def __init__(self, drawing_area, win, uibuilder): + self.log = logging.getLogger('VideoPreviewsController') + + self.drawing_area = drawing_area + self.win = win + + self.sources = ['cam1', 'cam2', 'grabber'] + self.preview_players = {} + self.previews = {} + + try: + width = Config.getint('previews', 'width') + self.log.debug('Preview-Width configured to %u', width) + except: + width = 320 + self.log.debug('Preview-Width selected as %u', width) + + try: + height = Config.getint('previews', 'height') + self.log.debug('Preview-Height configured to %u', width) + except: + height = width*9/16 + self.log.debug('Preview-Height calculated to %u', width) + + # Accelerators + accelerators = Gtk.AccelGroup() + win.add_accel_group(accelerators) + + group_a = None + group_b = None + + for idx, source in enumerate(self.sources): + self.log.info('Initializing Video Preview %s', source) + + preview = uibuilder.get_check_widget('widget_preview', clone=True) + video = uibuilder.find_widget_recursive(preview, 'video') + + video.set_size_request(width, height) + drawing_area.pack_start(preview, fill=False, expand=False, padding=0) + + player = VideoDisplay(video, port=13000 + idx) + + uibuilder.find_widget_recursive(preview, 'label').set_label(source) + btn_a = uibuilder.find_widget_recursive(preview, 'btn_a') + btn_b = uibuilder.find_widget_recursive(preview, 'btn_b') + + btn_a.set_name("%c %u" % ('a', idx)) + btn_b.set_name("%c %u" % ('b', idx)) + + if not group_a: + group_a = btn_a + else: + btn_a.join_group(group_a) + + + if not group_b: + group_b = btn_b + else: + btn_b.join_group(group_b) + + + btn_a.connect('toggled', self.btn_toggled) + btn_b.connect('toggled', self.btn_toggled) + + key, mod = Gtk.accelerator_parse('%u' % (idx+1)) + btn_a.add_accelerator('activate', accelerators, key, mod, Gtk.AccelFlags.VISIBLE) + + key, mod = Gtk.accelerator_parse('<Ctrl>%u' % (idx+1)) + btn_b.add_accelerator('activate', accelerators, key, mod, Gtk.AccelFlags.VISIBLE) + + self.preview_players[source] = player + self.previews[source] = preview + + def btn_toggled(self, btn): + if not btn.get_active(): + return + + self.log.info('btn_toggled: %s', btn.get_name()) diff --git a/voctogui/ui/voctogui.ui b/voctogui/ui/voctogui.ui index 5e0deb2..eac6794 100644 --- a/voctogui/ui/voctogui.ui +++ b/voctogui/ui/voctogui.ui @@ -32,20 +32,6 @@ <property name="can_focus">False</property> <property name="pixbuf">stream-live.svg</property> </object> - <object class="GtkListStore" id="liststore_audio"> - <columns> - <!-- column-name name --> - <column type="gchararray"/> - </columns> - <data> - <row> - <col id="0" translatable="yes">cam1</col> - </row> - <row> - <col id="0" translatable="yes">cam2</col> - </row> - </data> - </object> <object class="GtkWindow" id="window"> <property name="can_focus">False</property> <property name="default_width">1280</property> @@ -226,21 +212,23 @@ </packing> </child> <child> - <object class="GtkComboBox" id="combo_audio"> + <object class="GtkEventBox" id="combo_audio_events"> <property name="visible">True</property> - <property name="sensitive">False</property> <property name="can_focus">False</property> - <property name="margin_left">5</property> - <property name="margin_right">5</property> - <property name="margin_top">5</property> - <property name="margin_bottom">5</property> - <property name="model">liststore_audio</property> - <property name="id_column">0</property> + <property name="events">GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK</property> <child> - <object class="GtkCellRendererText" id="cellrenderertext"/> - <attributes> - <attribute name="text">0</attribute> - </attributes> + <object class="GtkComboBoxText" id="combo_audio"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">False</property> + <property name="events">GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK</property> + <property name="margin_top">5</property> + <property name="margin_bottom">5</property> + <items> + <item translatable="yes">Foo</item> + <item translatable="yes">Bar</item> + </items> + </object> </child> </object> <packing> |