예제 #1
0
def generate_GUI(menus):
    app_gui = TabbedPanel()
    app_gui.clear_tabs()
    app_gui.orientation = "vertical"
    app_gui.do_default_tab = False
    app_gui.tab_width = 150

    for menu_key, sub_menu in menus.items():
        main_menu = TabbedPanelHeader(text=menu_key)
        scroll_pane = ScrollView()
        scroll_pane.scroll_type = ['bars', 'content']
        scroll_pane.bar_pos_y = 'left'
        scroll_pane.bar_width = 6
        scroll_pane.do_scroll_y = True
        scroll_pane.do_scroll_x = False
        scroll_pane.scroll_y = 1

        menu_grid = GridLayout(cols=1, spacing=2, size_hint_y=None)
        menu_grid.orientation = "vertical"
        menu_grid.padding = 10
        menu_grid.row_default_height = 1
        menu_height = 0

        print(">>>" + menu_key)
        for sub_menu_key, items in sub_menu.items():
            menu_grid.add_widget(
                Label(text="     " + sub_menu_key, size_hint=(None, None), font_size=14, halign="left",
                      valign="middle"))
            print("\t" + sub_menu_key)
            for option in items:

                if "Name" in option:
                    print("\t\t" + option["Name"])
                    btn = Button(text=option["Name"], size_hint=(0.1, None), background_color=(0.2, 1, 1, 0.8))
                    btn.bind(on_press=lambda x: webbrowser.open(option["URL"]))
                else:
                    print("\t\t" + "<EMPTY>")
                    btn = Button(text="<EMPTY>", size_hint=(0.1, None), background_color=(0.2, 1, 1, 0.8))
                    btn.bind(on_press=lambda x: webbrowser.open(option["URL"]))
                btn.width = 250
                btn.height = 50
                menu_grid.add_widget(btn)
                menu_height += 80
            menu_height += 51
        menu_grid.height = menu_height
        scroll_pane.add_widget(menu_grid)
        main_menu.content = scroll_pane
        main_menu.orientation = "vertical"

        # Adding headers to main layout
        app_gui.add_widget(main_menu)
    return app_gui
