コード例 #1
0
def show_settings(window) -> None:
    """Shows the settings dialog and allows the user the change deck specific
    settings. Settings are not saved until OK is clicked."""
    ui = window.ui
    main_window = window
    deck_id = _deck_id(ui)
    settings = SettingsDialog(window)
    dimmers[deck_id].stop()

    settings.ui.buttonfeedback.addItem("Disabled")
    settings.ui.buttonfeedback.addItem("Enabled")

    if api.get_feedback_enabled(deck_id) == "Enabled":
        settings.ui.buttonfeedback.setCurrentIndex(1)
    else:
        settings.ui.buttonfeedback.setCurrentIndex(0)

    settings.ui.buttonfeedback.currentTextChanged.connect(
        partial(update_feedback_enabled, ui))

    location = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            "ok.png")
    settings.ui.removeButton.clicked.connect(
        api.set_default_custom_image_for_feedback(deck_id))

    settings.ui.imageButton.clicked.connect(
        partial(select_image_for_custom_feedback, main_window))

    for label, value in dimmer_options.items():
        settings.ui.dim.addItem(f"{label}", userData=value)

    existing_timeout = api.get_display_timeout(deck_id)
    existing_index = next((i for i, (k, v) in enumerate(dimmer_options.items())
                           if v == existing_timeout), None)

    if existing_index is None:
        settings.ui.dim.addItem(f"Custom: {existing_timeout}s",
                                userData=existing_timeout)
        existing_index = settings.ui.dim.count() - 1
        settings.ui.dim.setCurrentIndex(existing_index)
    else:
        settings.ui.dim.setCurrentIndex(existing_index)

    settings.ui.label_streamdeck.setText(deck_id)
    settings.ui.brightness.setValue(api.get_brightness(deck_id))
    settings.ui.brightness.valueChanged.connect(
        partial(change_brightness, deck_id))
    if settings.exec_():
        # Commit changes
        if existing_index != settings.ui.dim.currentIndex():
            dimmers[deck_id].timeout = settings.ui.dim.currentData()
            api.set_display_timeout(deck_id, settings.ui.dim.currentData())
        set_brightness(window.ui, settings.ui.brightness.value())
    else:
        # User cancelled, reset to original brightness
        change_brightness(deck_id, api.get_brightness(deck_id))

    dimmers[deck_id].reset()
コード例 #2
0
def show_settings(window) -> None:
    """Shows the settings dialog and allows the user the change deck specific
    settings. Settings are not saved until OK is clicked."""
    ui = window.ui
    deck_id = _deck_id(ui)
    settings = SettingsDialog(window)
    dimmers[deck_id].stop()

    for label, value in dimmer_options.items():
        settings.ui.dim.addItem(f"{label}", userData=value)

    existing_timeout = api.get_display_timeout(deck_id)
    existing_index = next((i for i, (k, v) in enumerate(dimmer_options.items())
                           if v == existing_timeout), None)

    if existing_index is None:
        settings.ui.dim.addItem(f"Custom: {existing_timeout}s",
                                userData=existing_timeout)
        existing_index = settings.ui.dim.count() - 1
        settings.ui.dim.setCurrentIndex(existing_index)
    else:
        settings.ui.dim.setCurrentIndex(existing_index)

    existing_brightness_dimmed = api.get_brightness_dimmed(deck_id)
    settings.ui.brightness_dimmed.setValue(existing_brightness_dimmed)

    settings.ui.label_streamdeck.setText(deck_id)
    settings.ui.brightness.setValue(api.get_brightness(deck_id))
    settings.ui.brightness.valueChanged.connect(
        partial(change_brightness, deck_id))
    settings.ui.dim.currentIndexChanged.connect(
        partial(disable_dim_settings, settings))
    if settings.exec_():
        # Commit changes
        if existing_index != settings.ui.dim.currentIndex():
            dimmers[deck_id].timeout = settings.ui.dim.currentData()
            api.set_display_timeout(deck_id, settings.ui.dim.currentData())
        set_brightness(window.ui, settings.ui.brightness.value())
        set_brightness_dimmed(window.ui, settings.ui.brightness_dimmed.value(),
                              settings.ui.brightness.value())
    else:
        # User cancelled, reset to original brightness
        change_brightness(deck_id, api.get_brightness(deck_id))

    dimmers[deck_id].reset()
