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 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 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 effectTypeSelect(self): # Read entries from JSON self.effect_types = JsonIO('effects.json').readEntry('effects') # Create new right click menu self.menu_effects = CreateMenuContext(parent=self).makeMenu() # Add all JSON entries as options to right click menu for effect_name, effect_class in self.effect_types.items(): self.menu_args = (self.ui.btn_effect_types, effect_class) CreateMenuContext(parent=self).addOption(self.menu_effects, effect_name, (self.menu_args))
class BaseFinder(): def __init__(self, *args, **kwargs): self.json = JsonIO('devices.json') def addDevice(self, name, type, port): self.command = {'type': type, 'payload': port} self.json.writeEntry('discovered_devices', 'devices', port, name, self.command, sort_keys=True)
def selectStrip(strip, *args, **kwargs): from src.rw.jsonio import JsonIO __globals__.current_strip = strip # Clear existing strip JsonIO('devices.json').blankCopy('selected_device', 'strips', dump=True) # Write new strip JsonIO('devices.json').writeRaw('selected_device', 'strips', strip, None, sort_keys=True)
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.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)
def findEffects(self): # Store effects dict self.effects_dict = {'effects': {}} # Find all valid python files for file in self.effects_files: self.file_path = abspath(join(self.effects_path, file)) if isfile(self.file_path) and file.endswith( '.py') and file != '__init__.py': # Format file name self.effect = file.split('.py')[0] # Import file try: self.module = __import__( f'{__globals__.effect_import_path}.{self.effect}', fromlist=[None]) self.effect_class = getattr(self.module, self.effect) # Get effect name self.effect_name = getattr(self.effect_class, 'effectData')() self.effects_dict['effects'][ self.effect_name] = self.effect except: if settings.do_logs: __globals__.logger.error( f'Failed to load effect definitions from {__globals__.effect_import_path}.{self.effect}, ' f'does module exist / contain __init__ and effectData methods?' ) # Write effect data to file JsonIO('effects.json').dumpJson(self.effects_dict)
def selectDevice(device, *args, **kwargs): from src.serial.serialio import SerialIO from src.rw.jsonio import JsonIO device_name = device[0] device_attributes = device[1] # Clear existing device JsonIO('devices.json').blankCopy('selected_device', 'devices', dump=True) # Write new device JsonIO('devices.json').writeRaw('selected_device', 'devices', device_name, device_attributes, sort_keys=True) # Set new communcation type comm_type = device_attributes['command']['type'] comm_port = device_attributes['command']['payload'] # Initialise communication comm_objects = {'serial': SerialIO} comm_globals = ['serial'] disable_strips = [] try: # Init device communication comm_objects[comm_type](comm_port) # Display debugging tools if previously disabled from invalid device if settings.advanced_mode: settings.setAdvancedModeVisible(override=True) # Disable strips menu if comm_type in disable_strips: __globals__.strips_menu.setVisible(False) else: __globals__.strips_menu.setVisible(True) except: if settings.do_logs: __globals__.logger.error( f'Failed to initialise {comm_type} communication through {comm_port}' ) # Set all communications to None for global_var in comm_globals: setattr(__globals__, global_var, None) # Clear global board data __globals__.board_data = {'name': None, 'type': None, 'port': None} # Disable strips menu __globals__.strips_menu.setVisible(False) # Disable debugging tools settings.setAdvancedModeVisible(override=False)
def deleteButton(self): # Delete button if user confirms in message box if CreateMessageBox('Delete Effect', 'This action will remove this button. Continue?' ).confirmDelete(): JsonIO(self.file).removeEntry(self.button.objectName()) # Refresh menu __globals__.refreshMenus()
def resetPreferences(self, file, menu=None, layout=None, reset_file=False, reload_settings=False): # Get input from user and continue only if input was 'yes' if self.getBool(): if reset_file: JsonIO(file).copyFromBase() else: JsonIO(file).copyLayout(menu, layout) # Reload settings if reload_settings: settings.reloadSettings() # Refresh menu button layout using JSON __globals__.refreshMenus()
def removeDevice(device, *args, **kwargs): from src.rw.jsonio import JsonIO Json = JsonIO('devices.json') Json.removeSingleEntry('known_devices', device) # Clear device selection if forgetting currently selected device try: Json.removeSingleEntry('selected_device', device) Json.clearLayout('selected_devices', 'strips') except: pass
def __init__(self, menu, new_entry=True, btn_name=None, *args, **kwargs): super().__init__(*args, **kwargs) # Setup UI self.ui = Ui_Form() self.ui.setupUi(self) # Initialise variables self.effect_name = None self.effect_payload = None self.menu = menu self.new_entry = new_entry self.btn_name = btn_name # Get buttons from current menu self.page_contents = JsonIO('menus.json').readEntry(self.menu) # Initialise effect type selection menu self.effectTypeSelect() # Open effect drop down when 'effects' button clicked self.ui.btn_effect_types.clicked.connect( lambda: self.contextMenu(self.menu_effects)) # Add functionality to 'submit' button self.ui.btn_submit.clicked.connect(self.getInputs) # Create input types super().genValidators(button=self.ui.btn_payload_type, entry=self.ui.input_effect_payload) # Get existing data from button if editing if new_entry: # Clear current menu selection __globals__.popup_menu_selection = None else: # Get button data self.btn = JsonIO('menus.json').findElement(self.btn_name) # Set existing text entry fields self.ui.input_effect_name.setText(self.btn[0]) self.ui.btn_effect_types.setText(self.btn[1]) self.ui.input_effect_payload.setText(self.btn[2].split(']')[1]) self.selected_type = self.btn[2].split(']')[0].split('[')[1] self.ui.input_effect_payload.setValidator( self.input_types[self.selected_type]) print(self.selected_type) self.ui.btn_payload_type.setText(f'Input: {self.selected_type}') # Set current menu selection __globals__.popup_menu_selection = self.btn[3] # Block inputs to application while dialogue active self.setWindowModality(Qt.ApplicationModal)
def createEffect(self, menu, layout, entry_name): self.command = { 'type': __globals__.popup_menu_selection, 'payload': f'[{self.selected_type}]{self.effect_payload}' } JsonIO('menus.json').writeEntry(menu, layout, entry_name, self.effect_name, self.command, sort_keys=False)
def setBoardInfo(cls): __globals__.board_data_buffer += SerialIO.read(__globals__.serial) # Finished reading data if __globals__.board_data_lines: # Disconnect slot __globals__.serial.readyRead.disconnect(SerialIO.setBoardInfo) # Create list of board data serial_data = __globals__.board_data_buffer serial_data = serial_data.strip('\r\n').split(',') # Ensure received message contains all data try: # Get relevant data if len(serial_data) == int(serial_data[0]) + 1: board_data = { 'name': serial_data[1], 'type': serial_data[2], 'version': serial_data[3], 'physical_strips': serial_data[4], 'virtual_strips': serial_data[5], 'default_brightness': serial_data[6], 'port': __globals__.serial.portName() } __globals__.board_data = board_data __globals__.comm_module = [__name__, cls.__name__] command = { 'type': 'serial', 'payload': __globals__.serial.portName() } JsonIO('devices.json').writeEntry('known_devices', 'devices', serial_data[1], serial_data[1], command, sort_keys=True) # Update brightness slider __globals__.parent.ui.slider_brightness.setValue( int(serial_data[6])) # Show strips menu when clicked __globals__.strips_menu.clicked.connect( lambda: initStripsMenu(int(serial_data[5]))) else: if settings.do_logs: __globals__.logger.warn( f'Serial input {serial_data[1:]} not of expected size {serial_data[0]}' ) except: if settings.do_logs: __globals__.logger.warn( f'Expected type integer, instead got {serial_data[0]}') # Read next line from serial - message sent in two lines else: __globals__.board_data_lines += 1
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))
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)
def reloadSettings(): ld_settings = JsonIO('settings.json').readEntry('settings') settings = ld_settings['settings_button_layout'] for option_name, option_contents in settings.items(): # Ensure option is toggle if option_contents['command']['type'] == 'toggleBool': # Update each option with value from file globals()[option_name] = option_contents['command']['payload'] options = { 'advanced_mode': setAdvancedModeVisible, 'do_logs': initLogs } # Run function associated with option if option_name in list(options.keys()): options.get(option_name)()
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 checkInputs(self, generated_object_name): # Cycle through existing effects to ensure effect does not exist already if self.new_entry: for menu in self.page_contents: for element in self.page_contents[menu]: if element == generated_object_name: # Raise error to user self.ui.label_error.setText('Effect already exists') return False # Only runs if effect does not already exist self.createEffect('main_menu', 'main_menu_button_layout', generated_object_name) self.exitWindow() # Edit existing entry else: # Replace existing button data with new data JsonIO('menus.json').replaceEntry( self.btn_name, generated_object_name, self.effect_name, __globals__.popup_menu_selection, f'[{self.selected_type}]{self.effect_payload}') self.exitWindow()
class InputDialogue(QWidget, InputTypes): def __init__(self, menu, new_entry=True, btn_name=None, *args, **kwargs): super().__init__(*args, **kwargs) # Setup UI self.ui = Ui_Form() self.ui.setupUi(self) # Initialise variables self.effect_name = None self.effect_payload = None self.menu = menu self.new_entry = new_entry self.btn_name = btn_name # Get buttons from current menu self.page_contents = JsonIO('menus.json').readEntry(self.menu) # Initialise effect type selection menu self.effectTypeSelect() # Open effect drop down when 'effects' button clicked self.ui.btn_effect_types.clicked.connect( lambda: self.contextMenu(self.menu_effects)) # Add functionality to 'submit' button self.ui.btn_submit.clicked.connect(self.getInputs) # Create input types super().genValidators(button=self.ui.btn_payload_type, entry=self.ui.input_effect_payload) # Get existing data from button if editing if new_entry: # Clear current menu selection __globals__.popup_menu_selection = None else: # Get button data self.btn = JsonIO('menus.json').findElement(self.btn_name) # Set existing text entry fields self.ui.input_effect_name.setText(self.btn[0]) self.ui.btn_effect_types.setText(self.btn[1]) self.ui.input_effect_payload.setText(self.btn[2].split(']')[1]) self.selected_type = self.btn[2].split(']')[0].split('[')[1] self.ui.input_effect_payload.setValidator( self.input_types[self.selected_type]) print(self.selected_type) self.ui.btn_payload_type.setText(f'Input: {self.selected_type}') # Set current menu selection __globals__.popup_menu_selection = self.btn[3] # Block inputs to application while dialogue active self.setWindowModality(Qt.ApplicationModal) def effectTypeSelect(self): # Read entries from JSON self.effect_types = JsonIO('effects.json').readEntry('effects') # Create new right click menu self.menu_effects = CreateMenuContext(parent=self).makeMenu() # Add all JSON entries as options to right click menu for effect_name, effect_class in self.effect_types.items(): self.menu_args = (self.ui.btn_effect_types, effect_class) CreateMenuContext(parent=self).addOption(self.menu_effects, effect_name, (self.menu_args)) def contextMenu(self, menu): # Place context menu at cursor position menu.exec(QCursor.pos()) def getInputs(self): # Reset user presented error self.ui.label_error.setText('') # Update variables with user input self.effect_name = self.ui.input_effect_name.text() self.effect_payload = self.ui.input_effect_payload.text() # Ensure no input is blank except for payload # if not self.effect_name or not self.effect_payload or not __globals__.popup_menu_selection: if not self.effect_name or not __globals__.popup_menu_selection: # Raise error to user self.ui.label_error.setText('Input(s) cannot be left empty') else: self.genObjectName(self.effect_name) def genObjectName(self, user_input): self.object_name = 'btn_effect' # Create formatted object name for word in user_input.split(' '): self.object_name += '_' + word self.object_name = self.object_name.lower() self.checkInputs(self.object_name) def checkInputs(self, generated_object_name): # Cycle through existing effects to ensure effect does not exist already if self.new_entry: for menu in self.page_contents: for element in self.page_contents[menu]: if element == generated_object_name: # Raise error to user self.ui.label_error.setText('Effect already exists') return False # Only runs if effect does not already exist self.createEffect('main_menu', 'main_menu_button_layout', generated_object_name) self.exitWindow() # Edit existing entry else: # Replace existing button data with new data JsonIO('menus.json').replaceEntry( self.btn_name, generated_object_name, self.effect_name, __globals__.popup_menu_selection, f'[{self.selected_type}]{self.effect_payload}') self.exitWindow() def createEffect(self, menu, layout, entry_name): self.command = { 'type': __globals__.popup_menu_selection, 'payload': f'[{self.selected_type}]{self.effect_payload}' } JsonIO('menus.json').writeEntry(menu, layout, entry_name, self.effect_name, self.command, sort_keys=False) def exitWindow(self): # Update menu layout with new JSON __globals__.refreshMenus() # Close input menu self.close()
def moveButtonDown(self): JsonIO(self.file).shiftEntry(self.button, 1) # Refresh menu __globals__.refreshMenus()
def findDevices(self): # Clear cache JsonIO('devices.json').clearLayout('discovered_devices', 'devices') # Repopulate cache SerialFinder()
def updateBool(self, text, entry_name, switch): # Update settings file JsonIO('settings.json').replaceEntry(entry_name, entry_name, text, 'toggleBool', switch.isChecked()) # Run toggle action ButtonActions.toggleBool()
class GenerateButtons(): def __init__(self, file, page): self.file = file self.page_contents = JsonIO(file).readEntry(page) self.button = __globals__.current_hovered_btn def generateGenericButtons(self, vertical_element, scroll_element, style, right_click_menu=None, spacer=False, effect_btn=False): for elements in self.page_contents.values(): for element_name, element_attributes in elements.items(): # Create toggle button if element_attributes['command']['type'] == 'toggleBool': self.btn = CreateLargeButton( vertical_element, spacer=spacer).createToggleButton( element_name, element_attributes, scroll_element, style) # Create pushbutton else: self.btn = CreateLargeButton( vertical_element, spacer=spacer, effect_btn=effect_btn).createGenericButton( element_name, element_attributes, scroll_element, style, right_click_menu) @staticmethod def removeButtons(layout): for i in reversed(range(layout.count())): try: widget = layout.takeAt(i).widget() item = layout.itemAt(i) # Remove widget if widget: widget.deleteLater() # Remove spacer item elif item: item.removeItem() except: if settings.do_logs: __globals__.logger.error( f'Failed to remove UI element in layout {layout.objectName()}' f' at UI position {i}') @staticmethod def editButton(): button = __globals__.current_hovered_btn # Reset input window __globals__.popup_view = None # Set up input window __globals__.popup_view = InputDialogue('main_menu', new_entry=False, btn_name=button.objectName()) __globals__.popup_view.setWindowTitle('Edit Effect') __globals__.popup_view.show() def deleteButton(self): # Delete button if user confirms in message box if CreateMessageBox('Delete Effect', 'This action will remove this button. Continue?' ).confirmDelete(): JsonIO(self.file).removeEntry(self.button.objectName()) # Refresh menu __globals__.refreshMenus() def moveButtonUp(self): JsonIO(self.file).shiftEntry(self.button, -1) # Refresh menu __globals__.refreshMenus() def moveButtonDown(self): JsonIO(self.file).shiftEntry(self.button, 1) # Refresh menu __globals__.refreshMenus() @staticmethod def deviceDiscovery(*args, **kwargs): from src.ui.views.discovery.device_discovery import DeviceDiscovery # Reset input window __globals__.popup_view = None __globals__.popup_view = DeviceDiscovery() __globals__.popup_view.setWindowTitle('Device Discovery') __globals__.popup_view.show() @staticmethod def deviceRemoval(*args, **kwargs): from src.ui.views.discovery.device_removal import DeviceRemoval # Reset input window __globals__.popup_view = None __globals__.popup_view = DeviceRemoval() __globals__.popup_view.setWindowTitle('Forget Devices') __globals__.popup_view.show()
def __init__(self, file, page): self.file = file self.page_contents = JsonIO(file).readEntry(page) self.button = __globals__.current_hovered_btn
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
def __init__(self, *args, **kwargs): self.json = JsonIO('devices.json')