Esempio n. 1
0
    def __init__(self):
        HUDElement.__init__(self)
        self.dir = ani.model_dir / 'hud' / 'english'
        self.text_scale = 0.2
        self.text_color = (1, 1, 1, 1)

        self.circle = OnscreenImage(image=panda_path(self.dir / 'circle.png'),
                                    parent=self.dummy_right,
                                    scale=0.15)
        self.circle.setTransparency(TransparencyAttrib.MAlpha)
        autils.alignTo(self.circle, self.dummy_right, autils.CL, autils.C)
        self.circle.setZ(-0.65)

        self.crosshairs = OnscreenImage(image=panda_path(self.dir /
                                                         'crosshairs.png'),
                                        pos=(0, 0, 0),
                                        parent=self.circle,
                                        scale=0.14)
        self.crosshairs.setTransparency(TransparencyAttrib.MAlpha)

        self.text = OnscreenText(
            text="(0.00, 0.00)",
            pos=(0, -1.15),
            scale=self.text_scale,
            fg=self.text_color,
            align=TextNode.ACenter,
            mayChange=True,
            parent=self.circle,
        )
Esempio n. 2
0
    def add_subtitle(self, item):
        """Add a subtitle"""

        title = DirectLabel(
            text=item.text,
            scale=SUBHEADING_SCALE,
            parent=self.area.getCanvas(),
            relief=None,
            text_fg=TEXT_COLOR,
            text_align=TextNode.ALeft,
            text_font=self.title_font,
        )

        if self.last_element:
            autils.alignTo(title,
                           self.last_element,
                           autils.CT,
                           autils.CB,
                           gap=(1, 1))
        else:
            title.setPos((-0.77, 0, 0.8))
        title.setX(-0.77)

        # Underscore
        title_x, title_y, title_z = title.getPos()
        lines = LineSegs()
        lines.setColor(TEXT_COLOR)
        lines.moveTo(title_x, 0, title_z - HEADING_SCALE * 0.2)
        lines.drawTo(0.8, 0, title_z - HEADING_SCALE * 0.2)
        lines.setThickness(1)
        node = lines.create()
        underscore = NodePath(node)
        underscore.reparentTo(self.area.getCanvas())

        # Invisible line for white space
        lines = LineSegs()
        lines.setColor((0, 0, 0, 0))
        lines.moveTo(title_x, 0, title_z - HEADING_SCALE * 0.5)
        lines.drawTo(0.8, 0, title_z - HEADING_SCALE * 0.5)
        lines.setThickness(1)
        node = lines.create()
        whitespace = NodePath(node)
        whitespace.reparentTo(self.area.getCanvas())

        # Create a parent for all the nodes
        title_obj = self.area.getCanvas().attachNewNode(f"title_{self.name}")
        title.reparentTo(title_obj)
        underscore.reparentTo(title_obj)
        whitespace.reparentTo(title_obj)

        self.last_element = title_obj

        self.elements.append({
            'type': 'subtitle',
            'name': item.text,
            'content': title_obj,
        })

        return title_obj
Esempio n. 3
0
    def add_text(self, item):
        """Add text"""

        text = item.text.strip()
        max_len = 55
        new_text = []
        line, columns = [], 0
        for word in text.split():
            if columns + len(word) > max_len:
                new_text.append(' '.join(line))
                line, columns = [], 0
            columns += len(word)
            line.append(word)
        new_text.append(' '.join(line))
        text = '\n'.join(new_text)

        text_obj = DirectLabel(
            text=text,
            scale=TEXT_SCALE,
            parent=self.area.getCanvas(),
            relief=None,
            text_fg=TEXT_COLOR,
            text_align=TextNode.ALeft,
            text_font=None,
        )

        if self.last_element:
            autils.alignTo(text_obj,
                           self.last_element,
                           autils.CT,
                           autils.CB,
                           gap=(1, 1))
        else:
            text_obj.setPos((-0.7, 0, 0.8))
        text_obj.setX(-0.7)

        self.last_element = text_obj

        self.elements.append({
            'type': 'text',
            'text': text,
            'content': text_obj,
        })

        return text_obj