コード例 #3
0
def sync(ui) -> None:
    api.ensure_decks_connected()
    ui.brightness.setValue(api.get_brightness(_deck_id(ui)))
    ui.pages.setCurrentIndex(api.get_page(_deck_id(ui)))
コード例 #4
0
def start(_exit: bool = False) -> None:
    show_ui = True
    if "-h" in sys.argv or "--help" in sys.argv:
        print(f"Usage: {os.path.basename(sys.argv[0])}")
        print("Flags:")
        print("  -h, --help\tShow this message")
        print("  -n, --no-ui\tRun the program without showing a UI")
        return
    elif "-n" in sys.argv or "--no-ui" in sys.argv:
        show_ui = False

    app = QApplication(sys.argv)

    logo = QIcon(LOGO)
    main_window = MainWindow()
    ui = main_window.ui
    main_window.setWindowIcon(logo)
    tray = QSystemTrayIcon(logo, app)
    tray.activated.connect(main_window.systray_clicked)

    menu = QMenu()
    action_exit = QAction("Exit")
    action_exit.triggered.connect(app.exit)
    menu.addAction(action_exit)

    tray.setContextMenu(menu)

    ui.text.textChanged.connect(partial(queue_text_change, ui))
    ui.command.textChanged.connect(partial(update_button_command, ui))
    ui.keys.textChanged.connect(partial(update_button_keys, ui))
    ui.write.textChanged.connect(partial(update_button_write, ui))
    ui.change_brightness.valueChanged.connect(partial(update_change_brightness, ui))
    ui.switch_page.valueChanged.connect(partial(update_switch_page, ui))
    ui.imageButton.clicked.connect(partial(select_image, main_window))
    ui.removeButton.clicked.connect(partial(remove_image, main_window))
    ui.settingsButton.clicked.connect(partial(show_settings, main_window))

    api.streamdesk_keys.key_pressed.connect(handle_keypress)

    items = api.open_decks().items()
    if len(items) == 0:
        print("Waiting for Stream Deck(s)...")
        while len(items) == 0:
            time.sleep(3)
            items = api.open_decks().items()

    for deck_id, deck in items:
        ui.device_list.addItem(f"{deck['type']} - {deck_id}", userData=deck_id)
        dimmers[deck_id] = Dimmer(
            api.get_display_timeout(deck_id),
            api.get_brightness(deck_id),
            partial(change_brightness, deck_id),
        )
        dimmers[deck_id].reset()

    build_device(ui)
    ui.device_list.currentIndexChanged.connect(partial(build_device, ui))

    ui.pages.currentChanged.connect(partial(change_page, ui))

    ui.actionExport.triggered.connect(partial(export_config, main_window))
    ui.actionImport.triggered.connect(partial(import_config, main_window))
    ui.actionExit.triggered.connect(app.exit)

    timer = QTimer()
    timer.timeout.connect(partial(sync, ui))
    timer.start(1000)

    api.render()
    tray.show()

    if show_ui:
        main_window.show()

    if _exit:
        return
    else:
        app.exec_()
        api.close_decks()
        sys.exit()
コード例 #5
0
def handle_keypress(deck_id: str, key: int, state: bool) -> None:

    if state:

        if dimmers[deck_id].reset():
            return

        keyboard = Controller()
        page = api.get_page(deck_id)

        command = api.get_button_command(deck_id, page, key)
        if command:
            try:
                Popen(shlex.split(command))
            except Exception as error:
                print(f"The command '{command}' failed: {error}")

        keys = api.get_button_keys(deck_id, page, key)
        if keys:
            keys = keys.strip().replace(" ", "")
            for section in keys.split(","):
                # Since + and , are used to delimit our section and keys to press,
                # they need to be substituded with keywords.
                section_keys = [_replace_special_keys(key_name) for key_name in section.split("+")]

            # Translate string to enum, or just the string itself if not found
            section_keys = [getattr(Key, key_name.lower(), key_name) for key_name in section_keys]

            for key_name in section_keys:
                try:
                    if key_name == "delay":
                        time.sleep(0.5)
                    else:
                        keyboard.press(key_name)
                except Exception:
                    print(f"Could not press key '{key_name}'")

            for key_name in section_keys:
                try:
                    if key_name != "delay":
                        keyboard.release(key_name)
                except Exception:
                    print(f"Could not release key '{key_name}'")

        write = api.get_button_write(deck_id, page, key)
        if write:
            try:
                keyboard.type(write)
            except Exception as error:
                print(f"Could not complete the write command: {error}")

        brightness_change = api.get_button_change_brightness(deck_id, page, key)
        if brightness_change:
            try:
                api.change_brightness(deck_id, brightness_change)
                dimmers[deck_id].brightness = api.get_brightness(deck_id)
                dimmers[deck_id].reset()
            except Exception as error:
                print(f"Could not change brightness: {error}")

        switch_page = api.get_button_switch_page(deck_id, page, key)
        if switch_page:
            api.set_page(deck_id, switch_page - 1)
