Esempio n. 1
0
 def sign_cb(parent):
     thanks = open(eng.curr_path + 'assets/thanks.txt').readlines()
     shuffle(thanks)
     text = '\n\n'.join(thanks[:3])
     txt = OnscreenText(text,
                        parent=parent,
                        scale=.2,
                        fg=(0, 0, 0, 1),
                        pos=(.245, 0))
     bounds = lambda: txt.getTightBounds()
     while bounds()[1][0] - bounds()[0][0] > .48:
         scale = txt.getScale()[0]
         txt.setScale(scale - .01, scale - .01)
     bounds = txt.getTightBounds()
     height = bounds[1][2] - bounds[0][2]
     txt.setZ(.06 + height / 2)
Esempio n. 2
0
class ScrollText():
    def __init__(self,
                 text='',
                 align=TextNode.ALeft,
                 scale=(1, 1),
                 font=None,
                 font_size=12,
                 parent=None,
                 frameColor=(0.33, 0.33, 0.33, .66),
                 frameSize=(0, 0.5, -1.0, 0)):
        if parent is None:
            parent = aspect2d
        self.parent = parent
        self.frame = DirectScrolledFrame(
            parent=parent,
            frameColor=frameColor,
            state=DGG.DISABLED,
            frameSize=frameSize,
            relief=DGG.FLAT,
            scrollBarWidth=scale[0] * font_size,
            horizontalScroll_relief=DGG.FLAT,
            verticalScroll_relief=DGG.FLAT,
        )
        self.text = OnscreenText(parent=self.frame.getCanvas(),
                                 text=text,
                                 align=align,
                                 scale=tuple(scale * font_size),
                                 font=font)
        bounds = self.text.getTightBounds()
        self.frame['canvasSize'] = [
            0, bounds[1][0] - bounds[0][0], -bounds[1][2] + bounds[0][2], 0
        ]
        self.text.setPos(-bounds[0][0], -bounds[1][2])
        self.frame.setPos(0, 0, 0)

    def destroy(self):
        self.frame.destroy()

    def reparent_to(self, parent):
        self.frame.reparent_to(parent)
Esempio n. 3
0
class HostMenu(DirectObject):
    def __init__(self):
        self.defaultBtnMap = base.loader.loadModel("gui/button_map")
        self.buttonGeom = (
            self.defaultBtnMap.find("**/button_ready"),
            self.defaultBtnMap.find("**/button_click"),
            self.defaultBtnMap.find("**/button_rollover"),
            self.defaultBtnMap.find("**/button_disabled"))

        defaultFont = loader.loadFont('gui/eufm10.ttf')

        self.logFrame = DirectScrolledFrame(
            canvasSize = (0, base.a2dRight * 2, -5, 0),
            frameSize = (0, base.a2dRight * 2,
                (base.a2dBottom+.2) * 2, 0),
            frameColor = (0.1, 0.1, 0.1, 1))
        self.logFrame.reparentTo(base.a2dTopLeft)

        # create the info and server debug output
        self.textscale = 0.1
        self.txtinfo = OnscreenText(
            scale = self.textscale,
            pos = (0.1, -0.1),
            text = "",
            align = TextNode.ALeft,
            fg = (0.1,1.0,0.15,1),
            bg = (0, 0, 0, 0),
            shadow = (0, 0, 0, 1),
            shadowOffset = (-0.02, -0.02))
        self.txtinfo.setTransparency(1)
        self.txtinfo.reparentTo(self.logFrame.getCanvas())

        # create a close Server button
        self.btnBackPos = Vec3(0.4, 0, 0.2)
        self.btnBackScale = 0.25
        self.btnBack = DirectButton(
            # Scale and position
            scale = self.btnBackScale,
            pos = self.btnBackPos,
            # Text
            text = "Quit Server",
            text_scale = 0.45,
            text_pos = (0, -0.1),
            text_fg = (0.82,0.85,0.87,1),
            text_shadow = (0, 0, 0, 1),
            text_shadowOffset = (-0.02, -0.02),
            text_font = defaultFont,
            # Frame
            geom = self.buttonGeom,
            frameColor = (0, 0, 0, 0),
            relief = 0,
            pressEffect = False,
            # Functionality
            command = self.back,
            rolloverSound = None,
            clickSound = None)
        self.btnBack.setTransparency(1)
        self.btnBack.reparentTo(base.a2dBottomLeft)

        # catch window resizes and recalculate the aspectration
        self.accept("window-event", self.recalcAspectRatio)
        self.accept("addLog", self.addLog)

    def show(self):
        self.logFrame.show()
        self.btnBack.show()

    def hide(self):
        self.logFrame.hide()
        self.btnBack.hide()

    def back(self):
        self.hide()
        base.messenger.send("stop_server")
        self.addLog("Quit Server!")

    def addLog(self, text):
        self.txtinfo.appendText(text + "\n")
        textbounds = self.txtinfo.getTightBounds()
        self.logFrame["canvasSize"] = (0, textbounds[1].getX(),
                                        textbounds[0].getZ(), 0)

    def recalcAspectRatio(self, window):
        """get the new aspect ratio to resize the mainframe"""
        # set the mainframe size to the window borders again
        self.logFrame["frameSize"] = (
            0, base.a2dRight * 2,
            (base.a2dBottom+.2) * 2, 0)
