~martijnbraam/pyatem

dba5191d6959bac972829975e06a3c089595461e — Martijn Braam 2 months ago 9f0119b
Implement AUX M/E
M gtk_switcher/atem.gresource.xml => gtk_switcher/atem.gresource.xml +1 -0
@@ 5,6 5,7 @@
    <file>ui/connection.glade</file>
    <file>ui/style.css</file>
    <file>ui/mixeffect.glade</file>
    <file>ui/mixeffect-aux.glade</file>
    <file>ui/upstream-keyer.glade</file>
    <file>ui/downstream-keyer.glade</file>
    <file>ui/preferences.glade</file>

M gtk_switcher/atemwindow.py => gtk_switcher/atemwindow.py +1 -1
@@ 219,7 219,7 @@ class AtemWindow(SwitcherPage, MediaPage, AudioPage, CameraPage, MidiControl):
        self.connection.die()
        self.connection.join(timeout=1)

        self.connection = AtemConnection(self.on_change, self.on_disconnect)
        self.connection = AtemConnection(self.on_change, self.on_disconnect, self.on_transfer_progress, self.on_download_done)
        self.connection.daemon = True
        self.connection.ip = self.settings.get_string('switcher-ip')
        self.connection.start()

A gtk_switcher/mixeffect_aux.py => gtk_switcher/mixeffect_aux.py +77 -0
@@ 0,0 1,77 @@
import gi

gi.require_version('Gtk', '3.0')

from gi.repository import Gtk, GObject


@Gtk.Template(resource_path='/nl/brixit/switcher/ui/mixeffect-aux.glade')
class AuxMixEffectBlock(Gtk.Grid):
    __gtype_name__ = 'AuxMixEffectBlock'

    dsk_box = Gtk.Template.Child()

    aux_name = Gtk.Template.Child()
    bus = Gtk.Template.Child()
    focus_dummy = Gtk.Template.Child()

    def __init__(self, index, name):
        super(Gtk.Grid, self).__init__()
        self.init_template()
        self.index = index
        self.aux_name.set_label(name)

    def set_class(self, widget, classname, state):
        if state:
            widget.get_style_context().add_class(classname)
        else:
            widget.get_style_context().remove_class(classname)

    def set_inputs(self, buttons):
        # Clear the existing buttons
        for child in self.bus:
            child.destroy()

        for top, row in enumerate(buttons):
            for left, button in enumerate(row):
                if button is None:
                    spacer = Gtk.Box()
                    spacer.set_size_request(4, 4)
                    spacer.source_index = -1
                    pspacer = Gtk.Box()
                    pspacer.set_size_request(4, 4)
                    pspacer.source_index = -1

                    self.bus.attach(spacer, left, top, 1, 1)
                    continue
                active = button.short_name != ""

                label = Gtk.Label(label=button.short_name)

                btn = Gtk.Button()
                btn.add(label)
                btn.source_index = button.index
                btn.set_sensitive(active)
                btn.set_size_request(48, 48)
                btn.get_style_context().add_class('bmdbtn')
                btn.connect('clicked', self.do_program_input_change)
                self.bus.attach(btn, left, top, 1, 1)

        self.bus.show_all()

    def source_change(self, source):
        for btn in self.bus:
            if btn.source_index == source:
                btn.get_style_context().add_class('program')
            else:
                btn.get_style_context().remove_class('program')

    @GObject.Signal(name="source-changed", flags=GObject.SignalFlags.RUN_LAST, return_type=bool,
                    arg_types=(int, int),
                    accumulator=GObject.signal_accumulator_true_handled)
    def source_changed(self, *args):
        pass

    def do_program_input_change(self, widget):
        self.focus_dummy.grab_focus()
        self.emit("source-changed", self.index, widget.source_index)

