Esempio n. 1
0
class Query:
    def __init__(self, scale, font, color, text_size, suggestions_text_size,
                 query_delay):
        self.scale = scale
        self.font = font
        self.color = color
        self.text_size = text_size
        self.suggestions_text_size = suggestions_text_size
        self.query_delay = query_delay
        self.background = None
        self.prefix = None
        self.query = None
        self.suggestions = None
        self.owner = None
        self.current_selection = None
        self.current_list = []
        self.completion_task = None
        self.max_columns = 4
        self.max_lines = 3
        self.max_elems = self.max_columns * self.max_lines

    def do_query(self, text):
        body = None
        if self.current_selection is not None:
            if self.current_selection < len(self.current_list):
                body = self.current_list[self.current_selection][1]
        else:
            text = self.query.get()
            body = self.owner.get_object(text)
        self.owner.select_object(body)
        self.close()

    def close(self):
        self.background.destroy()
        self.background = None
        self.prefix.destroy()
        self.prefix = None
        self.query.destroy()
        self.query = None
        self.suggestions.destroy()
        self.suggestions = None
        self.current_selection = None
        self.current_list = []
        if self.completion_task is not None:
            taskMgr.remove(self.completion_task)
            self.completion_task = None

    def escape(self, event):
        self.close()

    def update_suggestions(self):
        if self.current_selection is not None:
            page = self.current_selection // self.max_elems
        else:
            page = 0
        start = page * self.max_elems
        end = min(start + self.max_elems - 1, len(self.current_list) - 1)
        suggestions = ""
        for i in range(start, end + 1):
            if i != start and ((i - start) % self.max_columns) == 0:
                suggestions += '\n'
            if i == self.current_selection:
                suggestions += "\1md_bold\1%s\2" % self.current_list[i][0]
            else:
                suggestions += self.current_list[i][0]
            suggestions += '\t'
        self.suggestions.setText(suggestions)

    def completion(self, event):
        text = self.query.get()
        if text != '':
            self.current_list = self.owner.list_objects(text)
        else:
            self.current_list = []
        self.current_selection = None
        if self.completion_task is not None:
            taskMgr.remove(self.completion_task)
        self.completion_task = taskMgr.doMethodLater(self.query_delay,
                                                     self.update_suggestions,
                                                     'completion task',
                                                     extraArgs=[])

    def select(self, event):
        modifiers = event.getModifierButtons()
        if modifiers.isDown(KeyboardButton.shift()):
            incr = -1
        else:
            incr = 1
        if self.current_selection is not None:
            new_selection = self.current_selection + incr
        else:
            new_selection = 0
        if new_selection < 0:
            new_selection = len(self.current_list) - 1
        if new_selection >= len(self.current_list):
            new_selection = 0
        self.current_selection = new_selection
        self.update_suggestions()

    def open_query(self, owner):
        self.owner = owner
        bg_color = LColor(*self.color)
        bg_color[3] = 0.2
        scale3 = LVector3(self.scale[0], 1.0, self.scale[1])
        self.background = DirectFrame(
            frameColor=bg_color,
            frameSize=(-1 / self.scale[0], 1.0 / self.scale[0],
                       0.15 + self.scale[1] * self.text_size, 0.0),
            parent=base.a2dBottomLeft)
        self.prefix = OnscreenText(
            text=_("Target name:"),
            font=self.font,
            fg=self.color,
            align=TextNode.ALeft,
            parent=base.a2dBottomLeft,
            scale=tuple(self.scale * self.text_size),
            pos=(0, .15),
        )
        bounds = self.prefix.getTightBounds()
        length = bounds[1][0] - bounds[0][
            0] + self.scale[0] * self.text_size / 2
        self.query = DirectEntry(text="",
                                 text_fg=self.color,
                                 scale=tuple(scale3 * self.text_size),
                                 command=self.do_query,
                                 parent=base.a2dBottomLeft,
                                 frameColor=(0, 0, 0, 0),
                                 pos=(length, 0, .15),
                                 initialText="",
                                 numLines=1,
                                 width=200,
                                 entryFont=self.font,
                                 focus=1,
                                 suppressKeys=1)
        self.query.bind("press-escape-", self.escape)
        self.query.bind("press-tab-", self.select)
        self.query.accept(self.query.guiItem.getTypeEvent(), self.completion)
        self.query.accept(self.query.guiItem.getEraseEvent(), self.completion)
        pos = self.prefix.getPos()
        bounds = self.query.getBounds()
        llz = bounds[2] / self.text_size
        self.suggestions = OnscreenText(
            text="",
            font=self.font,
            fg=self.color,
            align=TextNode.ALeft,
            mayChange=True,
            parent=base.a2dBottomLeft,
            scale=tuple(self.scale * self.suggestions_text_size),
            pos=(pos[0], pos[1] + llz),
        )