Esempio n. 4
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),
        )
    def setupGUI(self):
        """ Builds the GUI based on the JSON description """
        # stores the GUI labels
        self.guiLabels = []
        # stores ALL the widgets in order of focus (even if they cannot get focus)
        self.focusOrder = []
        # DirectFrame that will contain the GUI
        self.myFrame = None

        # frame to hold the form (left, right, bottom, top)
        # Find out window dimensions
        ratio = self.config.world.camera.ratio
        frameSize = (-ratio, ratio, -1.0, 1.0)
        # centered
        pos = (0, 1.0, 0)
        # background colour
        try:
            colour = self.config.color_background
        except:
            colour = self.colours['dark_grey']

        # guiLabels colour
        labelColour = getattr(self.config.settings, 'color_label',
                              (1.0, 1.0, 1.0, 1.0))
        # global scale of the frame
        scale = self.config.settings.scale
        # canvas with scrolling capabilities
        self.myFrame = DirectScrolledFrame(
            canvasSize=(frameSize[0], frameSize[1], 50 * frameSize[2],
                        frameSize[3]),
            frameColor=colour,
            frameSize=frameSize,
            pos=pos)
        # reparent the frame to the hudNP so we can hide it easily
        self.myFrame.reparentTo(self.hudNP)

        # read title or set to a default value
        title = getattr(self.config.settings, "title", "Introduce your data")

        # title of the frame
        label = OnscreenText(text=title,
                             pos=(0, frameSize[3] - scale * 2.5),
                             scale=scale * 1.5,
                             fg=labelColour,
                             align=TextNode.ACenter,
                             mayChange=1)
        label.reparentTo(self.myFrame.getCanvas())

        # max length in characters of a label (will split in lines if bigger)
        maxLabel = self.config.settings.maxlabel
        maxwidth = 0
        # position of the first label and widget
        lastYpos = frameSize[3] - scale * 4

        for count, i in enumerate(self.config.input):

            # create label in several lines up to 15 chars
            # split the string in several lines up to 15 chars
            printOut("Creating element: %s" % i.label, 2)
            splitWords = splitString(str(i.label) + ':', maxLabel)
            for s in splitWords:
                lastYpos -= 1.1 * scale
                label2 = OnscreenText(text=s,
                                      pos=(0, lastYpos),
                                      scale=scale,
                                      fg=labelColour,
                                      align=TextNode.ARight,
                                      mayChange=1)
                bounds = label2.getTightBounds()
                width = abs(bounds[0][0] - bounds[1][1])
                if (width > maxwidth): maxwidth = width
                label2.reparentTo(self.myFrame.getCanvas())
                self.guiLabels.append(label2)

            # for each label, create a widget matching the YAML
            widgetYpos = lastYpos
            if (str(i.type) == 'TextEntry'):
                widget = DirectEntry(text="",
                                     scale=scale,
                                     cursorKeys=1,
                                     command=self.setText,
                                     extraArgs=[],
                                     pos=(0.05, 1, widgetYpos),
                                     numLines=1,
                                     focus=0)
            elif (str(i.type) == 'Option'):
                widget = DirectOptionMenu(text="options",
                                          scale=1.05 * scale,
                                          items=i.tuple_values,
                                          popupMarkerBorder=(1, 0),
                                          initialitem=0,
                                          command=self.optionMenu,
                                          extraArgs=[],
                                          pos=(0.05, 1, widgetYpos),
                                          text_scale=(0.7, 0.7),
                                          text_pos=(0.3, 0.1))

            elif (str(i.type) == 'TickBox'):
                widget = DirectCheckButton(text="",
                                           scale=scale,
                                           command=self.tickBoxClicked,
                                           extraArgs=[],
                                           pos=(scale + 0.04, 1,
                                                widgetYpos + scale / 3.0))
                widget.clicked = getattr(i, 'default', False)

            # order of creation
            widget['extraArgs'] = [widget]
            self.focusOrder.append(widget)
            widget.reparentTo(self.myFrame.getCanvas())
            # distance to next widget
            lastYpos -= scale

        # adjust X position based on the largest word
        for l in self.guiLabels:
            #adjust X position
            l.setX(frameSize[0] + maxwidth + 0.05)
        for w in self.focusOrder:
            w.setX(w['pos'][0] + frameSize[0] + maxwidth + 0.10)

        # add a button to save the values and advance from the FORM (exit this state)
        lastYpos -= 2 * scale
        pad0 = (0.9, 0.7)
        #self.saveButton = DirectButton( parent = self.myFrame,
        #                            text="Save", pad=pad0, scale=0.05,
        #                            pos=(frameSize[1] - 10*0.05, 0, lastYpos), command=self.savePressed
        #                            )
        #self.finishButton = DirectButton ( parent = self.myFrame,
        #        text="Finish", pad=pad0, scale=0.05,
        #        pos=(frameSize[1] - 5*0.05,0,lastYpos), command=self.finishPressed
        #        )
        #self.finishButton["state"] = DGG.DISABLED
        #self.clearButton = DirectButton ( parent = self.myFrame,
        #        text="Clear", pad=pad0, scale=0.05,
        #        pos=(frameSize[1] - 15*0.05,0,lastYpos), command=self.clearButton
        #        )
        self.nextButton = DirectButton(parent=self.myFrame,
                                       text="Next",
                                       pad=pad0,
                                       scale=0.05,
                                       pos=(frameSize[1] - 10 * 0.05, 0, -0.9),
                                       command=self.nextPressed)
        # resize canvas to fit in height
        self.myFrame['canvasSize'] = (frameSize[0], frameSize[1], lastYpos,
                                      frameSize[3])
