Example #1
0
class DeviceDiscovery(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Setup UI
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        # Block inputs to application while dialogue active
        self.setWindowModality(Qt.ApplicationModal)
        # Set style sheet
        with open(getPath('main_ld.qss'), 'r') as style_file:
            self.setStyleSheet(style_file.read())
        # Get devices and save to JSON
        self.findDevices()
        # Add devices to menu
        self.addDevices()

    def findDevices(self):
        # Clear cache
        JsonIO('devices.json').clearLayout('discovered_devices', 'devices')
        # Repopulate cache
        SerialFinder()
        # Remove added devices
        self.json = JsonIO('devices.json')
        self.discovered_devices = list(self.json.readEntry(
            'discovered_devices')['devices'].keys())
        self.known_devices = self.json.readEntry('known_devices')['devices']
        for device in self.known_devices.values():
            self.port = device['command']['payload']
            if self.port in self.discovered_devices:
                self.json.removeSingleEntry('discovered_devices', self.port)

    def addDevices(self):
        # Imports done here to prevent circular imports
        from src.ui.generate_buttons import GenerateButtons
        GenerateButtons('devices.json', 'discovered_devices').generateGenericButtons(
            self.ui.discovery_button_layout, self.ui.discovery_scroll_region, 'primary', spacer=True)
        # Additional spacer below buttons for better separation between border and bottom button
        self.ui.discovery_button_layout.addItem(QSpacerItem(
            20, 40, QSizePolicy.Minimum, QSizePolicy.Fixed))
Example #2
0
class DeviceRemoval(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Setup UI
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        # Block inputs to application while dialogue active
        self.setWindowModality(Qt.ApplicationModal)
        # Set style sheet
        with open(getPath('main_ld.qss'), 'r') as style_file:
            self.setStyleSheet(style_file.read())
        # Get devices and save to JSON
        self.findDevices()
        # Add devices to menu
        self.addDevices()

    def findDevices(self):
        # Clear cache
        JsonIO('devices.json').clearLayout('discovered_devices', 'devices')
        # Repopulate cache
        SerialFinder()

    def addDevices(self):
        # Imports done here to prevent circular imports
        from src.ui.generators.create_large_button import CreateLargeButton
        self.json = JsonIO('devices.json')
        self.discovered_devices = list(self.json.readEntry(
            'discovered_devices')['devices'].keys())
        self.known_devices = self.json.readEntry('known_devices')['devices']
        for device_name, device_attributes in self.known_devices.items():
            self.attr = {
                'command': {
                    'payload': device_name,
                    'type': 'removeDevice'},
                'text': device_attributes['text']}
            self.btn = CreateLargeButton(self.ui.discovery_button_layout, spacer=True, effect_btn=False).createGenericButton(
                'name', self.attr, self.ui.discovery_scroll_region, 'primary', right_click_menu=None)
Example #3
0
class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        __globals__.parent = self
        self.setupFiles()
        settings.reloadSettings()
        Effects()
        self.version = __version__.__version__
        __globals__.refreshMenus = lambda: self.refreshMenus()
        __globals__.serial_thread = QThread()
        # UI initialisation
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        # Setup UI elements
        self.createRightClickMenus()
        self.setupButtons()
        __globals__.colour_picker = QColorDialog(self)
        self.list_menu = CreateMenuContext(parent=self).makeMenu()
        # Initialise first communication
        self.DevicesJson = JsonIO('devices.json')
        try:
            self.comm_name = list(
                self.DevicesJson.readEntry('selected_device')
                ['devices'].keys())[0]
            self.comm_attr = list(
                self.DevicesJson.readEntry('selected_device')
                ['devices'].values())[0]
            __globals__.current_strip = int(
                list(
                    self.DevicesJson.readEntry('selected_device')
                    ['strips'].keys())[0])
        except:
            self.comm_name = None
        if self.comm_name and self.comm_attr:
            ButtonActions.selectDevice((self.comm_name, self.comm_attr))

    def setupFiles(self):
        self.init_files = [
            'menus.json', 'settings.json', 'effects.json', 'devices.json'
        ]
        # Copy all files from base dir if they don't already exist
        for file in self.init_files:
            if JsonIO(file).fileExists():
                pass
            else:
                JsonIO(file).copyFromBase()

    def refreshMenus(self):
        try:
            # Reset main menu
            GenerateButtons('menus.json', 'main_menu').removeButtons(
                self.ui.main_menu_button_layout)
            GenerateButtons('menus.json', 'main_menu').generateGenericButtons(
                self.ui.main_menu_button_layout,
                self.ui.effects_scroll_region,
                'primary',
                self.right_click_menu_effects,
                spacer=True,
                effect_btn=True)
            # Reset settings menu
            GenerateButtons('settings.json', 'settings').removeButtons(
                self.ui.settings_button_layout)
            GenerateButtons('settings.json',
                            'settings').generateGenericButtons(
                                self.ui.settings_button_layout,
                                self.ui.settings_scroll_region,
                                'primary',
                                spacer=True)
        except:
            if settings.do_logs:
                __globals__.logger.error(
                    'Failed to reload menu(s), are preferences corrupted?')

    def setupButtons(self):
        # Add elements controlled by advanced mode to global list
        __globals__.advanced_mode_elements.append(self.ui.btn_device_debug)
        __globals__.advanced_mode_elements.append(
            self.ui.btn_device_information)
        # Refresh menus
        self.refreshMenus()
        # Bottom bar
        self.ui.btn_version.setText(f'Version {self.version}')
        self.ui.btn_device_debug.clicked.connect(
            lambda: self.initSerialMonitor())
        self.ui.btn_effect_off.clicked.connect(self.toggleLeds)
        self.ui.btn_device_information.clicked.connect(
            lambda: QMessageBox.information(
                self, 'Device Information',
                f'Device Name: {__globals__.board_data["name"]}\n'
                f'COM Port: {__globals__.board_data["port"]}\n'
                f'Physical Strips: {__globals__.board_data["physical_strips"]}\n'
                f'Virtual Strips: {__globals__.board_data["virtual_strips"]}\n'
                f'ArduRGB Version: {__globals__.board_data["version"]}\n'
                f'Board: {__globals__.board_data["type"]}\n'))
        self.ui.slider_brightness.sliderReleased.connect(self.setBright)
        # Left bar
        self.ui.btn_menu_effects.clicked.connect(
            lambda: self.changePage(self.ui.main_menus, 0))
        self.ui.btn_menu_settings.clicked.connect(
            lambda: self.changePage(self.ui.main_menus, 1))
        self.ui.btn_list_device.clicked.connect(
            lambda: self.initListMenu('devices'))
        self.ui.btn_list_device.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.btn_list_device.customContextMenuRequested.connect(
            lambda: self.contextMenu(self.right_click_menu_devices))
        __globals__.strips_menu = self.ui.btn_list_strip
        # Effects menu
        self.ui.btn_menu_effect_new.clicked.connect(
            lambda: self.initDialogue('main_menu', 'Create New Effect'))
        self.ui.btn_menu_effect_reset.clicked.connect(lambda: CreateMessageBox(
            'Reset Effects Menu',
            'This action will erase all custom effects you have specified. Continue?'
        ).resetPreferences(file='menus.json',
                           menu='main_menu',
                           layout='main_menu_button_layout'))
        # Settings menu
        self.ui.btn_settings_reset.clicked.connect(lambda: CreateMessageBox(
            'Reset Settings',
            'This action will revert all settings to their defaults. Continue?'
        ).resetPreferences(
            file='settings.json', reset_file=True, reload_settings=True))

    def changePage(self, widget, index):
        widget.setCurrentIndex(index)

    def createRightClickMenus(self):
        self.right_click_json = JsonIO('right_click_menu.json')
        self.right_click_create = CreateMenuEffectEdit(parent=self)
        # Effects right click menu
        self.right_click_menu_effects = self.genRightClickMenu(
            'main_menu_right_click_menu')
        # Devices right click menu
        self.right_click_menu_devices = self.genRightClickMenu(
            'devices_right_click_menu')

    def genRightClickMenu(self, menu):
        # Get menu options
        options = self.right_click_json.readEntry(menu)
        # Create new right click menu
        r_c_menu = self.right_click_create.makeMenu()
        # Add all JSON entries as options to right click menu
        for entry_name, entry_payload in options.items():
            self.right_click_create.addOption(r_c_menu, entry_name,
                                              entry_payload)
        return r_c_menu

    def setBright(self):
        self.current_brightness = self.ui.slider_brightness.value()
        comm.run('write', f'setbright,{self.current_brightness}', 'ArduRGB')

    def toggleLeds(self):
        comm.run('write', 'toggleleds', 'ArduRGB')

    def setWindowParams(self, window, title, icon=None):
        window.setWindowTitle(title)
        window.show()
        # window.setWindowIcon(icon)

    def initSerialMonitor(self):
        self.serial_monitor = SerialMonitor()
        self.setWindowParams(self.serial_monitor, 'Serial Port Debug View')

    def initDialogue(self, menu, window_title):
        self.input_dialogue = InputDialogue(menu)
        self.setWindowParams(self.input_dialogue, window_title)

    def initListMenu(self, menu):
        self.DevicesJson = JsonIO('devices.json')
        self.ContextMenuGen = CreateMenuContext(parent=self)
        # Clear menu actions
        self.list_menu.clear()
        # Get actions from file
        self.connected_devices = self.DevicesJson.readEntry('known_devices')
        self.device_list = self.connected_devices[menu]
        for device_name, device_attributes in self.device_list.items():
            self.selected_devices = list(
                self.DevicesJson.readEntry('selected_device')
                ['devices'].keys())
            try:
                # Set highlighted entry
                if device_name == list(
                        self.DevicesJson.readEntry('selected_device')
                    ['devices'].keys())[0]:
                    self.ContextMenuGen.addOption(
                        self.list_menu,
                        device_name,
                        (None, ('selectDevice',
                                (device_name, device_attributes))),
                        highlighted=True)
                # Set non-highlighted entry
                else:
                    self.ContextMenuGen.addOption(
                        self.list_menu, device_name,
                        (None, ('selectDevice',
                                (device_name, device_attributes))))
            # Set non-highlighted entry
            except:
                self.ContextMenuGen.addOption(
                    self.list_menu, device_name,
                    (None, ('selectDevice', (device_name, device_attributes))))
        # Place context menu at cursor position
        self.list_menu.exec(QCursor.pos())

    def contextMenu(self, menu):
        menu.exec(QCursor.pos())

    def mousePressEvent(self, event):
        pass