コード例 #6
0
def start(_exit: bool = False) -> None:
    show_ui = True
    if "-h" in sys.argv or "--help" in sys.argv:
        print(f"Usage: {os.path.basename(sys.argv[0])}")
        print("Flags:")
        print("  -h, --help\tShow this message")
        print("  -n, --no-ui\tRun the program without showing a UI")
        return
    elif "-n" in sys.argv or "--no-ui" in sys.argv:
        show_ui = False

    app = QApplication(sys.argv)

    logo = QIcon(LOGO)
    main_window = MainWindow()
    ui = main_window.ui
    main_window.setWindowIcon(logo)
    tray = QSystemTrayIcon(logo, app)
    tray.activated.connect(main_window.systray_clicked)

    menu = QMenu()
    action_dim = QAction("Dim display (toggle)")
    action_dim.triggered.connect(dim_all_displays)
    action_configure = QAction("Configure...")
    action_configure.triggered.connect(main_window.bring_to_top)
    menu.addAction(action_dim)
    menu.addAction(action_configure)
    menu.addSeparator()
    action_exit = QAction("Exit")
    action_exit.triggered.connect(app.exit)
    menu.addAction(action_exit)

    tray.setContextMenu(menu)

    ui.text.textChanged.connect(partial(queue_text_change, ui))
    ui.font_Size.valueChanged.connect(partial(update_font_size, ui))
    ui.command.textChanged.connect(partial(update_button_command, ui))
    ui.keys.textChanged.connect(partial(update_button_keys, ui))
    ui.write.textChanged.connect(partial(update_button_write, ui))
    ui.change_brightness.valueChanged.connect(
        partial(update_change_brightness, ui))
    ui.switch_page.valueChanged.connect(partial(update_switch_page, ui))
    ui.imageButton.clicked.connect(partial(select_image, main_window))
    ui.removeButton.clicked.connect(partial(remove_image, main_window))
    ui.settingsButton.clicked.connect(partial(show_settings, main_window))

    ui.font_Color.addItem("white")
    ui.font_Color.addItem("black")
    ui.font_Color.addItem("blue")
    ui.font_Color.addItem("red")
    ui.font_Color.addItem("green")
    ui.font_Color.addItem("purple")
    ui.font_Color.addItem("cyan")
    ui.font_Color.addItem("magenta")
    ui.font_Color.currentTextChanged.connect(partial(update_font_color, ui))

    ui.selected_font.addItem("Goblin_One")
    ui.selected_font.addItem("Open_Sans")
    ui.selected_font.addItem("Roboto")
    ui.selected_font.addItem("Lobster")
    ui.selected_font.addItem("Anton")
    ui.selected_font.addItem("Pacifico")
    ui.selected_font.currentTextChanged.connect(
        partial(update_selected_font, ui))

    ui.text_Align.addItem("left")
    ui.text_Align.addItem("center")
    ui.text_Align.addItem("right")
    ui.text_Align.currentTextChanged.connect(partial(update_text_align, ui))

    api.streamdesk_keys.key_pressed.connect(handle_keypress)

    items = api.open_decks().items()
    if len(items) == 0:
        print("Waiting for Stream Deck(s)...")
        while len(items) == 0:
            time.sleep(3)
            items = api.open_decks().items()

    for deck_id, deck in items:
        ui.device_list.addItem(f"{deck['type']} - {deck_id}", userData=deck_id)
        ui.target_device.addItem(deck_id)
        dimmers[deck_id] = Dimmer(
            api.get_display_timeout(deck_id),
            api.get_brightness(deck_id),
            partial(change_brightness, deck_id),
        )
        dimmers[deck_id].reset()

    build_device(ui)
    ui.device_list.currentIndexChanged.connect(partial(build_device, ui))

    ui.target_device.currentTextChanged.connect(
        partial(update_target_device, ui))

    ui.pages.currentChanged.connect(partial(change_page, ui))

    ui.actionExport.triggered.connect(partial(export_config, main_window))
    ui.actionImport.triggered.connect(partial(import_config, main_window))

    ui.actionCut.triggered.connect(partial(cut_button, main_window))
    ui.actionCopy.triggered.connect(partial(copy_button, main_window))

    ui.actionCut.setShortcuts([QKeySequence.Cut, QKeySequence("Shift+Del")])
    ui.actionCopy.setShortcuts(
        [QKeySequence.Copy, QKeySequence("Ctrl+Insert")])
    ui.actionPaste.setShortcuts(
        [QKeySequence.Paste, QKeySequence("Shift+Insert")])
    ui.actionDelete.setShortcuts([QKeySequence.Delete])

    ui.actionPaste.triggered.connect(partial(paste_button, main_window))
    ui.actionDelete.triggered.connect(partial(delete_button, main_window))
    ui.actionMultiPaste.triggered.connect(
        partial(multi_paste_Button, main_window))

    ui.actionExit.triggered.connect(app.exit)

    timer = QTimer()
    timer.timeout.connect(partial(sync, ui))
    timer.start(1000)

    api.render()
    tray.show()

    if show_ui:
        main_window.show()

    if _exit:
        return
    else:
        app.exec_()
        api.close_decks()
        sys.exit()