class ChatHandler(DirectObject, Chat):
    def __init__(self, cr):
        base.messenger.send("registerLoadEvent", ["loadChatDone"])

        Chat.__init__(self, base.a2dTopRight)

        self.cr = cr

        self.frmChat.setPos(
            -self.frmChat["frameSize"][1],
            self.frmChat.getY(),
            self.frmChat.getZ())
        self.btnToggleChat.hide()
        self.btnToggleChat.setPos(
            -self.btnToggleChat["frameSize"][1],
            self.btnToggleChat.getY(),
            self.btnToggleChat.getZ())
        self.btnToggleChatOrigTextFG = self.btnToggleChat.component("text1").fg


        self.btnToggleChat["sortOrder"] = 990
        self.frmChat["sortOrder"] = 990

        self.txtMessage["focusInCommand"] = self.focusInCommandFunc
        self.txtMessage["focusOutCommand"] = self.focusOutCommandFunc
        self.txtMessage["command"] = self.sendMessage

        tpMgr = TextPropertiesManager.getGlobalPtr()
        tpBold = TextProperties()
        font = loader.loadFont("assets/fonts/OldaniaADFStd-Bold.otf")
        tpBold.setFont(font)
        tpMgr.setProperties("bold", tpBold)


        self.lblMessages = OnscreenText(
            text="\1bold\1Messages:\2",
            scale = 0.05,
            pos = (self.frmMessages["canvasSize"][0], -0.05),
            align = TextNode.ALeft,
            wordwrap = 14,
            parent = self.frmMessages.getCanvas())

        self.accept("sendMessage", self.sendMessage)
        self.accept("setText", self.addMessage)
        self.accept("toggleChat", self.toggleChat)
        self.hide()

    def start(self, roomZone):
        self.msg = self.cr.createDistributedObject(
            className = "DMessage",
            zoneId = roomZone)

        self.frmChat.show()
        self.btnToggleChat.show()
        base.messenger.send("loadChatDone")

    def destroy(self):
        self.ignoreAll()
        self.frmChat.removeNode()
        self.btnToggleChat.removeNode()

    def toggleChat(self):
        """Toggle the visibility of the chat frame and set the buttons text
        accordingly"""
        base.messenger.send("playSFXSlide")
        if self.frmChat.isHidden():
            self.frmChat.show()
            btnName = self.btnToggleChat["text"]
            if btnName.endswith("*"):
                self.btnToggleChat["text_fg"] = self.btnToggleChatOrigTextFG
                self.btnToggleChat["text"] = btnName[:-1]
        else:
            self.frmChat.hide()

    def focusInCommandFunc(self):
        base.messenger.send("disableOtherKeyboardInput")
        self.clearText()

    def focusOutCommandFunc(self):
        base.messenger.send("enableOtherKeyboardInput")
        self.setDefaultText()

    def clearText(self):
        """ Write an empty string in the textbox """
        self.txtMessage.enterText("")

    def setDefaultText(self):
        """ Write the default message in the textbox """
        self.txtMessage.enterText("Your Message")

    def sendMessage(self, args=None):
        """ Send the text written in the message textbox to the clients """
        txtMsg = self.txtMessage.get()
        if txtMsg.strip() == "": return
        sentText = "\1bold\1{}:\2 {}".format(self.cr.getMyName(), self.txtMessage.get())

        self.msg.b_sendText(sentText)

        self.txtMessage.enterText("")

    def addMessage(self, message):
        """Add the given message to the chat messages frame and add a * to the
        toggle buttons text if the chat is hidden"""
        if self.frmChat.isHidden():
            self.btnToggleChat["text_fg"] = (0.2,0.2,1,1)
            self.btnToggleChat["text"] += "*"

        self.lblMessages["text"] = "{}\n{}".format(
            self.lblMessages["text"],
            message)

        # get the size of the written text
        textbounds = self.lblMessages.getTightBounds()
        # resize the canvas. This will make the scrollbars dis-/appear,
        # dependent on if the canvas is bigger than the frame size.
        self.frmMessages["canvasSize"] = (
            -0.38, textbounds[1].getX(),
            textbounds[0].getZ(), 0)
        self.frmMessages.setCanvasSize()