M gtk_switcher/switcher.py => gtk_switcher/switcher.py +73 -1
@@ 1,7 1,8 @@
from gtk_switcher.layout import LayoutView
from pyatem.command import CutCommand, AutoCommand, FadeToBlackCommand, TransitionSettingsCommand, WipeSettingsCommand, \
    TransitionPositionCommand, TransitionPreviewCommand, ColorGeneratorCommand, MixSettingsCommand, DipSettingsCommand, \
    DveSettingsCommand, AudioMasterPropertiesCommand, FairlightMasterPropertiesCommand, DkeyRateCommand, DkeyAutoCommand, DkeyTieCommand, \
    DveSettingsCommand, AudioMasterPropertiesCommand, FairlightMasterPropertiesCommand, DkeyRateCommand, \
    DkeyAutoCommand, DkeyTieCommand, \
    DkeyOnairCommand, ProgramInputCommand, PreviewInputCommand, KeyOnAirCommand, KeyFillCommand, \
    FadeToBlackConfigCommand, RecorderStatusCommand, AuxSourceCommand
from pyatem.field import TransitionSettingsField, InputPropertiesField


@@ 713,6 714,12 @@ class SwitcherPage:
        self.aux[source.index].set_active_id(str(source.source))
        self.aux[source.index].ignore_change = False

        for me in self.me:
            if not hasattr(me, 'category'):
                continue
            if me.index == source.index:
                me.source_change(source.source)

    def on_input_layout_change(self, changed_input):
        inputs = self.connection.mixer.mixerstate['input-properties']
        external = []


@@ 762,6 769,11 @@ class SwitcherPage:
                    self.aux[aux_id].add_attribute(renderer, "text", 1)
                    self.grid_aux.attach(self.aux[aux_id], 1, aux_id, 1, 1)

                    aux_me = Gtk.CheckButton()
                    aux_me.index = i.index
                    aux_me.connect('toggled', self.on_aux_me_enable_toggled)
                    self.grid_aux.attach(aux_me, 2, aux_id, 1, 1)

                    aux_label = Gtk.Label(label=i.name)
                    aux_label.get_style_context().add_class('dim-label')
                    self.grid_aux.attach(aux_label, 0, aux_id, 1, 1)


@@ 786,3 798,63 @@ class SwitcherPage:
        self.model_changing = False
        for i in self.has_models:
            i.model_changing = False

    def on_aux_me_enable_toggled(self, widget):
        from gtk_switcher.mixeffect_aux import AuxMixEffectBlock
        if widget.get_active():
            inputs = self.connection.mixer.mixerstate['input-properties']
            auxsrcs = self.connection.mixer.mixerstate['aux-output-source']
            auxsrc = auxsrcs[widget.index - 8001]
            external = []
            output = []
            passthrough = []
            special = []
            black = []
            bars = []
            for i in inputs.values():
                if i.available_aux:
                    if i.port_type == InputPropertiesField.PORT_EXTERNAL:
                        external.append(i)
                    elif i.port_type == InputPropertiesField.PORT_ME_OUTPUT:
                        output.append(i)
                    elif i.port_type == InputPropertiesField.PORT_PASSTHROUGH:
                        passthrough.append(i)
                    elif i.port_type == InputPropertiesField.PORT_BLACK:
                        black.append(None)
                        black.append(i)
                    elif i.port_type == InputPropertiesField.PORT_BARS:
                        bars.append(None)
                        bars.append(i)
                    else:
                        special.append(i)

            row1_ext = external
            row2_ext = [None] * len(external)
            if len(external) > 6:
                num = len(external) // 2
                row1_ext = external[0:num]
                row2_ext = external[num:] + [None] * ((2 * num) - len(external))

                row1 = row1_ext + black + [None] + output + passthrough
                row2 = row2_ext + bars + [None] + special
            else:
                row1 = row1_ext + [None] + passthrough + black + bars + [None] + output + special
                row2 = row2_ext

            name = inputs[widget.index].name
            aux_me = AuxMixEffectBlock(widget.index, name)
            aux_me.set_inputs([row1, row2])
            aux_me.source_change(auxsrc.source)
            aux_me.connect('source-changed', self.on_aux_me_source_changed)
            aux_me.index = widget.index - 8001
            aux_me.category = 'aux'
            self.apply_css(aux_me, self.provider)
            self.me.append(aux_me)
            self.main_blocks.add(aux_me)
        else:
            # Remove the UI for this M/E
            pass

    def on_aux_me_source_changed(self, widget, aux, source):
        cmd = AuxSourceCommand(aux, source=source)
        self.connection.mixer.send_commands([cmd])