aboutsummaryrefslogtreecommitdiff
path: root/voctogui/lib/ui.py
blob: 628b96cec61af3cb238f4d57955531d9e53409db (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. group_a = None
  70. group_b = None
  71. for idx, source in enumerate(sources):
  72. self.log.info('Initializing Video Preview %s', source)
  73. preview = self.get_check_widget('widget_preview', clone=True)
  74. video = self.find_widget_recursive(preview, 'video')
  75. video.set_size_request(width, height)
  76. box.pack_start(preview, fill=False, expand=False, padding=0)
  77. player = VideoDisplay(13000 + idx, video)
  78. self.find_widget_recursive(preview, 'label').set_label(source)
  79. btn_a = self.find_widget_recursive(preview, 'btn_a')
  80. btn_b = self.find_widget_recursive(preview, 'btn_b')
  81. btn_a.set_name("%c %u" % ('a', idx))
  82. btn_b.set_name("%c %u" % ('b', idx))
  83. if not group_a:
  84. group_a = btn_a
  85. else:
  86. btn_a.join_group(group_a)
  87. if not group_b:
  88. group_b = btn_b
  89. else:
  90. btn_b.join_group(group_b)
  91. btn_a.connect('toggled', self.preview_btn_toggled)
  92. btn_b.connect('toggled', self.preview_btn_toggled)
  93. key, mod = Gtk.accelerator_parse('%u' % (idx+1))
  94. btn_a.add_accelerator('activate', accelerators, key, mod, Gtk.AccelFlags.VISIBLE)
  95. key, mod = Gtk.accelerator_parse('<Ctrl>%u' % (idx+1))
  96. btn_b.add_accelerator('activate', accelerators, key, mod, Gtk.AccelFlags.VISIBLE)
  97. self.preview_players[source] = player
  98. self.previews[source] = preview
  99. def preview_btn_toggled(self, btn):
  100. if not btn.get_active():
  101. return
  102. self.log.info('preview_btn_toggled: %s', btn.get_name())
  103. def configure_audio_selector(self):
  104. self.log.info('Initializing Audio Selector')
  105. combo = self.find_widget_recursive(self.win, 'combo_audio')
  106. combo.set_sensitive(True)
  107. # FIXME access via combo_audio?
  108. liststore = self.get_check_widget('liststore_audio')
  109. liststore.clear()
  110. row = liststore.append()
  111. liststore.set(row, [0], ['foobar'])
  112. row = liststore.append('')
  113. liststore.set(row, [0], ['moofar'])
  114. combo.set_active_id('moofar')
  115. def configure_streamblank_selector(self):
  116. livebtn = self.get_check_widget('stream_live')
  117. blankbtn = self.get_check_widget('stream_blank')
  118. toolbar = blankbtn.get_parent()
  119. pos = toolbar.get_item_index(blankbtn)
  120. self.blink_btn = None
  121. self.blink_btn_state = False
  122. livebtn.connect('toggled', self.streamblank_button_toggled)
  123. livebtn.set_name('live')
  124. GLib.timeout_add_seconds(1, self.blink_streamblank_button)
  125. for idx, name in enumerate(['pause', 'nostream']):
  126. if idx == 0:
  127. new_btn = blankbtn
  128. else:
  129. new_icon = Gtk.Image.new_from_pixbuf(blankbtn.get_icon_widget().get_pixbuf())
  130. new_btn = Gtk.RadioToolButton(group=livebtn)
  131. new_btn.set_icon_widget(new_icon)
  132. toolbar.insert(new_btn, pos+1)
  133. new_btn.set_label("Stream %s" % name)
  134. new_btn.connect('toggled', self.streamblank_button_toggled)
  135. new_btn.set_name(name)
  136. def blink_streamblank_button(self):
  137. self.blink_btn_state = not self.blink_btn_state
  138. if self.blink_btn:
  139. self.blink_btn.get_icon_widget().override_background_color(
  140. Gtk.StateType.NORMAL,
  141. Gdk.RGBA(1.0, 0.0, 0.0, 1.0 if self.blink_btn_state else 0.0))
  142. return True
  143. def streamblank_button_toggled(self, btn):
  144. btn.get_icon_widget().override_background_color(
  145. Gtk.StateType.NORMAL,
  146. Gdk.RGBA(1.0, 0.0, 0.0, 0.0))
  147. if not btn.get_active():
  148. return
  149. if btn.get_name() != 'live':
  150. self.blink_btn = btn
  151. self.blink_btn_state = False
  152. else:
  153. self.blink_btn = None
  154. def show(self):
  155. self.log.info('Running Video-Playback Pipelines')
  156. self.video_main_player.run()
  157. for name, player in self.preview_players.items():
  158. player.run()
  159. self.log.info('Showing Main-Window')
  160. self.win.show_all()