Esempio n. 7
0
class Window():
    texture = None
    def __init__(self, title_text, scale, parent=None, child=None, transparent=False, owner=None):
        self.title_text = title_text
        self.scale = scale
        self.title_size = settings.ui_font_size
        self.owner = owner
        self.child = None
        self.last_pos = None
        self.title_color = (1, 1, 1, 1)
        self.title_pad = tuple(self.scale * 2)
        if parent is None:
            parent = aspect2d
        self.parent = parent
        if transparent:
            frameColor = (0, 0, 0, 0)
        else:
            frameColor = (0.5, 0.5, 0.5, 1)
        self.pad = 0
        self.event_handler = DirectObject()
        self.button_thrower = base.buttonThrowers[0].node()
        self.event_handler.accept("wheel_up-up", self.mouse_wheel_event, extraArgs = [-1])
        self.event_handler.accept("wheel_down-up", self.mouse_wheel_event, extraArgs = [1])
        self.scrollers = []

#         if Window.texture is None:
#             Window.texture = loader.loadTexture('textures/futureui1.png')
#         image_scale = (scale[0] * Window.texture.get_x_size(), 1, scale[1] * Window.texture.get_y_size())
        self.frame = DirectFrame(parent=parent, state=DGG.NORMAL, frameColor=frameColor)#, image=self.texture, image_scale=image_scale)
        self.title_frame = DirectFrame(parent=self.frame, state=DGG.NORMAL, frameColor=(.5, .5, .5, 1))
        self.title = OnscreenText(text=self.title_text,
                                  style=Plain,
                                  fg=self.title_color,
                                  scale=tuple(self.scale * self.title_size),
                                  parent=self.title_frame,
                                  pos=(0, 0),
                                  align=TextNode.ALeft,
                                  font=None,
                                  mayChange=True)
        bounds = self.title.getTightBounds()
        self.title_frame['frameSize'] = [0, bounds[1][0] - bounds[0][0] + self.title_pad[0] * 2,
                                         0, bounds[1][2] - bounds[0][2] + self.title_pad[1] * 2]
        self.title.setPos( -bounds[0][0] + self.title_pad[0],  -bounds[0][2] + self.title_pad[1])
        self.close_frame = DirectFrame(parent=self.frame, state=DGG.NORMAL, frameColor=(.5, .5, .5, 1))
        self.close = OnscreenText(text='X',
                                  style=Plain,
                                  fg=self.title_color,
                                  scale=tuple(self.scale * self.title_size),
                                  parent=self.close_frame,
                                  pos=(0, 0),
                                  align=TextNode.ACenter,
                                  font=None,
                                  mayChange=True)
        bounds = self.close.getTightBounds()
        self.close_frame['frameSize'] = [0, bounds[1][0] - bounds[0][0] + self.title_pad[0] * 2,
                                         self.title_frame['frameSize'][2], self.title_frame['frameSize'][3]]
        self.close.setPos( -bounds[0][0] + self.title_pad[0],  -bounds[0][2] + self.title_pad[1])
        self.frame.setPos(0, 0, 0)
        self.title_frame.bind(DGG.B1PRESS, self.start_drag)
        self.title_frame.bind(DGG.B1RELEASE, self.stop_drag)
        self.close_frame.bind(DGG.B1PRESS, self.close_window)
        self.set_child(child)

    def set_child(self, child):
        if child is not None:
            self.child = child
            child.reparent_to(self.frame)
            self.update()

    def update(self):
        if self.child is not None:
            frame_size = list(self.child.frame['frameSize'])
            if frame_size is not None:
                frame_size[0] -= self.pad
                frame_size[1] += self.pad
                frame_size[2] += self.pad
                frame_size[3] -= self.pad
            self.frame['frameSize'] = frame_size
        if self.frame['frameSize'] is not None:
            width = self.frame['frameSize'][1] - self.frame['frameSize'][0]
            title_size = self.title_frame['frameSize']
            title_size[0] = 0
            title_size[1] = width
            self.title_frame['frameSize'] = title_size
            self.close_frame.setPos(width - self.close_frame['frameSize'][1], 0, 0)

    def register_scroller(self, scroller):
        self.scrollers.append(scroller)

    def mouse_wheel_event(self, dir):
        # If the user is scrolling a scroll-bar, don't try to scroll the scrolled-frame too.
        region = base.mouseWatcherNode.getOverRegion()
        if region is not None:
            widget = base.render2d.find("**/*{0}".format(region.name))
            if widget.is_empty() or isinstance(widget.node(), PGSliderBar) or isinstance(widget.getParent().node(), PGSliderBar):
                return

        # Get the mouse-position
        if not base.mouseWatcherNode.hasMouse():
            return
        mouse_pos = base.mouseWatcherNode.getMouse()

        found_scroller = None
        # Determine whether any of the scrolled-frames are under the mouse-pointer
        for scroller in self.scrollers:
            bounds = scroller['frameSize']
            pos = scroller.get_relative_point(base.render2d, Point3(mouse_pos.get_x() ,0, mouse_pos.get_y()))
            if pos.x > bounds[0] and pos.x < bounds[1] and \
                pos.z > bounds[2] and pos.z < bounds[3]:
                found_scroller = scroller
                break

        if found_scroller is not None:
            if not found_scroller.verticalScroll.isHidden():
                self.do_mouse_scroll(found_scroller.verticalScroll, dir, None)
            else:
                self.do_mouse_scroll(found_scroller.horizontalScroll, dir, None)

    def do_mouse_scroll(self, obj, dir, data):
        if isinstance(obj, DirectSlider) or isinstance(obj, DirectScrollBar):
            obj.setValue(obj.getValue() + dir * obj["pageSize"] * 0.1)

    def start_drag(self, event):
        if base.mouseWatcherNode.has_mouse():
            mpos = base.mouseWatcherNode.get_mouse()
            self.drag_start = self.frame.parent.get_relative_point(render2d, Point3(mpos.get_x() ,0, mpos.get_y())) - self.frame.getPos()
            taskMgr.add(self.drag, "drag", -1)

    def drag(self, task):
        if base.mouseWatcherNode.has_mouse():
            mpos = base.mouseWatcherNode.get_mouse()
            current_pos = self.frame.parent.get_relative_point(render2d, Point3(mpos.get_x() ,0, mpos.get_y()))
            self.frame.set_pos(current_pos - self.drag_start)
        return task.again

    def close_window(self, event=None):
        if self.owner is not None:
            self.owner.window_closed(self)
        self.destroy()

    def stop_drag(self, event):
        taskMgr.remove("drag")
        self.last_pos = self.frame.getPos()

    def destroy(self):
        if self.frame is not None:
            self.frame.destroy()
        self.frame = None
        self.scrollers = []
        self.event_handler.ignore_all()

    def getPos(self):
        return self.frame.getPos()

    def setPos(self, pos):
        self.frame.setPos(pos)
