summaryrefslogtreecommitdiff
path: root/voctogui/lib/ui.py
blob: 3d7cda7edbd577bb943b9001ef4655d54b9eaf32 (plain)
  1. #!/usr/bin/python3
  2. import gi, logging
  3. from gi.repository import Gtk, Gst, Gdk, GLib
  4. from lib.config import Config
  5. from lib.uibuilder import UiBuilder
  6. from lib.videodisplay import VideoDisplay
  7. class Ui(UiBuilder):
  8. def __init__(self, uifile):
  9. self.log = logging.getLogger('Ui')
  10. super().__init__(uifile)
  11. def setup(self):
  12. self.log.info('Initializing Ui')
  13. # Aquire the Main-Window from the UI-File
  14. self.win = self.get_check_widget('window')
  15. # Connect Close-Handler
  16. self.win.connect('delete-event', Gtk.main_quit)
  17. self.previews = {}
  18. self.preview_players = {}
  19. self.configure_toolbar_accelerators()
  20. self.configure_video_main()
  21. self.configure_video_previews()
  22. self.configure_audio_selector()
  23. self.configure_streamblank_selector()
  24. def configure_toolbar_accelerators(self):
  25. accelerators = Gtk.AccelGroup()
  26. self.win.add_accel_group(accelerators)
  27. composites = [
  28. 'composite-fullscreen',
  29. 'composite-picture-in-picture',
  30. 'composite-side-by-side-equal',
  31. 'composite-side-by-side-preview'
  32. ]
  33. for idx, name in enumerate(composites):
  34. key, mod = Gtk.accelerator_parse('F%u' % (idx+1))
  35. btn = self.find_widget_recursive(self.win, name)
  36. btn.set_name(name)
  37. # Thanks to http://stackoverflow.com/a/19739855/1659732
  38. btn.get_child().add_accelerator('clicked', accelerators, key, mod, Gtk.AccelFlags.VISIBLE)
  39. btn.connect('toggled', self.composite_btn_toggled)
  40. def composite_btn_toggled(self, btn):
  41. if not btn.get_active():
  42. return
  43. self.log.info("composite_btn_toggled: %s", btn.get_name())
  44. def configure_video_main(self):
  45. self.log.info('Initializing Main Video and Main Audio-Level View')
  46. video = self.find_widget_recursive(self.win, 'video_main')
  47. audiolevel = self.find_widget_recursive(self.win, 'audiolevel_main')
  48. self.video_main_player = VideoDisplay(11000, video, audiolevel,
  49. playaudio=Config.getboolean('mainvideo', 'playaudio'))
  50. def configure_video_previews(self):
  51. self.log.info('Initializing Video Previews')
  52. sources = ['cam1', 'cam2', 'grabber']
  53. box = self.find_widget_recursive(self.win, 'box_left')
  54. try:
  55. width = Config.getint('previews', 'width')
  56. self.log.debug('Preview-Width configured to %u', width)
  57. except:
  58. width = 320
  59. self.log.debug('Preview-Width selected as %u', width)
  60. try:
  61. height = Config.getint('previews', 'height')
  62. self.log.debug('Preview-Height configured to %u', width)
  63. except:
  64. height = width*9/16
  65. self.log.debug('Preview-Height calculated to %u', width)
  66. # Accelerators
  67. accelerators = Gtk.AccelGroup()
  68. self.win.add_accel_group(accelerators)
  69. for idx, source in enumerate(sources):
  70. self.log.info('Initializing Video Preview %s', source)
  71. preview = self.get_check_widget('widget_preview', clone=True)
  72. video = self.find_widget_recursive(preview, 'video')
  73. video.set_size_request(width, height)
  74. box.pack_start(preview, fill=False, expand=False, padding=0)
  75. player = VideoDisplay(13000 + idx, video)
  76. self.find_widget_recursive(preview, 'label').set_label(source)
  77. btn_a = self.find_widget_recursive(preview, 'btn_a')
  78. btn_b = self.find_widget_recursive(preview, 'btn_b')
  79. btn_a.connect('toggled', self.preview_btn_toggled)
  80. btn_b.connect('toggled', self.preview_btn_toggled)
  81. key, mod = Gtk.accelerator_parse('%u' % (idx+1))
  82. btn_a.add_accelerator('activate', accelerators, key, mod, Gtk.AccelFlags.VISIBLE)
  83. key, mod = Gtk.accelerator_parse('<Ctrl>%u' % (idx+1))
  84. btn_b.add_accelerator('activate', accelerators, key, mod, Gtk.AccelFlags.VISIBLE)
  85. self.preview_players[source] = player
  86. self.previews[source] = preview
  87. def preview_btn_toggled(self, btn):
  88. self.log.info('preview_btn_toggled')
  89. def configure_audio_selector(self):
  90. self.log.info('Initializing Audio Selector')
  91. combo = self.find_widget_recursive(self.win, 'combo_audio')
  92. combo.set_sensitive(True)
  93. # FIXME access via combo_audio?
  94. liststore = self.get_check_widget('liststore_audio')
  95. liststore.clear()
  96. row = liststore.append()
  97. liststore.set(row, [0], ['foobar'])
  98. row = liststore.append('')
  99. liststore.set(row, [0], ['moofar'])
  100. combo.set_active_id('moofar')
  101. def configure_streamblank_selector(self):
  102. livebtn = self.get_check_widget('stream_live')
  103. blankbtn = self.get_check_widget('stream_blank')
  104. toolbar = blankbtn.get_parent()
  105. pos = toolbar.get_item_index(blankbtn)
  106. self.blink_btn = None
  107. self.blink_btn_state = False
  108. livebtn.connect('toggled', self.streamblank_button_toggled)
  109. livebtn.set_name('live')
  110. GLib.timeout_add_seconds(1, self.blink_streamblank_button)
  111. for idx, name in enumerate(['pause', 'nostream']):
  112. if idx == 0:
  113. new_btn = blankbtn
  114. else:
  115. new_icon = Gtk.Image.new_from_pixbuf(blankbtn.get_icon_widget().get_pixbuf())
  116. new_btn = Gtk.RadioToolButton(group=livebtn)
  117. new_btn.set_icon_widget(new_icon)
  118. toolbar.insert(new_btn, pos+1)
  119. new_btn.set_label("Stream %s" % name)
  120. new_btn.connect('toggled', self.streamblank_button_toggled)
  121. new_btn.set_name(name)
  122. def blink_streamblank_button(self):
  123. self.blink_btn_state = not self.blink_btn_state
  124. if self.blink_btn:
  125. self.blink_btn.get_icon_widget().override_background_color(
  126. Gtk.StateType.NORMAL,
  127. Gdk.RGBA(1.0, 0.0, 0.0, 1.0 if self.blink_btn_state else 0.0))
  128. return True
  129. def streamblank_button_toggled(self, btn):
  130. btn.get_icon_widget().override_background_color(
  131. Gtk.StateType.NORMAL,
  132. Gdk.RGBA(1.0, 0.0, 0.0, 0.0))
  133. if not btn.get_active():
  134. return
  135. if btn.get_name() != 'live':
  136. self.blink_btn = btn
  137. self.blink_btn_state = False
  138. else:
  139. self.blink_btn = None
  140. def show(self):
  141. self.log.info('Running Video-Playback Pipelines')
  142. self.video_main_player.run()
  143. for name, player in self.preview_players.items():
  144. player.run()
  145. self.log.info('Showing Main-Window')
  146. self.win.show_all()