Skip to content

Commit

Permalink
Merge pull request #320 from voc/preset_toolbar
Browse files Browse the repository at this point in the history
voctogui: add presets tab to gui
  • Loading branch information
Kunsi committed May 19, 2024
2 parents 8bd7d18 + 459a0c7 commit a9bc3d4
Show file tree
Hide file tree
Showing 9 changed files with 821 additions and 317 deletions.
23 changes: 23 additions & 0 deletions voctogui/lib/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,29 @@ def getWindowSize(self):
def getForceFullScreen(self):
return self.getboolean('mainwindow', 'forcefullscreen', fallback=False)

def getPresetComposites(self):
return self.getList('preset', 'composites', fallback=self.getToolbarComposites().get("buttons", ""))

def getPresetKeybindings(self):
return self.getList('preset', 'keybindings', fallback=[])

def getPresetSourcesComposites(self):
return self._filterPresetSources(self.getList('preset', 'sources_composites'))

def getPresetSourcesFullscreen(self):
return self._filterPresetSources(self.getList('preset', 'sources_fullscreen'))

def _filterPresetSources(self, sources):
toolbar_sources = self.getToolbarSourcesA().get("buttons", "").split(",")
if not sources:
return toolbar_sources
else:
return [
source
for source in sources
if source in toolbar_sources
]

def getShowCloseButton(self):
return self.getboolean('toolbar', 'close', fallback=True)

Expand Down
166 changes: 166 additions & 0 deletions voctogui/lib/presetcontroller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/env python3
import logging
import os
import time

import lib.connection as Connection
from gi.repository import GLib, Gtk
from lib.config import Config
from lib.toolbar.buttons import Buttons

from vocto.composite_commands import CompositeCommand


class PresetController(object):
def __init__(self, win, preview_controller, uibuilder):
self.log = logging.getLogger("PresetController")
self.box = uibuilder.find_widget_recursive(win, "preset_box")
self.toolbar = uibuilder.find_widget_recursive(win, "preset_toolbar")
self.preview_controller = preview_controller

keybindings = Config.getPresetKeybindings()
sources_composites = Config.getPresetSourcesComposites()
sources_fullscreen = Config.getPresetSourcesFullscreen()
composites = Config.getPresetComposites()
accelerators = Gtk.AccelGroup()

buttons = {}
self.button_to_composites = {}
self.current_state = None

self.log.debug(f"{keybindings=}")
self.log.debug(f"{sources_composites=}")
self.log.debug(f"{sources_fullscreen=}")
self.log.debug(f"{composites=}")

if (not sources_composites and not sources_fullscreen) or not composites:
self.box.hide()
self.box.set_no_show_all(True)
return

idx = 0
if "fs" in composites:
for sourceA in sources_fullscreen:
button_name = f"preset_fs_{sourceA}"
buttons[f"{button_name}.name"] = f"{sourceA}"
if 'slides' in sourceA:
buttons[f"{button_name}.icon"] = "slides.svg"
else:
buttons[f"{button_name}.icon"] = "speaker.svg"

try:
buttons[f"{button_name}.key"] = keybindings[idx]
idx += 1
except IndexError:
pass
for sourceB in sources_fullscreen:
if sourceA != sourceB:
self.button_to_composites[button_name] = CompositeCommand(
"fs", sourceA, sourceB
)
break
else:
self.button_to_composites[button_name] = CompositeCommand(
"fs", sourceA, None
)

if "lec" in composites:
for sourceA in sources_composites:
if sourceA not in Config.getLiveSources():
continue
for sourceB in sources_composites:
if sourceB not in Config.getLiveSources():
button_name = f"preset_lec_{sourceA}_{sourceB}"
buttons[f"{button_name}.name"] = (
f"{sourceA}\n{sourceB}"
)
buttons[f"{button_name}.icon"] = (
"side-by-side-preview.svg"
)

try:
buttons[f"{button_name}.key"] = keybindings[idx]
idx += 1
except IndexError:
pass
self.button_to_composites[button_name] = CompositeCommand(
"lec", sourceA, sourceB
)

if "sbs" in composites:
for sourceA in sources_composites:
if sourceA not in Config.getLiveSources():
continue
for sourceB in sources_composites:
if sourceB not in Config.getLiveSources():
button_name = f"preset_sbs_{sourceA}_{sourceB}"
buttons[f"{button_name}.name"] = (
f"{sourceA}\n{sourceB}"
)
buttons[f"{button_name}.icon"] = (
"side-by-side.svg"
)
try:
buttons[f"{button_name}.key"] = keybindings[idx]
idx += 1
except IndexError:
pass
self.button_to_composites[button_name] = CompositeCommand(
"sbs", sourceA, sourceB
)