コード例 #7
0
def handle_keypress(deck_id: str, key: int, state: bool) -> None:
    if state:

        if dimmers[deck_id].reset():
            return

        keyboard = Controller()
        page = api.get_page(deck_id)

        command = api.get_button_command(deck_id, page, key)
        if command:
            try:
                Popen(shlex.split(command))
            except Exception as error:
                print(f"The command '{command}' failed: {error}")

        keys = api.get_button_keys(deck_id, page, key)
        if keys:
            keys = keys.strip().replace(" ", "")
            for section in keys.split(","):
                # Since + and , are used to delimit our section and keys to press,
                # they need to be substituted with keywords.
                section_keys = [
                    _replace_special_keys(key_name)
                    for key_name in section.split("+")
                ]

                # Translate string to enum, or just the string itself if not found
                section_keys = [
                    getattr(Key, key_name.lower(), key_name)
                    for key_name in section_keys
                ]

                for key_name in section_keys:
                    if isinstance(key_name,
                                  str) and key_name.startswith("delay"):
                        sleep_time_arg = key_name.split("delay", 1)[1]
                        if sleep_time_arg:
                            try:
                                sleep_time = float(sleep_time_arg)
                            except Exception:
                                print(
                                    f"Could not convert sleep time to float '{sleep_time_arg}'"
                                )
                                sleep_time = 0
                        else:
                            # default if not specified
                            sleep_time = 0.5

                        if sleep_time:
                            try:
                                time.sleep(sleep_time)
                            except Exception:
                                print(
                                    f"Could not sleep with provided sleep time '{sleep_time}'"
                                )
                    else:
                        try:
                            keyboard.press(key_name)
                        except Exception:
                            print(f"Could not press key '{key_name}'")

                for key_name in section_keys:
                    if not (isinstance(key_name, str)
                            and key_name.startswith("delay")):
                        try:
                            keyboard.release(key_name)
                        except Exception:
                            print(f"Could not release key '{key_name}'")

        write = api.get_button_write(deck_id, page, key)
        if write:
            try:
                keyboard.type(write)
            except Exception as error:
                print(f"Could not complete the write command: {error}")

        brightness_change = api.get_button_change_brightness(
            deck_id, page, key)
        if brightness_change:
            try:
                api.change_brightness(deck_id, brightness_change)
                dimmers[deck_id].brightness = api.get_brightness(deck_id)
                dimmers[deck_id].reset()
            except Exception as error:
                print(f"Could not change brightness: {error}")

        switch_page = api.get_button_switch_page(deck_id, page, key)
        target_device = api.get_target_device(deck_id, page, key)
        if switch_page:
            api.set_page(target_device, switch_page - 1)