Esempio n. 4
0
    def __init__(self):
        HUDElement.__init__(self)
        self.dir = ani.model_dir / 'hud' / 'jack'
        self.text_scale = 0.4
        self.text_color = (1, 1, 1, 1)

        self.arc = OnscreenImage(image=panda_path(self.dir / 'arc.png'),
                                 pos=(1.4, 0, -0.45),
                                 parent=aspect2d,
                                 scale=0.075)
        self.arc.setTransparency(TransparencyAttrib.MAlpha)

        self.cue_cartoon = OnscreenImage(
            image=panda_path(self.dir / 'cue.png'),
            parent=aspect2d,
            pos=(0, 0, 0),
            scale=(0.15, 1, 0.01),
        )
        self.cue_cartoon.setTransparency(TransparencyAttrib.MAlpha)
        autils.alignTo(self.cue_cartoon, self.dummy_right, autils.CL, autils.C)
        self.cue_cartoon.setZ(-0.40)

        autils.alignTo(self.arc, self.cue_cartoon, autils.LR, autils.CR)

        self.rotational_point = OnscreenImage(image=panda_path(
            ani.model_dir / 'hud' / 'english' / 'circle.png'),
                                              parent=self.arc,
                                              scale=0.15)
        self.rotational_point.setTransparency(TransparencyAttrib.MAlpha)
        autils.alignTo(self.rotational_point, self.arc, autils.C, autils.LR)

        self.cue_cartoon.wrtReparentTo(self.rotational_point)

        self.text = OnscreenText(
            text="0 deg",
            pos=(-1, -1.4),
            scale=self.text_scale,
            fg=self.text_color,
            align=TextNode.ACenter,
            mayChange=True,
            parent=self.arc,
        )
Esempio n. 5
0
    def add_button(self, item):
        """Add a button"""

        name = self.search_child_tag(item, 'name').text
        func_name = self.search_child_tag(item, 'func').text
        desc = self.search_child_tag(item, 'description').text

        # This is the button you click. NOTE `command` is assigned ad hoc. See
        # Menus.populate_menus
        button = DirectButton(
            text=name,
            text_align=TextNode.ALeft,
            text_font=self.button_font,
            scale=BUTTON_TEXT_SCALE,
            geom=loadImageAsPlane(panda_path(MENU_ASSETS / 'button.png')),
            relief=None,
        )

        # Bind mouse hover to highlighting option
        button.bind(DGG.ENTER, self.highlight_button, extraArgs=[button])
        button.bind(DGG.EXIT, self.unhighlight_button)

        button_np = NodePath(button)
        # functional_button-<menu_name>-<button_text>
        button_id = f"functional_button-{self.name}-{name.replace(' ','_')}"
        button_np.setName(button_id)
        button_np.reparentTo(self.area.getCanvas())

        if self.last_element:
            autils.alignTo(button_np, self.last_element, autils.CT, autils.CB)
        else:
            button_np.setPos(-0.63, 0, 0.8)
        button_np.setX(-0.63)
        button_np.setZ(button_np.getZ() - MOVE)

        # This is the info button you hover over
        info_button = DirectButton(
            text='',
            text_align=TextNode.ALeft,
            scale=INFO_SCALE,
            image=panda_path(MENU_ASSETS / 'info_button.png'),
            relief=None,
        )

        # Bind mouse hover to displaying button info
        info_button.bind(DGG.ENTER, self.display_button_info, extraArgs=[desc])
        info_button.bind(DGG.EXIT, self.destroy_button_info)

        info_button = NodePath(info_button)
        info_button.reparentTo(self.area.getCanvas())

        # Align the info button next to the button it refers to
        autils.alignTo(info_button, button_np, autils.CR, autils.CL)
        # Then shift it over just a bit to give some space
        info_button.setX(info_button.getX() - 0.02)

        # Create a parent for all the nodes
        button_id = 'button_' + item.text.replace(' ', '_')
        button_obj = self.area.getCanvas().attachNewNode(button_id)
        button_np.reparentTo(button_obj)
        info_button.reparentTo(button_obj)

        self.last_element = button_np

        self.elements.append({
            'type': 'button',
            'name': name,
            'content': button_obj,
            'object': button,
            'convert_factor': None,
            'func_name': func_name,
        })

        return button_obj