Esempio n. 8
0
class Window():
    texture = None

    def __init__(self,
                 title,
                 scale,
                 parent=None,
                 child=None,
                 transparent=False,
                 owner=None):
        self.scale = scale
        self.owner = owner
        self.last_pos = None
        self.title_text = title
        self.title_color = (1, 1, 1, 1)
        self.title_pad = tuple(self.scale * 2)
        if parent is None:
            parent = aspect2d
        self.parent = parent
        if transparent:
            frameColor = (0, 0, 0, 0)
        else:
            frameColor = (0, 0, 0, 1)
        self.pad = 0
        #         if Window.texture is None:
        #             Window.texture = loader.loadTexture('textures/futureui1.png')
        #         image_scale = (scale[0] * Window.texture.get_x_size(), 1, scale[1] * Window.texture.get_y_size())
        self.frame = DirectFrame(
            parent=parent, state=DGG.NORMAL, frameColor=frameColor
        )  #, image=self.texture, image_scale=image_scale)
        self.title_frame = DirectFrame(parent=self.frame,
                                       state=DGG.NORMAL,
                                       frameColor=(.5, .5, .5, 1))
        self.title = OnscreenText(text=self.title_text,
                                  style=Plain,
                                  fg=self.title_color,
                                  scale=tuple(self.scale * 14),
                                  parent=self.title_frame,
                                  pos=(0, 0),
                                  align=TextNode.ALeft,
                                  font=None,
                                  mayChange=True)
        bounds = self.title.getTightBounds()
        self.title_frame['frameSize'] = [
            0, bounds[1][0] - bounds[0][0] + self.title_pad[0] * 2, 0,
            bounds[1][2] - bounds[0][2] + self.title_pad[1] * 2
        ]
        self.title.setPos(-bounds[0][0] + self.title_pad[0],
                          -bounds[0][2] + self.title_pad[1])
        self.close_frame = DirectFrame(parent=self.frame,
                                       state=DGG.NORMAL,
                                       frameColor=(.5, .5, .5, 1))
        self.close = OnscreenText(text='X',
                                  style=Plain,
                                  fg=self.title_color,
                                  scale=tuple(self.scale * 14),
                                  parent=self.close_frame,
                                  pos=(0, 0),
                                  align=TextNode.ACenter,
                                  font=None,
                                  mayChange=True)
        bounds = self.close.getTightBounds()
        self.close_frame['frameSize'] = [
            0, bounds[1][0] - bounds[0][0] + self.title_pad[0] * 2,
            self.title_frame['frameSize'][2], self.title_frame['frameSize'][3]
        ]
        self.close.setPos(-bounds[0][0] + self.title_pad[0],
                          -bounds[0][2] + self.title_pad[1])
        self.frame.setPos(0, 0, 0)
        self.title_frame.bind(DGG.B1PRESS, self.start_drag)
        self.title_frame.bind(DGG.B1RELEASE, self.stop_drag)
        self.close_frame.bind(DGG.B1PRESS, self.close_window)
        self.set_child(child)

    def set_child(self, child):
        if child is not None:
            self.child = child
            child.reparent_to(self.frame)
            self.update()

    def update(self):
        if self.child is not None:
            frame_size = self.child.frame['frameSize']
            if frame_size is not None:
                frame_size[0] -= self.pad
                frame_size[1] += self.pad
                frame_size[2] += self.pad
                frame_size[3] -= self.pad
            self.frame['frameSize'] = frame_size
        if self.frame['frameSize'] is not None:
            width = self.frame['frameSize'][1] - self.frame['frameSize'][0]
            title_size = self.title_frame['frameSize']
            title_size[0] = 0
            title_size[1] = width
            self.title_frame['frameSize'] = title_size
            self.close_frame.setPos(width - self.close_frame['frameSize'][1],
                                    0, 0)

    def start_drag(self, event):
        if base.mouseWatcherNode.has_mouse():
            mpos = base.mouseWatcherNode.get_mouse()
            self.drag_start = self.frame.parent.get_relative_point(
                render2d, Point3(mpos.get_x(), 0,
                                 mpos.get_y())) - self.frame.getPos()
            taskMgr.add(self.drag, "drag", -1)

    def drag(self, task):
        if base.mouseWatcherNode.has_mouse():
            mpos = base.mouseWatcherNode.get_mouse()
            current_pos = self.frame.parent.get_relative_point(
                render2d, Point3(mpos.get_x(), 0, mpos.get_y()))
            self.frame.set_pos(current_pos - self.drag_start)
        return task.again

    def close_window(self, event=None):
        if self.owner is not None:
            self.owner.window_closed(self)
        self.destroy()

    def stop_drag(self, event):
        taskMgr.remove("drag")
        self.last_pos = self.frame.getPos()

    def destroy(self):
        if self.frame is not None:
            self.frame.destroy()
        self.frame = None

    def getPos(self):
        return self.frame.getPos()

    def setPos(self, pos):
        self.frame.setPos(pos)
