def setUp(self): GuiTest.setUp(self) self.mockController = MockController() self.main = Device("Main") self.mockController.addDevice(self.main) self.main.sendInputToOutput = MagicMock(return_value=1) self.preview = Device("Preview") self.mockController.addDevice(self.preview) self.preview.sendInputToOutput = MagicMock(return_value=1) self.extras = Device("Extras") self.mockController.addDevice(self.extras) self.extras.sendInputToOutput = MagicMock(return_value=1) fakeMainWindow = object() self.vs = VideoSwitcher(self.mockController, fakeMainWindow)
def makeVS(self): return VideoSwitcher(self.mockController, self.mainWindow, self.switcherState)
class TestVideoSwitcher(GuiTest): def setUp(self): GuiTest.setUp(self) self.mockController = MockController() self.main = Device("Main") self.mockController.addDevice(self.main) self.main.sendInputToOutput = MagicMock(return_value=1) self.preview = Device("Preview") self.mockController.addDevice(self.preview) self.preview.sendInputToOutput = MagicMock(return_value=1) self.extras = Device("Extras") self.mockController.addDevice(self.extras) self.extras.sendInputToOutput = MagicMock(return_value=1) fakeMainWindow = object() self.vs = VideoSwitcher(self.mockController, fakeMainWindow) def testSendInputsToOutputs(self): outputsGrid = self.vs.findChild(OutputsGrid) self.assertTrue(outputsGrid is not None) self.vs.btnCamera1.click() self.assertPreviewCalledFor(1) # Camera 1 is previewed outputsGrid.btnChurch.click() self.main.sendInputToOutput.assert_called_with(1, 4) # Camera 1 sent to output 4 (church) self.vs.btnCamera3.click() self.assertPreviewCalledFor(3) # Camera 3 previewed outputsGrid.btnGallery.click() self.main.sendInputToOutput.assert_called_with(3, 6) # Camera 3 sent to output 6 (gallery) outputsGrid.btnPCMix.click() self.preview.sendInputToOutput.assert_called_with(3, 2) # Camera 3 sent to PC Mix self.vs.btnBlank.click() outputsGrid.btnAll.click() self.main.sendInputToOutput.assert_called_with(0, 0) # Everything blanked self.extras.sendInputToOutput.reset_mock() self.vs.btnExtras.click() self.extras.sendInputToOutput.assert_not_called() # main sw not involved and no input selected self.vs.extrasSwitcher.inputs.buttons()[4].click() # Visuals PC video self.assertEqual("PC video", self.vs.btnExtras.text()) self.extras.sendInputToOutput.assert_called_with(8, EXTRAS_OUTPUT_TO_PREVIEW) self.assertEqual(self.vs.extrasSwitcher.inputs.checkedButton(), self.vs.extrasSwitcher.inputs.buttons()[4]) outputsGrid.btnAll.click() # This one click should trigger two takes, one on each switcher self.extras.sendInputToOutput.assert_called_with(8, 1) self.main.sendInputToOutput.assert_called_with(5, 0) # Extras to everywhere outputsGrid.updateOutputMappings({'Main': {0: 5}}) self.assertEqual("PC video", outputsGrid.btnMonitor1.inputDisplay.text()) self.main.sendInputToOutput.reset_mock() self.extras.sendInputToOutput.reset_mock() self.assertTrue(outputsGrid.isEnabled()) self.assertTrue(outputsGrid.btnPCMix.isEnabled()) outputsGrid.btnPCMix.click() self.assertTrue(outputsGrid.isEnabled()) self.extras.sendInputToOutput.assert_called_with(8, 2) self.preview.sendInputToOutput.assert_called_with(6, 2) # Extras to PC Mix def testCantSendPCMixToItself(self): outputsGrid = self.vs.findChild(OutputsGrid) self.vs.btnVisualsPC.click() self.assertPreviewCalledFor(6) self.main.sendInputToOutput.reset_mock() outputsGrid.btnPCMix.click() self.assertFalse(self.preview.sendInputToOutput.called) self.assertFalse(self.main.sendInputToOutput.called) self.assertFalse(outputsGrid.btnPCMix.isEnabled()) def testCantBlankPCMix(self): outputsGrid = self.vs.findChild(OutputsGrid) self.vs.btnBlank.click() outputsGrid.btnPCMix.click() self.assertFalse(self.preview.sendInputToOutput.called) self.assertFalse(self.main.sendInputToOutput.called) self.assertFalse(outputsGrid.btnPCMix.isEnabled()) def testKeyboardControls(self): QTest.keyClick(self.vs, Qt.Key_0) QTest.keyClick(self.vs, Qt.Key_Space) self.main.sendInputToOutput.assert_called_with(0, 0) QTest.keyClick(self.vs, Qt.Key_1) self.assertPreviewCalledFor(1) QTest.keyClick(self.vs, Qt.Key_Space) self.main.sendInputToOutput.assert_called_with(1, 0) QTest.keyClick(self.vs, Qt.Key_2) self.assertPreviewCalledFor(2) QTest.keyClick(self.vs, Qt.Key_Space) self.main.sendInputToOutput.assert_called_with(2, 0) QTest.keyClick(self.vs, Qt.Key_3) self.assertPreviewCalledFor(3) QTest.keyClick(self.vs, Qt.Key_Space) self.main.sendInputToOutput.assert_called_with(3, 0) QTest.keyClick(self.vs, Qt.Key_4) self.assertPreviewCalledFor(4) QTest.keyClick(self.vs, Qt.Key_Space) self.main.sendInputToOutput.assert_called_with(4, 0) self.extras.sendInputToOutput.reset_mock() QTest.keyClick(self.vs, Qt.Key_5) self.extras.sendInputToOutput.assert_not_called() # main sw not involved and no input selected # Make sure there's an actual channel selected self.vs.extrasSwitcher.inputs.buttons()[3].click() self.assertEqual("Extras 4", self.vs.btnExtras.text()) self.extras.sendInputToOutput.assert_called_with(4, EXTRAS_OUTPUT_TO_PREVIEW) QTest.keyClick(self.vs, Qt.Key_Space) self.main.sendInputToOutput.assert_called_with(5, 0) QTest.keyClick(self.vs, Qt.Key_6) self.assertPreviewCalledFor(6) QTest.keyClick(self.vs, Qt.Key_Space) self.main.sendInputToOutput.assert_called_with(6, 0) self.main.sendInputToOutput.reset_mock() self.preview.sendInputToOutput.reset_mock() QTest.keyClick(self.vs, Qt.Key_7) self.assertFalse(self.preview.sendInputToOutput.called) QTest.keyClick(self.vs, Qt.Key_Space) self.main.sendInputToOutput.assert_called_with(6, 0) # which was the last valid input key pressed def testNotSendNullExtra(self): outputsGrid = self.vs.findChild(OutputsGrid) self.vs.btnExtras.click() self.assertIsNone(self.vs.extrasSwitcher.currentInput()) self.assertFalse(outputsGrid.isEnabled()) self.assertTrue(self.vs.extrasSwitcher.noInputWarning.isVisibleTo(self.vs.extrasSwitcher)) def assertPreviewCalledFor(self, inputID): self.main.sendInputToOutput.assert_called_with(inputID, 1) return self.extras.sendInputToOutput.assert_called_with(EXTRAS_INPUT_FROM_MAIN, EXTRAS_OUTPUT_TO_PREVIEW)
def __init__(self, controller): super(MainWindow, self).__init__() self.controller = controller self.setWindowTitle("av-control") self.resize(1024, 600) self.setWindowIcon(QIcon(":icons/video-display")) self.mainScreen = VideoSwitcher(controller, self) self.stack = QStackedWidget() self.stack.addWidget(self.mainScreen) outer = QWidget() mainLayout = QGridLayout() mainLayout.addWidget(self.stack, 0, 0, 1, 7) column = 0 self.spc = SystemPowerWidget(controller, self) syspower = ExpandingButton() syspower.setText("Power") syspower.clicked.connect(self.showSystemPower) syspower.setIcon(QIcon(":icons/system-shutdown")) syspower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(syspower, 1, column) column += 1 self.bc = BlindsControl(controller["Blinds"], self) blinds = ExpandingButton() blinds.setText("Blinds") blinds.clicked.connect(lambda: self.showScreen(self.bc)) blinds.setIcon(QIcon(":icons/blinds")) blinds.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(blinds, 1, column) column += 1 self.sc = ProjectorScreensControl(controller["Screens"], self) screens = ExpandingButton() screens.setText("Screens") screens.clicked.connect(lambda: self.showScreen(self.sc)) screens.setIcon(QIcon(":icons/screens")) screens.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(screens, 1, column) column += 1 if controller.hasDevice("Lights"): self.lightsMenu = LightingControl(controller["Lights"], self) lights = ExpandingButton() lights.setText("Lights") lights.clicked.connect(lambda: self.showScreen(self.lightsMenu)) lights.setIcon(QIcon(":icons/lightbulb_on")) lights.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(lights, 1, column) column += 1 self.advMenu = AdvancedMenu(self.controller, self) adv = ExpandingButton() adv.setText("Advanced") adv.setIcon(QIcon(":icons/applications-system")) adv.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) adv.clicked.connect(lambda: self.showScreen(self.advMenu)) mainLayout.addWidget(adv, 1, column) column += 1 for i in range(column): mainLayout.setColumnStretch(i, 1) tray = QHBoxLayout() tray.addWidget(Clock()) tray.addWidget(SystemStatus(controller)) mainLayout.addLayout(tray, 1, column) mainLayout.setRowStretch(0, 8) mainLayout.setRowStretch(1, 0) outer.setLayout(mainLayout) self.setCentralWidget(outer) self.pnd = PowerNotificationDialog(self) self.pnd.accepted.connect(self.hidePowerDialog)
def __init__(self, controller, joystickAdapter=None): super(MainWindow, self).__init__() self.controller = controller self.setWindowTitle("av-control") self.resize(1024, 600) self.setWindowIcon(QIcon(":icons/video-display")) atem = controller['ATEM'] self.switcherState = SwitcherState(atem) self.mainScreen = VideoSwitcher(controller, self, self.switcherState, joystickAdapter) # This is possibly a bad / too complicated idea... # self.mainScreen.setEnabled(self.switcherState.connected) # self.switcherState.connectionChanged.connect(self.mainScreen.setEnabled) self.stack = QStackedWidget() self.stack.addWidget(self.mainScreen) outer = QWidget() mainLayout = QGridLayout() mainLayout.addWidget(self.stack, 0, 0, 1, 7) column = 0 self.spc = SystemPowerWidget(controller, self) syspower = ExpandingButton() syspower.setText("Power") syspower.clicked.connect(self.showSystemPower) syspower.setIcon(QIcon(":icons/system-shutdown")) syspower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(syspower, 1, column) column += 1 if controller.hasDevice("Blinds"): self.bc = BlindsControl(controller["Blinds"], self) blinds = ExpandingButton() blinds.setText("Blinds") blinds.clicked.connect(lambda: self.showScreen(self.bc)) blinds.setIcon(QIcon(":icons/blinds")) blinds.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(blinds, 1, column) column += 1 if controller.hasDevice("Lights"): self.lightsMenu = LightingControl(controller["Lights"], self) lights = ExpandingButton() lights.setText("Lights") lights.clicked.connect(lambda: self.showScreen(self.lightsMenu)) lights.setIcon(QIcon(":icons/lightbulb_on")) lights.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(lights, 1, column) column += 1 if controller.hasDevice("Recorder"): hyperdeck = controller['Recorder'] self.hyperdeckState = HyperdeckState(hyperdeck) self.recorderScreen = RecorderControl(hyperdeck, atem, self.hyperdeckState, self) recorder = ExpandingButton() recorder.setText("Recorder") recorder.setIcon(QIcon(":icons/drive-optical")) recorder.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) recorder.clicked.connect(lambda: self.showScreen(self.recorderScreen)) mainLayout.addWidget(recorder, 1, column) column += 1 def update_recorder_icon(transport): if 'status' in transport: if transport['status'] == TransportState.RECORD: recorder.setIcon(QIcon(":icons/media-record")) elif transport['status'] == TransportState.PLAYING: recorder.setIcon(QIcon(":icons/media-playback-start")) else: recorder.setIcon(QIcon(":icons/drive-optical")) self.hyperdeckState.transportChange.connect(update_recorder_icon) self.advMenu = AdvancedMenu(self.controller, self.switcherState.mixTransition, atem, self) adv = ExpandingButton() adv.setText("Advanced") adv.setIcon(QIcon(":icons/applications-system")) adv.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) adv.clicked.connect(lambda: self.showScreen(self.advMenu)) mainLayout.addWidget(adv, 1, column) column += 1 for i in range(column): mainLayout.setColumnStretch(i, 1) tray = QHBoxLayout() tray.addWidget(Clock()) tray.addWidget(SystemStatus(controller)) mainLayout.addLayout(tray, 1, column) mainLayout.setRowStretch(0, 8) mainLayout.setRowStretch(1, 0) outer.setLayout(mainLayout) self.setCentralWidget(outer) self.pnd = PowerNotificationDialog(self) self.pnd.accepted.connect(self.hidePowerDialog)
class MainWindow(QMainWindow): def __init__(self, controller, joystickAdapter=None): super(MainWindow, self).__init__() self.controller = controller self.setWindowTitle("av-control") self.resize(1024, 600) self.setWindowIcon(QIcon(":icons/video-display")) atem = controller['ATEM'] self.switcherState = SwitcherState(atem) self.mainScreen = VideoSwitcher(controller, self, self.switcherState, joystickAdapter) # This is possibly a bad / too complicated idea... # self.mainScreen.setEnabled(self.switcherState.connected) # self.switcherState.connectionChanged.connect(self.mainScreen.setEnabled) self.stack = QStackedWidget() self.stack.addWidget(self.mainScreen) outer = QWidget() mainLayout = QGridLayout() mainLayout.addWidget(self.stack, 0, 0, 1, 7) column = 0 self.spc = SystemPowerWidget(controller, self) syspower = ExpandingButton() syspower.setText("Power") syspower.clicked.connect(self.showSystemPower) syspower.setIcon(QIcon(":icons/system-shutdown")) syspower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(syspower, 1, column) column += 1 if controller.hasDevice("Blinds"): self.bc = BlindsControl(controller["Blinds"], self) blinds = ExpandingButton() blinds.setText("Blinds") blinds.clicked.connect(lambda: self.showScreen(self.bc)) blinds.setIcon(QIcon(":icons/blinds")) blinds.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(blinds, 1, column) column += 1 if controller.hasDevice("Lights"): self.lightsMenu = LightingControl(controller["Lights"], self) lights = ExpandingButton() lights.setText("Lights") lights.clicked.connect(lambda: self.showScreen(self.lightsMenu)) lights.setIcon(QIcon(":icons/lightbulb_on")) lights.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) mainLayout.addWidget(lights, 1, column) column += 1 if controller.hasDevice("Recorder"): hyperdeck = controller['Recorder'] self.hyperdeckState = HyperdeckState(hyperdeck) self.recorderScreen = RecorderControl(hyperdeck, atem, self.hyperdeckState, self) recorder = ExpandingButton() recorder.setText("Recorder") recorder.setIcon(QIcon(":icons/drive-optical")) recorder.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) recorder.clicked.connect(lambda: self.showScreen(self.recorderScreen)) mainLayout.addWidget(recorder, 1, column) column += 1 def update_recorder_icon(transport): if 'status' in transport: if transport['status'] == TransportState.RECORD: recorder.setIcon(QIcon(":icons/media-record")) elif transport['status'] == TransportState.PLAYING: recorder.setIcon(QIcon(":icons/media-playback-start")) else: recorder.setIcon(QIcon(":icons/drive-optical")) self.hyperdeckState.transportChange.connect(update_recorder_icon) self.advMenu = AdvancedMenu(self.controller, self.switcherState.mixTransition, atem, self) adv = ExpandingButton() adv.setText("Advanced") adv.setIcon(QIcon(":icons/applications-system")) adv.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) adv.clicked.connect(lambda: self.showScreen(self.advMenu)) mainLayout.addWidget(adv, 1, column) column += 1 for i in range(column): mainLayout.setColumnStretch(i, 1) tray = QHBoxLayout() tray.addWidget(Clock()) tray.addWidget(SystemStatus(controller)) mainLayout.addLayout(tray, 1, column) mainLayout.setRowStretch(0, 8) mainLayout.setRowStretch(1, 0) outer.setLayout(mainLayout) self.setCentralWidget(outer) self.pnd = PowerNotificationDialog(self) self.pnd.accepted.connect(self.hidePowerDialog) def showScreen(self, screenWidget): if self.stack.currentWidget() == screenWidget: self.stepBack() else: self.stack.insertWidget(0, screenWidget) self.stack.setCurrentWidget(screenWidget) def showSystemPower(self): self.showScreen(self.spc) def stepBack(self): self.stack.removeWidget(self.stack.currentWidget()) def errorBox(self, text): Dialogs.errorBox(text) def showPowerDialog(self, message): self.pnd.message = message self.pnd.exec_() def hidePowerDialog(self): self.pnd.close() if self.stack.currentWidget() == self.spc: self.stepBack() def updateOutputMappings(self, deviceID, mapping): self.mainScreen.updateOutputMappings({deviceID: mapping}) def handleMessage(self, msgType, sourceDeviceID, data): if msgType == MessageTypes.SHOW_POWER_ON: self.showPowerDialog(StringConstants.poweringOn) elif msgType == MessageTypes.SHOW_POWER_OFF: self.showPowerDialog(StringConstants.poweringOff) elif msgType == MessageTypes.HIDE_POWER: self.hidePowerDialog() elif sourceDeviceID == "ATEM": self.switcherState.handleMessage(msgType, data) elif sourceDeviceID == "Recorder": self.hyperdeckState.handleMessage(msgType, data)