Esempio n. 6
0
    def add_entry(self, item):
        name = self.search_child_tag(item, 'name').text
        desc = self.search_child_tag(item, 'description').text

        validator = item.attrib.get('validator')
        if validator is None:
            validator = lambda value: True
        else:
            try:
                validator = getattr(self, validator)
            except AttributeError:
                raise AttributeError(
                    f"Unknown validator string '{validator}' for element with name '{name}'"
                )

        try:
            initial = item.attrib['initial']
        except KeyError:
            initial = ''

        try:
            width = int(item.attrib['width'])
        except KeyError:
            width = 4

        title = DirectLabel(
            text=name + ":",
            scale=AUX_TEXT_SCALE,
            parent=self.area.getCanvas(),
            relief=None,
            text_fg=TEXT_COLOR,
            text_align=TextNode.ALeft,
            text_font=self.title_font,
        )
        title.reparentTo(self.area.getCanvas())
        title_np = NodePath(title)
        title_np.reparentTo(self.area.getCanvas())

        entry = DirectEntry(
            text="",
            scale=BUTTON_TEXT_SCALE * 0.7,
            initialText=initial,
            relief=DGG.RIDGE,
            numLines=1,
            width=width,
            focus=0,
            focusInCommand=self.entry_buildup,
            focusInExtraArgs=[True, name],
            focusOutCommand=self.entry_teardown,
            focusOutExtraArgs=[name, initial],
            suppressKeys=True,
        )
        entry['frameColor'] = (1, 1, 1, 0.3)

        # If the mouse hovers over a direct entry, update self.hovered_entry
        entry.bind(DGG.ENTER, self.update_hovered_entry, extraArgs=[name])
        entry.bind(DGG.EXIT, self.update_hovered_entry, extraArgs=[None])

        entry_np = NodePath(entry)
        # functional_entry-<menu_name>-<entry_text>
        entry_id = f"functional_entry-{self.name}-{name.replace(' ','_')}"
        entry_np.setName(entry_id)
        entry_np.reparentTo(self.area.getCanvas())

        if self.last_element:
            autils.alignTo(title_np, self.last_element, autils.CT, autils.CB)
        else:
            title_np.setPos(-0.63, 0, 0.8)
        title_np.setX(-0.63)
        title_np.setZ(title_np.getZ() - MOVE)

        # Align the entry next to the title that refers to it
        autils.alignTo(entry_np, title_np, autils.CL, autils.CR)
        # Then shift it over just a bit to give some space
        entry_np.setX(entry_np.getX() + 0.02)
        # Then shift it down a little to align the text
        entry_np.setZ(entry_np.getZ() - 0.005)

        # This is the info button you hover over
        info_button = DirectButton(
            text='',
            text_align=TextNode.ALeft,
            scale=INFO_SCALE,
            image=panda_path(MENU_ASSETS / 'info_button.png'),
            relief=None,
        )

        # Bind mouse hover to displaying button info
        info_button.bind(DGG.ENTER, self.display_button_info, extraArgs=[desc])
        info_button.bind(DGG.EXIT, self.destroy_button_info)

        info_button = NodePath(info_button)
        info_button.reparentTo(self.area.getCanvas())

        # Align the info button next to the button it refers to
        autils.alignTo(info_button, title_np, autils.CR, autils.CL)
        # Then shift it over just a bit to give some space
        info_button.setX(info_button.getX() - 0.02)

        # This text is shown if an error is detected in the user input
        error = DirectLabel(
            text="",
            textMayChange=1,
            text_fg=ERROR_COLOR,
            text_bg=(0, 0, 0, 0.3),
            scale=ERROR_TEXT_SCALE,
            parent=self.area.getCanvas(),
            relief=None,
            text_align=TextNode.ALeft,
        )
        error.reparentTo(self.area.getCanvas())
        error_np = NodePath(error)
        error_np.reparentTo(self.area.getCanvas())
        error_np.hide()

        # Align the error msg next to the entry it refers to
        autils.alignTo(error, entry_np, autils.CL, autils.CR)
        # Then shift it over just a bit to give some space
        error_np.setX(error_np.getX() + 0.02)
        # And shift it down a little too
        error_np.setZ(error_np.getZ() - 0.01)

        # Create a parent for all the nodes
        entry_id = 'entry_' + item.text.replace(' ', '_')
        entry_obj = self.area.getCanvas().attachNewNode(entry_id)
        title_np.reparentTo(entry_obj)
        entry_np.reparentTo(entry_obj)
        info_button.reparentTo(entry_obj)
        error_np.reparentTo(entry_obj)

        self.last_element = entry_np

        self.elements.append({
            'type': 'entry',
            'initial': initial,
            'name': name,
            'content': entry_obj,
            'object': entry,
            'error_msg': error,
            'validator': validator,
            'convert_factor': None,
        })