Esempio n. 9
0
class HostMenu(DirectObject):
    def __init__(self):
        self.defaultBtnMap = base.loader.loadModel("gui/button_map")
        self.buttonGeom = (self.defaultBtnMap.find("**/button_ready"),
                           self.defaultBtnMap.find("**/button_click"),
                           self.defaultBtnMap.find("**/button_rollover"),
                           self.defaultBtnMap.find("**/button_disabled"))

        defaultFont = loader.loadFont('gui/eufm10.ttf')

        self.logFrame = DirectScrolledFrame(
            canvasSize=(0, base.a2dRight * 2, -5, 0),
            frameSize=(0, base.a2dRight * 2, (base.a2dBottom + .2) * 2, 0),
            frameColor=(0.1, 0.1, 0.1, 1))
        self.logFrame.reparentTo(base.a2dTopLeft)

        # create the info and server debug output
        self.textscale = 0.1
        self.txtinfo = OnscreenText(scale=self.textscale,
                                    pos=(0.1, -0.1),
                                    text="",
                                    align=TextNode.ALeft,
                                    fg=(0.1, 1.0, 0.15, 1),
                                    bg=(0, 0, 0, 0),
                                    shadow=(0, 0, 0, 1),
                                    shadowOffset=(-0.02, -0.02))
        self.txtinfo.setTransparency(1)
        self.txtinfo.reparentTo(self.logFrame.getCanvas())

        # create a close Server button
        self.btnBackPos = Vec3(0.4, 0, 0.2)
        self.btnBackScale = 0.25
        self.btnBack = DirectButton(
            # Scale and position
            scale=self.btnBackScale,
            pos=self.btnBackPos,
            # Text
            text="Quit Server",
            text_scale=0.45,
            text_pos=(0, -0.1),
            text_fg=(0.82, 0.85, 0.87, 1),
            text_shadow=(0, 0, 0, 1),
            text_shadowOffset=(-0.02, -0.02),
            text_font=defaultFont,
            # Frame
            geom=self.buttonGeom,
            frameColor=(0, 0, 0, 0),
            relief=0,
            pressEffect=False,
            # Functionality
            command=self.back,
            rolloverSound=None,
            clickSound=None)
        self.btnBack.setTransparency(1)
        self.btnBack.reparentTo(base.a2dBottomLeft)

        # catch window resizes and recalculate the aspectration
        self.accept("window-event", self.recalcAspectRatio)
        self.accept("addLog", self.addLog)

    def show(self):
        self.logFrame.show()
        self.btnBack.show()

    def hide(self):
        self.logFrame.hide()
        self.btnBack.hide()

    def back(self):
        self.hide()
        base.messenger.send("stop_server")
        self.addLog("Quit Server!")

    def addLog(self, text):
        self.txtinfo.appendText(text + "\n")
        textbounds = self.txtinfo.getTightBounds()
        self.logFrame["canvasSize"] = (0, textbounds[1].getX(),
                                       textbounds[0].getZ(), 0)

    def recalcAspectRatio(self, window):
        """get the new aspect ratio to resize the mainframe"""
        # set the mainframe size to the window borders again
        self.logFrame["frameSize"] = (0, base.a2dRight * 2,
                                      (base.a2dBottom + .2) * 2, 0)