def testDisplayInputSentToAll(self): og = OutputsGrid() og.updateOutputMappings({'Main': {0: 1}}) self.assertEqual("Camera 1", self.findButton(og, "Monitor 1").inputDisplay.text()) self.assertEqual("Camera 1", self.findButton(og, "Font").inputDisplay.text()) self.assertEqual("Camera 1", self.findButton(og, "Church").inputDisplay.text()) self.assertEqual("Camera 1", self.findButton(og, "Welcome").inputDisplay.text()) self.assertEqual("Camera 1", self.findButton(og, "Gallery").inputDisplay.text()) self.assertEqual("Camera 1", self.findButton(og, "Stage").inputDisplay.text()) self.assertEqual("Camera 1", self.findButton(og, "Record").inputDisplay.text())
def testDisplayInputNames(self): og = OutputsGrid() self.assertEqual("-", self.findButton(og, "Monitor 1").inputDisplay.text()) og.updateOutputMappings({'Main': {2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 0}}) self.assertEqual("Camera 1", self.findButton(og, "Monitor 1").inputDisplay.text()) self.assertEqual("Camera 2", self.findButton(og, "Font").inputDisplay.text()) self.assertEqual("Camera 3", self.findButton(og, "Church").inputDisplay.text()) self.assertEqual("DVD", self.findButton(og, "Welcome").inputDisplay.text()) self.assertEqual("Extras", self.findButton(og, "Gallery").inputDisplay.text()) self.assertEqual("Visuals PC", self.findButton(og, "Stage").inputDisplay.text()) self.assertEqual("Blank", self.findButton(og, "Record").inputDisplay.text())
def testDisplayInputSentToPCMix(self): og = OutputsGrid() og.updateOutputMappings({'Preview': {2: 4}}) self.assertEqual("DVD", self.findButton(og, "PC Mix").inputDisplay.text()) # And test that changing the preview side of the switcher doesn't update the PC Mix button! og.updateOutputMappings({'Preview': {1: 2}}) self.assertEqual("DVD", self.findButton(og, "PC Mix").inputDisplay.text()) # Buggy wiring means 6 is actually 5 og.updateOutputMappings({'Preview': {2: 6}}) self.assertEqual("Extras", self.findButton(og, "PC Mix").inputDisplay.text())
def testSendSignals(self): ss = MagicMock() ss.outputs = { 0: Output("Aux 1", VideoSource.AUX_1), 1: Output("Aux 2", VideoSource.AUX_2), } og = OutputsGrid(ss) handler = MagicMock() og.selected.connect(handler) btn = self.findButton(og, "Aux 1") self.assertTrue(btn is not None) btn.click() handler.assert_called_once_with(0) handler.reset_mock() btn = self.findButton(og, "Aux 2") self.assertTrue(btn is not None) btn.click() handler.assert_called_once_with(1) takeHandler = MagicMock() og.take.connect(takeHandler) cutHandler = MagicMock() og.cut.connect(cutHandler) btn = self.findButton(og, "Cut") self.assertTrue(btn is not None) btn.click() cutHandler.assert_called_once_with() btn = self.findButton(og, "Fade") self.assertTrue(btn is not None) btn.click() takeHandler.assert_called_once_with() allHandler = MagicMock() og.all.connect(allHandler) btn = self.findButton(og, "All") self.assertTrue(btn is not None) btn.click() takeHandler.assert_called_once_with() mainToAllHandler = MagicMock() og.mainToAll.connect(mainToAllHandler) btn = self.findButton(og, "Mix to all") self.assertTrue(btn is not None) btn.click() mainToAllHandler.assert_called_once_with()
def setupUi(self): gridlayout = QGridLayout() self.setLayout(gridlayout) ''' Buttons added to inputs should have a numeric ID set equal to their input number on the Aldates main switcher. ''' self.inputs = QButtonGroup() inputsGrid = QHBoxLayout() self.btnCamera1 = CameraSelectionButton(1) self.btnCamera1.setText("Camera 1") self.btnCamera1.setInput(VisualsSystem.camera1) inputsGrid.addWidget(self.btnCamera1) self.inputs.addButton(self.btnCamera1, 1) self.btnCamera1.setIcon(QIcon(":icons/camera-video")) self.btnCamera2 = CameraSelectionButton(2) self.btnCamera2.setText("Camera 2") self.btnCamera2.setInput(VisualsSystem.camera2) inputsGrid.addWidget(self.btnCamera2) self.inputs.addButton(self.btnCamera2, 2) self.btnCamera2.setIcon(QIcon(":icons/camera-video")) self.btnCamera3 = CameraSelectionButton(3) self.btnCamera3.setText("Camera 3") self.btnCamera3.setInput(VisualsSystem.camera3) inputsGrid.addWidget(self.btnCamera3) self.inputs.addButton(self.btnCamera3, 3) self.btnCamera3.setIcon(QIcon(":icons/camera-video")) self.btnDVD = InputButton() self.btnDVD.setText("DVD") self.btnDVD.setInput(VisualsSystem.dvd) inputsGrid.addWidget(self.btnDVD) self.inputs.addButton(self.btnDVD, 4) self.btnDVD.setIcon(QIcon(":icons/media-optical")) self.btnExtras = InputButton() self.btnExtras.setText("Extras") inputsGrid.addWidget(self.btnExtras) self.btnExtras.setIcon(QIcon(":icons/video-display")) self.inputs.addButton(self.btnExtras, 5) self.btnVisualsPC = InputButton() self.btnVisualsPC.setText("Visuals PC") self.btnVisualsPC.setInput(VisualsSystem.visualsPC) inputsGrid.addWidget(self.btnVisualsPC) self.inputs.addButton(self.btnVisualsPC, 6) self.btnVisualsPC.setIcon(QIcon(":icons/computer")) self.btnBlank = InputButton() self.btnBlank.setText("Blank") self.btnBlank.setInput(VisualsSystem.blank) inputsGrid.addWidget(self.btnBlank) self.inputs.addButton(self.btnBlank, 0) gridlayout.addLayout(inputsGrid, 0, 0, 1, 7) self.extrasSwitcher = ExtrasSwitcher(self.controller) self.extrasSwitcher.inputSelected.connect(self.handleExtrasSelect) self.btnExtras.setInput(ProxyInput(self.extrasSwitcher)) self.blank = QWidget(self) gridlayout.addWidget(self.blank, 1, 0, 1, 5) self.outputsGrid = OutputsGrid() gridlayout.addWidget(self.outputsGrid, 1, 5, 1, 2) gridlayout.setRowStretch(0, 1) gridlayout.setRowStretch(1, 5) QMetaObject.connectSlotsByName(self) self.setInputClickHandlers() self.setOutputClickHandlers(self.outputsGrid) self.configureInnerControlPanels() self.gridlayout = gridlayout
class VideoSwitcher(QWidget): def __init__(self, controller, mainWindow): super(VideoSwitcher, self).__init__() self.controller = controller self.mainWindow = mainWindow self.setupUi() def setupUi(self): gridlayout = QGridLayout() self.setLayout(gridlayout) ''' Buttons added to inputs should have a numeric ID set equal to their input number on the Aldates main switcher. ''' self.inputs = QButtonGroup() inputsGrid = QHBoxLayout() self.btnCamera1 = CameraSelectionButton(1) self.btnCamera1.setText("Camera 1") self.btnCamera1.setInput(VisualsSystem.camera1) inputsGrid.addWidget(self.btnCamera1) self.inputs.addButton(self.btnCamera1, 1) self.btnCamera1.setIcon(QIcon(":icons/camera-video")) self.btnCamera2 = CameraSelectionButton(2) self.btnCamera2.setText("Camera 2") self.btnCamera2.setInput(VisualsSystem.camera2) inputsGrid.addWidget(self.btnCamera2) self.inputs.addButton(self.btnCamera2, 2) self.btnCamera2.setIcon(QIcon(":icons/camera-video")) self.btnCamera3 = CameraSelectionButton(3) self.btnCamera3.setText("Camera 3") self.btnCamera3.setInput(VisualsSystem.camera3) inputsGrid.addWidget(self.btnCamera3) self.inputs.addButton(self.btnCamera3, 3) self.btnCamera3.setIcon(QIcon(":icons/camera-video")) self.btnDVD = InputButton() self.btnDVD.setText("DVD") self.btnDVD.setInput(VisualsSystem.dvd) inputsGrid.addWidget(self.btnDVD) self.inputs.addButton(self.btnDVD, 4) self.btnDVD.setIcon(QIcon(":icons/media-optical")) self.btnExtras = InputButton() self.btnExtras.setText("Extras") inputsGrid.addWidget(self.btnExtras) self.btnExtras.setIcon(QIcon(":icons/video-display")) self.inputs.addButton(self.btnExtras, 5) self.btnVisualsPC = InputButton() self.btnVisualsPC.setText("Visuals PC") self.btnVisualsPC.setInput(VisualsSystem.visualsPC) inputsGrid.addWidget(self.btnVisualsPC) self.inputs.addButton(self.btnVisualsPC, 6) self.btnVisualsPC.setIcon(QIcon(":icons/computer")) self.btnBlank = InputButton() self.btnBlank.setText("Blank") self.btnBlank.setInput(VisualsSystem.blank) inputsGrid.addWidget(self.btnBlank) self.inputs.addButton(self.btnBlank, 0) gridlayout.addLayout(inputsGrid, 0, 0, 1, 7) self.extrasSwitcher = ExtrasSwitcher(self.controller) self.extrasSwitcher.inputSelected.connect(self.handleExtrasSelect) self.btnExtras.setInput(ProxyInput(self.extrasSwitcher)) self.blank = QWidget(self) gridlayout.addWidget(self.blank, 1, 0, 1, 5) self.outputsGrid = OutputsGrid() gridlayout.addWidget(self.outputsGrid, 1, 5, 1, 2) gridlayout.setRowStretch(0, 1) gridlayout.setRowStretch(1, 5) QMetaObject.connectSlotsByName(self) self.setInputClickHandlers() self.setOutputClickHandlers(self.outputsGrid) self.configureInnerControlPanels() self.gridlayout = gridlayout def configureInnerControlPanels(self): self.panels = [ QWidget(), # Blank CameraControl(self.controller["Camera 1"]) if self.controller.hasDevice("Camera 1") else QLabel(StringConstants.noDevice), CameraControl(self.controller["Camera 2"]) if self.controller.hasDevice("Camera 2") else QLabel(StringConstants.noDevice), CameraControl(self.controller["Camera 3"]) if self.controller.hasDevice("Camera 3") else QLabel(StringConstants.noDevice), QLabel(StringConstants.noDevice), # DVD - no controls self.extrasSwitcher if self.controller.hasDevice("Extras") else QLabel(StringConstants.noDevice), # Extras EclipseControls(self.controller["Main Scan Converter"]) if self.controller.hasDevice("Main Scan Converter") else QLabel(StringConstants.noDevice), # Visuals PC ] self.advPanels = [ None, AdvancedCameraControl("Camera 1", self.controller["Camera 1"], self.mainWindow) if self.controller.hasDevice("Camera 1") else None, AdvancedCameraControl("Camera 2", self.controller["Camera 2"], self.mainWindow) if self.controller.hasDevice("Camera 1") else None, AdvancedCameraControl("Camera 3", self.controller["Camera 3"], self.mainWindow) if self.controller.hasDevice("Camera 1") else None, None, None, None ] def setInputClickHandlers(self): for btn in self.inputs.buttons(): btn.clicked.connect(self.handleInputSelect) btn.longpress.connect(self.showAdvPanel) def setOutputClickHandlers(self, outputsGrid): outputsGrid.connectMainOutputs(self.handleOutputSelect) ''' btnPCMix is a special case since that's on a different switcher ''' outputsGrid.connectPreviewOutputs(self.handlePCMixSelect) def keyPressEvent(self, e): if e.key() == Qt.Key_0: self.btnBlank.click() elif e.key() == Qt.Key_1: self.btnCamera1.click() elif e.key() == Qt.Key_2: self.btnCamera2.click() elif e.key() == Qt.Key_3: self.btnCamera3.click() elif e.key() == Qt.Key_4: self.btnDVD.click() elif e.key() == Qt.Key_5: self.btnExtras.click() elif e.key() == Qt.Key_6: self.btnVisualsPC.click() elif e.key() == Qt.Key_Space: self.outputsGrid.btnAll.click() else: self.panels[self.inputs.checkedId()].keyPressEvent(e) def keyReleaseEvent(self, e): self.panels[self.inputs.checkedId()].keyReleaseEvent(e) def handleInputSelect(self): inputID = self.inputs.checkedId() logging.debug("Input selected: " + str(inputID)) if inputID >= 0: myInput = self.inputs.checkedButton().input if myInput: myInput.preview(self.controller) self.gridlayout.removeWidget(self.gridlayout.itemAtPosition(1, 0).widget()) for p in self.panels: p.hide() chosenPanel = self.panels[inputID] self.gridlayout.addWidget(chosenPanel, 1, 0, 1, 5) chosenPanel.show() # Prevent certain options from being selectable if inputID == 6 or inputID == 0: self.outputsGrid.setEnabled(True) self.outputsGrid.btnPCMix.setEnabled(False) elif inputID == 5 and self.extrasSwitcher.currentInput() is None: self.outputsGrid.setEnabled(False) self.outputsGrid.btnPCMix.setEnabled(True) else: self.outputsGrid.setEnabled(True) self.outputsGrid.btnPCMix.setEnabled(True) def handleOutputSelect(self): outputChannel = self.sender().ID inputID = self.inputs.checkedId() checkedExtrasButton = self.extrasSwitcher.inputs.checkedButton() inputChannel = checkedExtrasButton.input if (inputID == 5 and checkedExtrasButton) else self.inputs.checkedButton().input if inputChannel: inputChannel.toMain(self.controller, outputChannel) def handlePCMixSelect(self): inputID = self.inputs.checkedId() checkedExtrasButton = self.extrasSwitcher.inputs.checkedButton() inputChannel = checkedExtrasButton.input if (inputID == 5 and checkedExtrasButton) else self.inputs.checkedButton().input if inputChannel: inputChannel.toPCMix(self.controller) @Slot(VisualsSystem.Input) def handleExtrasSelect(self, extrasInput): if extrasInput is not None: self.btnExtras.setText(extrasInput.name) self.outputsGrid.inputNames[5] = extrasInput.name self.outputsGrid.setEnabled(True) else: # Not sure under what circumstances, if any, this will arise self.btnExtras.setText("Extras") self.outputsGrid.inputNames[5] = "Extras" self.outputsGrid.setEnabled(False) def showAdvPanel(self): sender = self.sender() inputID = self.sender().ID if hasattr(sender, "ID") else None if inputID is not None and self.advPanels[inputID] is not None: self.mainWindow.showScreen(self.advPanels[inputID]) def updateOutputMappings(self, mapping): print mapping self.outputsGrid.updateOutputMappings(mapping)
def setupUi(self): layout = QGridLayout() inputs_grid = QHBoxLayout() self.inputs = QButtonGroup() def ifDevice(deviceID, func): if self.controller.hasDevice(deviceID): return func() return (None, None, None, None) def setCamera(cam, cc): if self.joystickAdapter: self.joystickAdapter.set_camera(cam) self.joystickAdapter.set_on_move(cc.deselectPreset) def makeCamera(videoSource, cameraID): cam = self.controller[cameraID] cc = CameraControl(cam) return ( videoSource, cc, AdvancedCameraControl(cameraID, cam, self.mainWindow), lambda: setCamera(cam, cc) ) def deselectCamera(): if self.joystickAdapter: self.joystickAdapter.set_camera(None) self.joystickAdapter.set_on_move(None) self.input_buttons_config = [ ifDevice("Camera 1", lambda: makeCamera(VideoSource.INPUT_1, "Camera 1")), ifDevice("Camera 2", lambda: makeCamera(VideoSource.INPUT_2, "Camera 2")), ifDevice("Camera 3", lambda: makeCamera(VideoSource.INPUT_3, "Camera 3")), (VideoSource.INPUT_4, QLabel(StringConstants.noDevice), None, deselectCamera), (VideoSource.INPUT_5, OverlayControl(self.switcherState.dsks[0], self.atem), None, deselectCamera), (VideoSource.INPUT_6, QLabel(StringConstants.noDevice), None, deselectCamera) ] for source, panel, adv_panel, on_select_func in self.input_buttons_config: if source: btn = InputButton(self.switcherState.inputs[source]) btn.setProperty("panel", panel) btn.setProperty("adv_panel", adv_panel) btn.clicked.connect(self.preview) btn.clicked.connect(self.displayPanel) if on_select_func: btn.clicked.connect(on_select_func) btn.longpress.connect(self.displayAdvPanel) self.inputs.addButton(btn) inputs_grid.addWidget(btn) self.extrasBtn = InputButton(None) self.inputs.addButton(self.extrasBtn) self.extrasBtn.clicked.connect(self.preview) self.extrasBtn.clicked.connect(self.displayPanel) self.extrasBtn.clicked.connect(deselectCamera) # An empty menu means the button will be given a "down arrow" icon # without actually showing a menu when pressed. self.extrasBtn.setMenu(QMenu()) self.allInputs = AllInputsPanel(self.switcherState) self.extrasBtn.setProperty("panel", self.allInputs) self.allInputs.inputSelected.connect(self.setExtraInput) inputs_grid.addWidget(self.extrasBtn) self.blackBtn = FlashingInputButton(self.switcherState.inputs[VideoSource.BLACK]) inputs_grid.addWidget(self.blackBtn) self.inputs.addButton(self.blackBtn) self.blackBtn.clicked.connect(self.preview) self.blackBtn.clicked.connect(self.displayPanel) self.blackBtn.clicked.connect(deselectCamera) self.ftb = FadeToBlackControl(self.switcherState.ftb, self.atem) self.blackBtn.setProperty("panel", self.ftb) self.blackBtn.flashing = self.switcherState.ftb.active self.switcherState.ftb.activeChanged.connect(self.blackBtn.setFlashing) layout.addLayout(inputs_grid, 0, 0, 1, 7) self.og = OutputsGrid(self.switcherState) self.og.take.connect(self.take) self.og.cut.connect(self.cut) self.og.selected.connect(self.sendToAux) self.og.mainToAll.connect(self.sendMainToAllAuxes) self.og.all.connect(self.sendToAll) self.og.sendMain.connect(self.sendMainToAux) self.og.setAuxesEnabled(False) # since we start off without an input selected layout.addWidget(self.og, 1, 5, 1, 2) self.blankWidget = QWidget() layout.addWidget(self.blankWidget, 1, 0, 1, 5) layout.setRowStretch(0, 1) layout.setRowStretch(1, 5) self.setLayout(layout)
class VideoSwitcher(QWidget): def __init__(self, controller, mainWindow, switcherState, joystickAdapter=None): super(VideoSwitcher, self).__init__() self.mainWindow = mainWindow self.atem = controller['ATEM'] self.controller = controller self.switcherState = switcherState self.joystickAdapter = joystickAdapter self.setupUi() def setupUi(self): layout = QGridLayout() inputs_grid = QHBoxLayout() self.inputs = QButtonGroup() def ifDevice(deviceID, func): if self.controller.hasDevice(deviceID): return func() return (None, None, None, None) def setCamera(cam, cc): if self.joystickAdapter: self.joystickAdapter.set_camera(cam) self.joystickAdapter.set_on_move(cc.deselectPreset) def makeCamera(videoSource, cameraID): cam = self.controller[cameraID] cc = CameraControl(cam) return ( videoSource, cc, AdvancedCameraControl(cameraID, cam, self.mainWindow), lambda: setCamera(cam, cc) ) def deselectCamera(): if self.joystickAdapter: self.joystickAdapter.set_camera(None) self.joystickAdapter.set_on_move(None) self.input_buttons_config = [ ifDevice("Camera 1", lambda: makeCamera(VideoSource.INPUT_1, "Camera 1")), ifDevice("Camera 2", lambda: makeCamera(VideoSource.INPUT_2, "Camera 2")), ifDevice("Camera 3", lambda: makeCamera(VideoSource.INPUT_3, "Camera 3")), (VideoSource.INPUT_4, QLabel(StringConstants.noDevice), None, deselectCamera), (VideoSource.INPUT_5, OverlayControl(self.switcherState.dsks[0], self.atem), None, deselectCamera), (VideoSource.INPUT_6, QLabel(StringConstants.noDevice), None, deselectCamera) ] for source, panel, adv_panel, on_select_func in self.input_buttons_config: if source: btn = InputButton(self.switcherState.inputs[source]) btn.setProperty("panel", panel) btn.setProperty("adv_panel", adv_panel) btn.clicked.connect(self.preview) btn.clicked.connect(self.displayPanel) if on_select_func: btn.clicked.connect(on_select_func) btn.longpress.connect(self.displayAdvPanel) self.inputs.addButton(btn) inputs_grid.addWidget(btn) self.extrasBtn = InputButton(None) self.inputs.addButton(self.extrasBtn) self.extrasBtn.clicked.connect(self.preview) self.extrasBtn.clicked.connect(self.displayPanel) self.extrasBtn.clicked.connect(deselectCamera) # An empty menu means the button will be given a "down arrow" icon # without actually showing a menu when pressed. self.extrasBtn.setMenu(QMenu()) self.allInputs = AllInputsPanel(self.switcherState) self.extrasBtn.setProperty("panel", self.allInputs) self.allInputs.inputSelected.connect(self.setExtraInput) inputs_grid.addWidget(self.extrasBtn) self.blackBtn = FlashingInputButton(self.switcherState.inputs[VideoSource.BLACK]) inputs_grid.addWidget(self.blackBtn) self.inputs.addButton(self.blackBtn) self.blackBtn.clicked.connect(self.preview) self.blackBtn.clicked.connect(self.displayPanel) self.blackBtn.clicked.connect(deselectCamera) self.ftb = FadeToBlackControl(self.switcherState.ftb, self.atem) self.blackBtn.setProperty("panel", self.ftb) self.blackBtn.flashing = self.switcherState.ftb.active self.switcherState.ftb.activeChanged.connect(self.blackBtn.setFlashing) layout.addLayout(inputs_grid, 0, 0, 1, 7) self.og = OutputsGrid(self.switcherState) self.og.take.connect(self.take) self.og.cut.connect(self.cut) self.og.selected.connect(self.sendToAux) self.og.mainToAll.connect(self.sendMainToAllAuxes) self.og.all.connect(self.sendToAll) self.og.sendMain.connect(self.sendMainToAux) self.og.setAuxesEnabled(False) # since we start off without an input selected layout.addWidget(self.og, 1, 5, 1, 2) self.blankWidget = QWidget() layout.addWidget(self.blankWidget, 1, 0, 1, 5) layout.setRowStretch(0, 1) layout.setRowStretch(1, 5) self.setLayout(layout) def setExtraInput(self, inp): self.extrasBtn.setInput(inp) self.preview() @with_atem def preview(self): checkedButton = self.inputs.checkedButton() if checkedButton and checkedButton.input: self.og.setAuxesEnabled(True) if self.atem: self.atem.setPreview(checkedButton.input.source) else: self.og.setAuxesEnabled(False) @with_atem def cut(self): self.atem.performCut() @with_atem def take(self): self.atem.setNextTransition(TransitionStyle.MIX, bkgd=True, key1=False, key2=False, key3=False, key4=False) self.atem.performAutoTake() @with_atem def sendToAux(self, auxIndex): if self.inputs.checkedButton().input: self.atem.setAuxSource(auxIndex + 1, self.inputs.checkedButton().input.source) @with_atem def sendToAll(self): if self.inputs.checkedButton().input: self.atem.setProgram(self.inputs.checkedButton().input.source) for aux in self.switcherState.outputs.keys(): self.sendToAux(aux) @with_atem def sendMainToAux(self, auxIndex): self.atem.setAuxSource(auxIndex + 1, VideoSource.ME_1_PROGRAM) @with_atem def sendMainToAllAuxes(self): for aux in self.switcherState.outputs.keys(): self.atem.setAuxSource(aux + 1, VideoSource.ME_1_PROGRAM) def displayPanel(self): panel = self.inputs.checkedButton().property("panel") layout = self.layout() existing = layout.itemAtPosition(1, 0) if existing: widget = existing.widget() widget.hide() layout.removeWidget(widget) if panel: # display panel layout.addWidget(panel, 1, 0, 1, 5) panel.show() else: # hide panel layout.addWidget(self.blankWidget, 1, 0, 1, 5) self.blankWidget.show() def displayAdvPanel(self): panel = self.sender().property("adv_panel") if panel: self.mainWindow.showScreen(panel)