Esempio n. 7
0
    def add_checkbox(self, item):
        name = self.search_child_tag(item, 'name').text
        desc = self.search_child_tag(item, 'description').text

        title = DirectLabel(
            text=name + ":",
            scale=AUX_TEXT_SCALE,
            parent=self.area.getCanvas(),
            relief=None,
            text_fg=TEXT_COLOR,
            text_align=TextNode.ALeft,
            text_font=self.title_font,
        )
        title.reparentTo(self.area.getCanvas())
        title_np = NodePath(title)
        title_np.reparentTo(self.area.getCanvas())

        checkbox = DirectCheckButton(
            scale=BUTTON_TEXT_SCALE * 0.5,
            boxImage=(
                panda_path(MENU_ASSETS / 'unchecked.png'),
                panda_path(MENU_ASSETS / 'checked.png'),
                None,
            ),
            text="",
            relief=None,
            boxRelief=None,
        )

        checkbox_np = NodePath(checkbox)
        # functional_checkbox-<menu_name>-<checkbox_text>
        checkbox_id = f"functional_checkbox-{self.name}-{name.replace(' ','_')}"
        checkbox_np.setName(checkbox_id)
        checkbox_np.reparentTo(self.area.getCanvas())

        if self.last_element:
            autils.alignTo(title_np, self.last_element, autils.CT, autils.CB)
        else:
            title_np.setPos(-0.63, 0, 0.8)
        title_np.setX(-0.63)
        title_np.setZ(title_np.getZ() - MOVE)

        # Align the checkbox next to the title that refers to it
        autils.alignTo(checkbox_np, title_np, autils.CL, autils.CR)
        # Then shift it over just a bit to give some space
        checkbox_np.setX(checkbox_np.getX() + 0.02)
        # Then shift it down a little to align the text
        checkbox_np.setZ(checkbox_np.getZ() - 0.005)

        # This is the info button you hover over
        info_button = DirectButton(
            text='',
            text_align=TextNode.ALeft,
            scale=INFO_SCALE,
            image=panda_path(MENU_ASSETS / 'info_button.png'),
            relief=None,
        )

        # Bind mouse hover to displaying button info
        info_button.bind(DGG.ENTER, self.display_button_info, extraArgs=[desc])
        info_button.bind(DGG.EXIT, self.destroy_button_info)

        info_button = NodePath(info_button)
        info_button.reparentTo(self.area.getCanvas())

        # Align the info button next to the button it refers to
        autils.alignTo(info_button, title_np, autils.CR, autils.CL)
        # Then shift it over just a bit to give some space
        info_button.setX(info_button.getX() - 0.02)

        # Create a parent for all the nodes
        checkbox_id = 'checkbox_' + item.text.replace(' ', '_')
        checkbox_obj = self.area.getCanvas().attachNewNode(checkbox_id)
        title_np.reparentTo(checkbox_obj)
        checkbox_np.reparentTo(checkbox_obj)
        info_button.reparentTo(checkbox_obj)

        self.last_element = checkbox_np

        self.elements.append({
            'type': 'checkbox',
            'name': name,
            'content': checkbox_obj,
            'object': checkbox,
            'convert_factor': None,
        })