예제 #2
0
class GameManager(App):
    logging_pairs = [
        ("Client", "Archipelago"),
    ]
    base_title: str = "Archipelago Client"
    last_autofillable_command: str

    def __init__(self, ctx: context_type):
        self.title = self.base_title
        self.ctx = ctx
        self.commandprocessor = ctx.command_processor(ctx)
        self.icon = r"data/icon.png"
        self.json_to_kivy_parser = KivyJSONtoTextParser(ctx)
        self.log_panels = {}

        # keep track of last used command to autofill on click
        self.last_autofillable_command = "hint"
        autofillable_commands = ("hint_location", "hint", "getitem")
        original_say = ctx.on_user_say

        def intercept_say(text):
            text = original_say(text)
            if text:
                for command in autofillable_commands:
                    if text.startswith("!" + command):
                        self.last_autofillable_command = command
                        break
            return text

        ctx.on_user_say = intercept_say

        super(GameManager, self).__init__()

    def build(self):
        self.container = ContainerLayout()

        self.grid = MainLayout()
        self.grid.cols = 1
        self.connect_layout = BoxLayout(orientation="horizontal",
                                        size_hint_y=None,
                                        height=30)
        # top part
        server_label = ServerLabel()
        self.connect_layout.add_widget(server_label)
        self.server_connect_bar = ConnectBarTextInput(text="archipelago.gg",
                                                      size_hint_y=None,
                                                      height=30,
                                                      multiline=False,
                                                      write_tab=False)
        self.server_connect_bar.bind(
            on_text_validate=self.connect_button_action)
        self.connect_layout.add_widget(self.server_connect_bar)
        self.server_connect_button = Button(text="Connect",
                                            size=(100, 30),
                                            size_hint_y=None,
                                            size_hint_x=None)
        self.server_connect_button.bind(on_press=self.connect_button_action)
        self.connect_layout.add_widget(self.server_connect_button)
        self.grid.add_widget(self.connect_layout)
        self.progressbar = ProgressBar(size_hint_y=None, height=3)
        self.grid.add_widget(self.progressbar)

        # middle part
        self.tabs = TabbedPanel(size_hint_y=1)
        self.tabs.default_tab_text = "All"
        self.log_panels["All"] = self.tabs.default_tab_content = UILog(
            *(logging.getLogger(logger_name)
              for logger_name, name in self.logging_pairs))

        for logger_name, display_name in self.logging_pairs:
            bridge_logger = logging.getLogger(logger_name)
            panel = TabbedPanelItem(text=display_name)
            self.log_panels[display_name] = panel.content = UILog(
                bridge_logger)
            self.tabs.add_widget(panel)

        self.grid.add_widget(self.tabs)

        if len(self.logging_pairs) == 1:
            # Hide Tab selection if only one tab
            self.tabs.clear_tabs()
            self.tabs.do_default_tab = False
            self.tabs.current_tab.height = 0
            self.tabs.tab_height = 0

        # bottom part
        bottom_layout = BoxLayout(orientation="horizontal",
                                  size_hint_y=None,
                                  height=30)
        info_button = Button(height=30, text="Command:", size_hint_x=None)
        info_button.bind(on_release=self.command_button_action)
        bottom_layout.add_widget(info_button)
        self.textinput = TextInput(size_hint_y=None,
                                   height=30,
                                   multiline=False,
                                   write_tab=False)
        self.textinput.bind(on_text_validate=self.on_message)

        def text_focus(event):
            """Needs to be set via delay, as unfocusing happens after on_message"""
            self.textinput.focus = True

        self.textinput.text_focus = text_focus
        bottom_layout.add_widget(self.textinput)
        self.grid.add_widget(bottom_layout)
        self.commandprocessor("/help")
        Clock.schedule_interval(self.update_texts, 1 / 30)
        self.container.add_widget(self.grid)
        return self.container

    def update_texts(self, dt):
        if hasattr(self.tabs.content.children[0], 'fix_heights'):
            self.tabs.content.children[0].fix_heights(
            )  # TODO: remove this when Kivy fixes this upstream
        if self.ctx.server:
            self.title = self.base_title + " " + Utils.__version__ + \
                         f" | Connected to: {self.ctx.server_address} " \
                         f"{'.'.join(str(e) for e in self.ctx.server_version)}"
            self.server_connect_button.text = "Disconnect"
            self.progressbar.max = len(self.ctx.checked_locations) + len(
                self.ctx.missing_locations)
            self.progressbar.value = len(self.ctx.checked_locations)
        else:
            self.server_connect_button.text = "Connect"
            self.title = self.base_title + " " + Utils.__version__
            self.progressbar.value = 0

    def command_button_action(self, button):
        if self.ctx.server:
            logging.getLogger("Client").info(
                "/help for client commands and !help for server commands.")
        else:
            logging.getLogger("Client").info(
                "/help for client commands and once you are connected, "
                "!help for server commands.")

    def connect_button_action(self, button):
        if self.ctx.server:
            self.ctx.server_address = None
            asyncio.create_task(self.ctx.disconnect())
        else:
            asyncio.create_task(
                self.ctx.connect(
                    self.server_connect_bar.text.replace("/connect ", "")))

    def on_stop(self):
        # "kill" input tasks
        for x in range(self.ctx.input_requests):
            self.ctx.input_queue.put_nowait("")
        self.ctx.input_requests = 0

        self.ctx.exit_event.set()

    def on_message(self, textinput: TextInput):
        try:
            input_text = textinput.text.strip()
            textinput.text = ""

            if self.ctx.input_requests > 0:
                self.ctx.input_requests -= 1
                self.ctx.input_queue.put_nowait(input_text)
            elif input_text:
                self.commandprocessor(input_text)

            Clock.schedule_once(textinput.text_focus)

        except Exception as e:
            logging.getLogger("Client").exception(e)

    def print_json(self, data: typing.List[JSONMessagePart]):
        text = self.json_to_kivy_parser(data)
        self.log_panels["Archipelago"].on_message_markup(text)
        self.log_panels["All"].on_message_markup(text)

    def enable_energy_link(self):
        if not hasattr(self, "energy_link_label"):
            self.energy_link_label = Label(text="Energy Link: Standby",
                                           size_hint_x=None,
                                           width=150)
            self.connect_layout.add_widget(self.energy_link_label)

    def set_new_energy_link_value(self):
        if hasattr(self, "energy_link_label"):
            self.energy_link_label.text = f"EL: {Utils.format_SI_prefix(self.ctx.current_energy_link_value)}J"