aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--voctogui/lib/audioselector.py63
-rw-r--r--voctogui/lib/toolbar/composition.py33
-rw-r--r--voctogui/lib/ui.py32
-rw-r--r--voctogui/lib/videopreviews.py86
-rw-r--r--voctogui/ui/voctogui.ui40
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>