Esempio n. 8
0
    def add_dropdown(self, item):
        name = self.search_child_tag(item, 'name').text
        desc = self.search_child_tag(item, 'description').text

        if item.attrib.get('from_yaml'):
            # Populate the options from a YAML
            path = Path(
                pooltool.__file__).parent / item.attrib.get('from_yaml')
            config_obj = configparser.ConfigParser()
            config_obj.read(path)
            options = [option for option in config_obj.sections()]
        else:
            # Read the options directly from the XML
            options = [
                subitem.text for subitem in item if subitem.tag == 'option'
            ]

        try:
            func_name = self.search_child_tag(item, 'func').text
        except ValueError:
            func_name = None

        title = DirectLabel(
            text=name + ":",
            scale=AUX_TEXT_SCALE,
            parent=self.area.getCanvas(),
            relief=None,
            text_fg=TEXT_COLOR,
            text_align=TextNode.ALeft,
            text_font=self.title_font,
        )
        title.reparentTo(self.area.getCanvas())
        title_np = NodePath(title)
        title_np.reparentTo(self.area.getCanvas())

        dropdown = DirectOptionMenu(
            scale=BUTTON_TEXT_SCALE * 0.8,
            items=options,
            highlightColor=(0.65, 0.65, 0.65, 1),
            textMayChange=1,
            text_align=TextNode.ALeft,
            #text_font = self.button_font,
            relief=DGG.RIDGE,
            popupMarker_scale=0.6,
            popupMarker_image=loadImageAsPlane(
                panda_path(MENU_ASSETS / 'dropdown_marker.png')),
            popupMarker_relief=None,
            item_pad=(0.2, 0.2),
        )
        dropdown['frameColor'] = (1, 1, 1, 0.3)
        dropdown.reparentTo(self.area.getCanvas())

        dropdown_np = NodePath(dropdown)
        # functional_dropdown-<menu_name>-<dropdown_text>
        dropdown_id = f"functional_dropdown-{self.name}-{name.replace(' ','_')}"
        dropdown_np.setName(dropdown_id)
        dropdown_np.reparentTo(self.area.getCanvas())

        if self.last_element:
            autils.alignTo(title_np, self.last_element, autils.CT, autils.CB)
        else:
            title_np.setPos(-0.63, 0, 0.8)
        title_np.setX(-0.63)
        title_np.setZ(title_np.getZ() - MOVE)

        # Align the dropdown next to the title that refers to it
        autils.alignTo(dropdown_np, title_np, autils.CL, autils.CR)
        # Then shift it over just a bit to give some space
        dropdown_np.setX(dropdown_np.getX() + 0.02)
        # Then shift it down a little to align the text
        dropdown_np.setZ(dropdown_np.getZ() - 0.005)

        # This is the info button you hover over
        info_button = DirectButton(
            text='',
            text_align=TextNode.ALeft,
            scale=INFO_SCALE,
            image=panda_path(MENU_ASSETS / 'info_button.png'),
            relief=None,
        )

        # Bind mouse hover to displaying button info
        info_button.bind(DGG.ENTER, self.display_button_info, extraArgs=[desc])
        info_button.bind(DGG.EXIT, self.destroy_button_info)

        info_button = NodePath(info_button)
        info_button.reparentTo(self.area.getCanvas())

        # Align the info button next to the button it refers to
        autils.alignTo(info_button, title_np, autils.CR, autils.CL)
        # Then shift it over just a bit to give some space
        info_button.setX(info_button.getX() - 0.02)

        # Create a parent for all the nodes
        dropdown_id = 'dropdown_' + item.text.replace(' ', '_')
        dropdown_obj = self.area.getCanvas().attachNewNode(dropdown_id)
        title_np.reparentTo(dropdown_obj)
        dropdown_np.reparentTo(dropdown_obj)
        info_button.reparentTo(dropdown_obj)

        self.last_element = dropdown_np

        self.elements.append({
            'type': 'dropdown',
            'name': name,
            'content': dropdown_obj,
            'object': dropdown,
            'convert_factor': None,
            'func_name': func_name,
        })