コード例 #8
0
def create_app(
    get_md_action_value: Callable[[int], str],
    get_md_data_value: Callable[[int], str],
    key_up_callback: Optional[Callable[[str, int, bool], None]] = None,
    md_action_callback: Optional[Callable[[int, str], None]] = None,
    md_data_callback: Optional[Callable[[int, str], None]] = None,
) -> Tuple[QApplication, MainWindow]:
    """
    Sets up the QApplication to use on the main thread without calling app.exec_()
    """
    global _get_md_action_value, _get_md_data_value  # pylint: disable=global-statement,invalid-name
    _get_md_action_value = get_md_action_value
    _get_md_data_value = get_md_data_value
    app = QApplication([])

    logo = QIcon(LOGO)
    main_window = MainWindow()
    ui = main_window.ui
    main_window.setWindowIcon(logo)
    tray = QSystemTrayIcon(logo, app)
    tray.activated.connect(main_window.systray_clicked)

    menu = QMenu()
    action_dim = QAction('Dim display (toggle)')
    action_dim.triggered.connect(dim_all_displays)
    action_configure = QAction('Configure...')
    action_configure.triggered.connect(main_window.bring_to_top)
    menu.addAction(action_dim)
    menu.addAction(action_configure)
    menu.addSeparator()
    action_exit = QAction('Exit')
    action_exit.triggered.connect(app.exit)
    menu.addAction(action_exit)

    tray.setContextMenu(menu)

    ui.text.textChanged.connect(partial(queue_text_change, ui))
    ui.command.textChanged.connect(partial(update_button_command, ui))
    ui.keys.textChanged.connect(partial(update_button_keys, ui))
    ui.write.textChanged.connect(partial(update_button_write, ui))
    ui.change_brightness.valueChanged.connect(
        partial(update_change_brightness, ui))
    ui.switch_page.valueChanged.connect(partial(update_switch_page, ui))
    ui.imageButton.clicked.connect(partial(select_image, main_window))
    ui.removeButton.clicked.connect(partial(remove_image, main_window))
    ui.settingsButton.clicked.connect(partial(show_settings, main_window))

    md_label = QLabel(ui.groupBox)
    md_label.setObjectName('md_label')
    md_label.setText('MD Action:')
    ui.formLayout.setWidget(7, QFormLayout.LabelRole, md_label)

    md_action = QComboBox(ui.groupBox)
    md_action.setObjectName('md_action')
    md_action.addItems(_MATERIAL_DECK_ACTIONS)
    md_action.currentIndexChanged.connect(
        partial(_md_action_changed, md_action_callback))
    ui.formLayout.setWidget(7, QFormLayout.FieldRole, md_action)
    ui.md_action = md_action

    md_data_label = QLabel(ui.groupBox)
    md_data_label.setObjectName('md_data_label')
    md_data_label.setText('MD Data:')
    ui.formLayout.setWidget(8, QFormLayout.LabelRole, md_data_label)

    text_timer = QTimer()
    text_timer.setSingleShot(True)
    text_timer.timeout.connect(partial(_md_data_changed, ui, md_data_callback))

    md_data = QPlainTextEdit(ui.groupBox)
    md_data.setObjectName('md_data')
    md_data.textChanged.connect(lambda: text_timer.start(500))
    ui.formLayout.setWidget(8, QFormLayout.FieldRole, md_data)
    ui.md_data = md_data

    api.streamdesk_keys.key_pressed.connect(
        partial(_extended_handle_key_press, key_up_callback))

    items = api.open_decks().items()
    if len(items) == 0:
        print('Waiting for Stream Deck(s)...')
        while len(items) == 0:
            time.sleep(3)
            items = api.open_decks().items()

    for deck_id, deck in items:
        ui.device_list.addItem(f"{deck['type']} - {deck_id}", userData=deck_id)
        dimmers[deck_id] = Dimmer(
            api.get_display_timeout(deck_id),
            api.get_brightness(deck_id),
            partial(change_brightness, deck_id),
        )
        dimmers[deck_id].reset()

    build_device(ui)
    ui.device_list.currentIndexChanged.connect(partial(build_device, ui))

    ui.pages.currentChanged.connect(partial(change_page, ui))

    ui.actionExport.triggered.connect(partial(export_config, main_window))
    ui.actionImport.triggered.connect(partial(import_config, main_window))
    ui.actionExit.triggered.connect(app.exit)

    timer = QTimer()
    timer.timeout.connect(partial(sync, ui))
    timer.start(1000)

    api.render()
    tray.show()

    return (app, main_window)