self.log.debug(f"{buttons=}")
self.buttons = Buttons(buttons)
self.buttons.create(self.toolbar, accelerators, self.on_btn_toggled)

Connection.on("best", self.on_best)
Connection.on("composite", self.on_composite)

def on_btn_toggled(self, btn):
self.log.debug(f">on_btn_toggle {btn=}")
if btn.get_active():
id = btn.get_name()
self.log.info(f"Preset Button {id} was pressed")
if id not in self.button_to_composites:
self.log.error(f"Button {id} not found in composites!")
return
self.log.debug(f"{self.button_to_composites[id]=}")
self.log.info(f"Selecting {self.button_to_composites[id]} for next scene")
self.preview_controller.set_command(self.button_to_composites[id])
self.log.debug(f"<on_btn_toggle {btn=}")

def on_best(self, best, targetA, targetB):
self.log.debug(f">on_best {best=} {targetA=} {targetB=} {self.current_state=}")
c = self.preview_controller.command()
for name, composite in self.button_to_composites.items():
self.buttons[name]["button"].set_active(c == composite)
self.log.debug(f"<on_best {best=} {targetA=} {targetB=} {self.current_state=}")
self.update_glow()

def on_composite(self, command):
self.log.debug(f">on_composite {command=} {self.current_state=}")
cmd = CompositeCommand.from_str(command)
for name, composite in self.button_to_composites.items():
if (
composite.A == cmd.A
and (
cmd.composite == 'fs'
or (
composite.composite == cmd.composite
and composite.B == cmd.B
)
)
):
self.current_state = name
break
else:
self.current_state = None
self.log.debug(f"<on_composite {command=} {self.current_state=}")
self.update_glow()

def update_glow(self):
for id, item in self.buttons.items():
if id == self.current_state:
item["button"].get_style_context().add_class("glow")
else:
item["button"].get_style_context().remove_class("glow")
7 changes: 5 additions & 2 deletions voctogui/lib/toolbar/mix.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ def __init__(self, win, uibuilder, preview_controller, overlay_controller):

self.mix = Buttons(Config.getToolbarMix())

self.toolbar = uibuilder.find_widget_recursive(win, 'toolbar_mix')
self.toolbar_composites = uibuilder.find_widget_recursive(win, 'toolbar_mix')
self.toolbar_presets = uibuilder.find_widget_recursive(win, 'toolbar_mix1')

self.mix.create(self.toolbar, accelerators,
self.mix.create(self.toolbar_composites, accelerators,
self.on_btn_clicked, radio=False)
self.mix.create(self.toolbar_presets, accelerators,
self.on_btn_clicked, radio=False)
Connection.on('best', self.on_best)

Expand Down
6 changes: 6 additions & 0 deletions voctogui/lib/toolbar/widgets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
from gi.repository import Gtk
import sys
import os

def _decode(text, multiline=True):
''' decode multiline text '''
Expand Down Expand Up @@ -34,6 +35,7 @@ class Widgets(dict):
def __init__(self, cfg_items, listname="widgets"):
# read all config items with their attributes
self.ids = []
self.iconpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../ui/')
if cfg_items:
filter = cfg_items[listname].split(
',') if listname in cfg_items else None
Expand Down Expand Up @@ -98,4 +100,8 @@ def add(self, widget, id, accelerators=None, callback=None, signal='clicked', cs
if 'expand' in attr:
widget.set_expand(True)

if 'icon' in attr:
img = Gtk.Image.new_from_file(os.path.join(self.iconpath, attr['icon']))
widget.set_icon_widget(img)

widget.set_can_focus(False)
7 changes: 7 additions & 0 deletions voctogui/lib/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from lib.videopreviews import VideoPreviewsController
from lib.queues import QueuesWindowController
from lib.ports import PortsWindowController
from lib.presetcontroller import PresetController

from lib.toolbar.mix import MixToolbarController
from lib.toolbar.preview import PreviewToolbarController
Expand Down Expand Up @@ -98,6 +99,12 @@ def setup(self):
uibuilder=self
)

self.preset_controller = PresetController(
win=self.win,
preview_controller=self.preview_toolbar_controller,
uibuilder=self,
)

self.overlay_toolbar_controller = OverlayToolbarController(
win=self.win,
uibuilder=self
Expand Down
44 changes: 44 additions & 0 deletions voctogui/ui/cut.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions voctogui/ui/retake.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions voctogui/ui/transition.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit a9bc3d4

Please sign in to comment.