예제 #1
0
    def _createComponents(self):
        self.debug("Creating GUI Components")

        self.categoryMenu = self.parent.attachNewNode("CategoryMenu")
        self.categoryMenu.setPos(-350, 0, -49)

        self.sidebar = self.parent.attachNewNode("EditorSidebar")

        self.sidebarBackground = DirectFrame(
            parent=self.sidebar,
            pos=(0, 0, 0),
            frameSize=(0, 92, 0, -base.win.getYSize()),
            frameColor=(0.05, 0.05, 0.05, 1.0),
        )

        self.logo = BetterOnscreenImage(
            parent=self.sidebar, transparent=False, image="Editor/GUI/logo.png", x=0, y=0, w=92, h=48
        )

        self.categoriesParent = self.sidebar.attachNewNode("Categories")
        self.categoriesParent.setPos(0, 0, -48)

        self.categoryIcons = {}

        self.animations = {"moveMenuArrow": None, "moveCategoryMenu": None}

        for index, category in enumerate(EditorCategories.Categories):
            iconDefault = "Editor/GUI/Icon-" + category.name + ".png"
            iconHover = "Editor/GUI/Icon-" + category.name + "-Hover.png"
            # iconActive = "Editor/GUI/Icon-" + category.name + "-Hover.png"
            self.categoryIcons[category.name] = BetterOnscreenImage(
                parent=self.categoriesParent, transparent=False, image=iconDefault, x=0, y=94 * index, w=92, h=94
            )

            # i hate direct gui
            hoverCatch = DirectFrame(
                parent=self.categoriesParent,
                frameSize=(0, 92, 0, -94),
                pos=(0, 0, -94 * index),
                frameColor=(0, 0, 0, 0),
                state=DGG.NORMAL,
            )

            # Add a hover effect
            hoverCatch.bind(DGG.ENTER, partial(self._showCategoryMenu, category.name))
            hoverCatch.bind(DGG.EXIT, partial(self._hideCategoryMenu, category.name))

        self.currentCategoryMarker = BetterOnscreenImage(
            parent=self.categoriesParent, image="Editor/GUI/Arrow-Right.png", x=92, y=0, w=11, h=21
        )

        self.currentCategoryMarker.hide()

        self.categoryMenuBg = DirectFrame(
            parent=self.categoryMenu, pos=(15, 0, 0), frameSize=(0, 300, 0, -400), frameColor=(0.2, 0.2, 0.2, 1.0)
        )
예제 #2
0
    def renderBuffers(self):
        self.buffersParent.node().removeAllChildren()

        posX = 0
        posY = 0

        for name in self.bufferOrder:
            target = self.buffers[name]
            for targetType in RenderTargetType.All:
                if not target.hasTarget(targetType):
                    continue
                tex = target.getTexture(targetType)
                sizeStr = str(tex.getXSize()) + " x " + str(tex.getYSize())

                if tex.getZSize() != 1:
                    sizeStr += " x " + str(tex.getZSize())

                sizeStr += " - " + str(self.calculateTexSize(tex)) + " MB"

                node = DirectFrame(parent=self.buffersParent, frameColor=(
                    1, 1, 1, 0.2), frameSize=(-self.innerPadding, self.texWidth + self.innerPadding, -self.texHeight - 30 - self.innerPadding, self.innerPadding + 15),
                    state=DGG.NORMAL)
                node.setPos(
                    20 + posX * (self.texWidth + self.texPadding), 0, -self.paddingTop - 22 - posY * (self.texHeight + self.texPadding + 44))
                node.bind(DGG.ENTER, partial(self.onMouseOver, node))
                node.bind(DGG.EXIT, partial(self.onMouseOut, node))
                node.bind(DGG.B1RELEASE, partial(self.showDetail, tex))

                aspect = tex.getYSize() / float(tex.getXSize())
                computedWidth = self.texWidth
                computedHeight = self.texWidth * aspect

                if computedHeight > self.texHeight:
                    # have to scale tex width instead
                    computedHeight = self.texHeight
                    computedWidth = tex.getXSize() / float(tex.getYSize()) * \
                        self.texHeight

                img = BetterOnscreenImage(
                    image=tex, parent=node, x=0, y=30, w=computedWidth,
                    h=computedHeight, transparent=False, nearFilter=False,
                    anyFilter=False)
                txtName = BetterOnscreenText(
                    text=name, x=0, y=0, size=13, parent=node)
                txtSizeFormat = BetterOnscreenText(
                    text=sizeStr, x=0, y=20, size=13, parent=node,
                    color=Vec3(0.2))
                txtTarget = BetterOnscreenText(
                    text=str(targetType), align="right", x=self.texWidth,
                    y=20, size=13, parent=node, color=Vec3(0.2))

                posX += 1
                if posX > self.pageSize:
                    posY += 1
                    posX = 0
예제 #3
0
class SocketBase:
    def __init__(self, node, name):
        self.socketID = uuid4()
        self.node = node
        self.name = name
        self.height = 0.2
        self.type = None
        self.value = None
        self.connected = False

    def getValue(self):
        """Returns a string serializable value stored in this node"""
        return self.value

    def setValue(self, value):
        self.value = value

    def createPlug(self, parent):
        self.plug = DirectFrame(
            state=DGG.NORMAL,
            frameColor=(0, 0, 0, 1),
            frameSize=(-0.05, 0.05, -0.05, 0.05),
            parent=parent,
        )
        self.setupBind()

    def setupBind(self):
        self.plug.bind(DGG.B1PRESS, self.startPlug)
        self.plug.bind(DGG.B1RELEASE, self.releasePlug)
        self.plug.bind(DGG.ENTER, self.endPlug)

    def startPlug(self, event):
        base.messenger.send("startPlug", [self])
        base.messenger.send("startLineDrawing", [self.plug.getPos(render2d)])

    def endPlug(self, event):
        taskMgr.remove("delayedPlugRelease")
        base.messenger.send("endPlug", [self])
        base.messenger.send("connectPlugs")

    def releasePlug(self, event):
        base.messenger.send("stopLineDrawing")
        taskMgr.doMethodLater(0.2,
                              base.messenger.send,
                              "delayedPlugRelease",
                              extraArgs=["cancelPlug"])

    def updateConnectedNodes(self, *args):
        base.messenger.send("updateConnectedNodes", [self.node])

    def setConnected(self, connected):
        self.connected = connected
예제 #4
0
class NodeBase(DirectObject):
    def __init__(self, name, parent):
        self.right = 0.5
        self.left = -0.5
        self.name = name
        self.nodeID = uuid4()
        self.inputList = []
        self.outputList = []
        self.selected = False

        self.frame = DirectFrame(state=DGG.NORMAL,
                                 text=name,
                                 text_align=TextNode.A_left,
                                 text_scale=0.1,
                                 text_pos=(self.left, 0.12),
                                 text_fg=(1, 1, 1, 1),
                                 frameColor=(0.25, 0.25, 0.25, 1),
                                 frameSize=(-0.5, 0.5, -.6, 0.2),
                                 parent=parent)

        self.setupBind()
        self.hide()

        self.setPos = self.frame.setPos
        self.getPos = self.frame.getPos

    def addIn(self, name, socketType):
        """Add a new input socket of the given socket type"""
        inSocket = socketType(self, name)
        self.inputList.append(inSocket)

    def addOut(self, name):
        """Add a new output socket"""
        outSocket = OutSocket(self, name)
        self.outputList.append(outSocket)

    def isLeaveNode(self):
        """Returns true if this is a leave node.
        Leave nodes do not have any input connections. Either if no
        input sockets are defined at all or none of the sockets is
        connected."""

        # check if we have any input sockets and if so if any of them is connected
        for inSocket in self.inputList:
            if inSocket.connected: return False
        return True

    def logic(self):
        """Run the logic of this node, process all in and output data.
        This is a stub and should be overwritten by the derived classes"""
        pass

    def update(self):
        """Show all sockets and resize the frame to fit all sockets in"""
        z = 0

        for outSocket in self.outputList:
            outSocket.show(z, self.right)
            z -= outSocket.height

        for inSocket in self.inputList:
            inSocket.show(z, self.left)
            z -= inSocket.height

        fs = self.frame["frameSize"]
        self.frame["frameSize"] = (fs[0], fs[1], z, fs[3])

    def create(self):
        """Place and show the node under the mouse and start draging it."""
        mwn = base.mouseWatcherNode
        if mwn.hasMouse():
            newPos = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1])
            self.frame.setPos(render2d, newPos)
        self._dragStart(self.frame, None)
        self.show()

    def show(self):
        """Shows the Node frame and updates its sockets"""
        self.update()
        self.frame.show()

    def hide(self):
        """Hide the Node frame"""
        self.frame.hide()

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

    def setupBind(self):
        """Setup the mousebutton actions for drag and drop feature"""
        self.frame.bind(DGG.B1PRESS, self._dragStart, [self.frame])
        self.frame.bind(DGG.B1RELEASE, self._dragStop)

    def select(self, select):
        """Set this node as selected or deselected"""
        if self.selected == select: return
        self.selected = select
        if self.selected:
            self.frame["frameColor"] = (0.45, 0.45, 0.45, 1)
        else:
            self.frame["frameColor"] = (0.25, 0.25, 0.25, 1)

    def _dragStart(self, nodeFrame, event):
        # Mark this node as selected
        base.messenger.send("selectNode", [
            self, True,
            base.mouseWatcherNode.isButtonDown(KeyboardButton.shift()), True
        ])
        # tell everyone we started to drag this node
        base.messenger.send("dragNodeStart", [self])

        # Remove any previous started drag tasks
        taskMgr.remove("dragNodeDropTask")

        # get some positions
        vWidget2render2d = nodeFrame.getPos(render2d)
        vMouse2render2d = Point3(0)
        if event is not None:
            # we get the mouse position from the event
            vMouse2render2d = Point3(event.getMouse()[0], 0,
                                     event.getMouse()[1])
        else:
            # we try to get the current mouse position from the mouse watcher
            mwn = base.mouseWatcherNode
            if mwn.hasMouse():
                vMouse2render2d = Point3(mwn.getMouse()[0], 0,
                                         mwn.getMouse()[1])
        editVec = Vec3(vWidget2render2d - vMouse2render2d)
        self.hasMoved = False

        # Initiate the task to move the node and pass it some initial values
        t = taskMgr.add(self.dragTask, "dragNodeDropTask")
        t.nodeFrame = nodeFrame
        t.editVec = editVec
        t.mouseVec = vMouse2render2d

    def dragTask(self, t):
        mwn = base.mouseWatcherNode
        if mwn.hasMouse():
            # get the current mouse position fitting for a render2d position
            vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1])

            # check if the cursor has moved enough to drag this node
            # this gives us some puffer zone for clicking
            if not self.hasMoved and (t.mouseVec -
                                      vMouse2render2d).length() < 0.01:
                return t.cont

            # We actually have moved now
            self.hasMoved = True

            # calculate the new position
            newPos = vMouse2render2d + t.editVec

            # move the node to the new position
            t.nodeFrame.setPos(render2d, newPos)

            # tell everyone we moved the node
            base.messenger.send("dragNodeMove", [t.mouseVec, vMouse2render2d])

        return t.cont

    def _dragStop(self, event=None):
        self.ignore("mouse1-up")
        # remove the node dragging task
        taskMgr.remove("dragNodeDropTask")

        # check if the node has moved
        if not self.hasMoved:
            # we want to select this node as it has not been moved
            base.messenger.send("selectNode", [
                self, True,
                base.mouseWatcherNode.isButtonDown(KeyboardButton.shift())
            ])
        # tell everyone we stopped moving the node
        base.messenger.send("dragNodeStop", [self])

    def getLeftEdge(self):
        """Get the left edge of the frame as seen from the frame"""
        return self.frame["frameSize"][0]

    def getRightEdge(self):
        """Get the right edge of the frame as seen from the frame"""
        return self.frame["frameSize"][1]

    def getBottomEdge(self):
        """Get the bottom edge of the frame as seen from the frame"""
        return self.frame["frameSize"][2]

    def getTopEdge(self):
        """Get the top edge of the frame as seen from the frame"""
        return self.frame["frameSize"][3]

    def getLeft(self, np=None):
        """Get left edge of the frame with respect to it's position as seen from the given np"""
        if np is None:
            np = render2d
        return self.getPos(render2d).getX() + self.frame["frameSize"][0]

    def getRight(self, np=None):
        """Get right edge of the frame with respect to it's position as seen from the given np"""
        if np is None:
            np = render2d
        return self.getPos(render2d).getX() + self.frame["frameSize"][1]

    def getBottom(self, np=None):
        """Get bottom edge of the frame with respect to it's position as seen from the given np"""
        if np is None:
            np = render2d
        return self.getPos(render2d).getZ() + self.frame["frameSize"][2]

    def getTop(self, np=None):
        """Get top edge of the frame with respect to it's position as seen from the given np"""
        if np is None:
            np = render2d
        return self.getPos(render2d).getZ() + self.frame["frameSize"][3]
예제 #5
0
    def _createComponents(self):
        self.debug("Creating GUI Components")

        self.categoryMenu = self.parent.attachNewNode("CategoryMenu")
        self.categoryMenu.setPos(-350, 0, -49)

        self.sidebar = self.parent.attachNewNode("EditorSidebar")

        self.sidebarBackground = DirectFrame(parent=self.sidebar,
                                             pos=(0, 0, 0),
                                             frameSize=(0, 92, 0,
                                                        -base.win.getYSize()),
                                             frameColor=(0.05, 0.05, 0.05,
                                                         1.0))

        self.logo = BetterOnscreenImage(parent=self.sidebar,
                                        transparent=False,
                                        image="Editor/GUI/logo.png",
                                        x=0,
                                        y=0,
                                        w=92,
                                        h=48)

        self.categoriesParent = self.sidebar.attachNewNode("Categories")
        self.categoriesParent.setPos(0, 0, -48)

        self.categoryIcons = {}

        self.animations = {"moveMenuArrow": None, "moveCategoryMenu": None}

        for index, category in enumerate(EditorCategories.Categories):
            iconDefault = "Editor/GUI/Icon-" + category.name + ".png"
            iconHover = "Editor/GUI/Icon-" + category.name + "-Hover.png"
            # iconActive = "Editor/GUI/Icon-" + category.name + "-Hover.png"
            self.categoryIcons[category.name] = BetterOnscreenImage(
                parent=self.categoriesParent,
                transparent=False,
                image=iconDefault,
                x=0,
                y=94 * index,
                w=92,
                h=94)

            # i hate direct gui
            hoverCatch = DirectFrame(parent=self.categoriesParent,
                                     frameSize=(0, 92, 0, -94),
                                     pos=(0, 0, -94 * index),
                                     frameColor=(0, 0, 0, 0),
                                     state=DGG.NORMAL)

            # Add a hover effect
            hoverCatch.bind(DGG.ENTER,
                            partial(self._showCategoryMenu, category.name))
            hoverCatch.bind(DGG.EXIT,
                            partial(self._hideCategoryMenu, category.name))

        self.currentCategoryMarker = BetterOnscreenImage(
            parent=self.categoriesParent,
            image="Editor/GUI/Arrow-Right.png",
            x=92,
            y=0,
            w=11,
            h=21)

        self.currentCategoryMarker.hide()

        self.categoryMenuBg = DirectFrame(parent=self.categoryMenu,
                                          pos=(15, 0, 0),
                                          frameSize=(0, 300, 0, -400),
                                          frameColor=(0.2, 0.2, 0.2, 1.0))
예제 #6
0
    def _render_stages(self):
        """ Renders the stages to the window """

        self._remove_components()
        entries_per_row = 8
        aspect = Globals.base.win.get_y_size() /\
            float(Globals.base.win.get_x_size())
        entry_width = 180
        entry_height = (entry_width - 20) * aspect + 55

        # Store already processed images
        processed = set()
        index = -1
        # Iterate over all stages
        for stage_tex in self._stages:
            if stage_tex in processed:
                continue
            processed.add(stage_tex)
            index += 1
            stage_name = stage_tex.get_name()

            xoffs = index % entries_per_row
            yoffs = index // entries_per_row
            node = self._content_node.attach_new_node("Preview")
            node.set_sz(-1)
            node.set_pos(10 + xoffs * (entry_width - 14), 1, yoffs * (entry_height-14))

            if stage_name.startswith("Image"):
                r, g, b = 0.4, 0.4, 0.4
            else:
                r, g, b = rgb_from_string(stage_name)

            DirectFrame(
                parent=node, frameSize=(7, entry_width - 17, -7, -entry_height + 17),
                frameColor=(r, g, b, 1.0), pos=(0, 0, 0))

            frame_hover = DirectFrame(
                parent=node, frameSize=(0, entry_width - 10, 0, -entry_height + 10),
                frameColor=(0, 0, 0, 0), pos=(0, 0, 0), state=DGG.NORMAL)
            frame_hover.bind(
                DGG.ENTER, partial(self._on_texture_hovered, frame_hover))
            frame_hover.bind(
                DGG.EXIT, partial(self._on_texture_blurred, frame_hover))
            frame_hover.bind(
                DGG.B1PRESS, partial(self._on_texture_clicked, stage_tex))

            BetterOnscreenText(text=stage_name, x=15, y=29, parent=node,
                               size=12, color=Vec3(0.2))

            # Scale image so it always fits
            w, h = stage_tex.get_x_size(), stage_tex.get_y_size()
            scale_x = float(entry_width - 30) / max(1, w)
            scale_y = float(entry_height - 60) / max(1, h)
            scale_factor = min(scale_x, scale_y)

            if stage_tex.get_texture_type() == Texture.TT_buffer_texture:
                scale_factor = 1
                w = entry_width - 30
                h = entry_height - 60

            preview = BetterOnscreenImage(
                image=stage_tex, w=scale_factor * w, h=scale_factor * h,
                any_filter=False, parent=node, x=10, y=40, transparent=False)

            preview.set_shader_input("mipmap", 0)
            preview.set_shader_input("slice", 0)

            preview_shader = DisplayShaderBuilder.build(stage_tex, scale_factor*w, scale_factor*h)
            preview.set_shader(preview_shader)
예제 #7
0
    def _render_stages(self):
        """ Renders the stages to the window """

        self._remove_components()
        entries_per_row = 6
        aspect = Globals.native_resolution.y / Globals.native_resolution.x
        entry_width = 235
        entry_height = (entry_width - 20) * aspect + 55

        # Store already processed images
        processed = set()
        index = -1
        # Iterate over all stages
        for stage_tex in self._stages:
            if stage_tex in processed:
                continue
            processed.add(stage_tex)
            index += 1
            stage_name = stage_tex.get_name()

            xoffs = index % entries_per_row
            yoffs = index // entries_per_row
            node = self._content_node.attach_new_node("Preview")
            node.set_sz(-1)
            node.set_pos(10 + xoffs * (entry_width - 14), 1, yoffs * (entry_height - 14 + 10))

            r, g, b = 0.2, 0.2, 0.2
            if isinstance(stage_tex, Image):
                r, g, b = 0.2, 0.4, 0.6

            stage_name = stage_name.replace("render_pipeline_internal:", "")
            parts = stage_name.split(":")
            stage_name = parts[-1]
            DirectFrame(
                parent=node, frameSize=(7, entry_width - 17, -7, -entry_height + 17),
                frameColor=(r, g, b, 1.0), pos=(0, 0, 0))

            frame_hover = DirectFrame(
                parent=node, frameSize=(0, entry_width - 10, 0, -entry_height + 10),
                frameColor=(0, 0, 0, 0), pos=(0, 0, 0), state=DGG.NORMAL)
            frame_hover.bind(
                DGG.ENTER, partial(self._on_texture_hovered, frame_hover))
            frame_hover.bind(
                DGG.EXIT, partial(self._on_texture_blurred, frame_hover))
            frame_hover.bind(
                DGG.B1PRESS, partial(self._on_texture_clicked, stage_tex))

            Text(text=stage_name, x=15, y=29, parent=node, size=12, color=Vec3(0.8))

            # Scale image so it always fits
            w, h = stage_tex.get_x_size(), stage_tex.get_y_size()
            padd_x, padd_y = 24, 57
            scale_x = (entry_width - padd_x) / max(1, w)
            scale_y = (entry_height - padd_y) / max(1, h)
            scale_factor = min(scale_x, scale_y)

            if stage_tex.get_texture_type() == Image.TT_buffer_texture:
                scale_factor = 1
                w = entry_width - padd_x
                h = entry_height - padd_y

            preview = Sprite(
                image=stage_tex, w=scale_factor * w, h=scale_factor * h,
                any_filter=False, parent=node, x=7, y=40, transparent=False)

            preview.set_shader_input("mipmap", 0)
            preview.set_shader_input("slice", 0)
            preview.set_shader_input("brightness", 1)
            preview.set_shader_input("tonemap", False)

            preview_shader = DisplayShaderBuilder.build(
                stage_tex, scale_factor * w, scale_factor * h)
            preview.set_shader(preview_shader)

        num_rows = (index + entries_per_row) // entries_per_row

        self._set_scroll_height(50 + (entry_height - 14 + 10) * num_rows)
class DraggableWindow(RPObject):
    """ This is a simple draggable but not resizeable window """
    def __init__(self, width=800, height=500, title="Window", parent=None):
        """ Constructs a new window with the given dimensions and title """
        RPObject.__init__(self, "Window-" + title)
        self._width = width
        self._height = height
        self._title = title
        self._visible = True
        self._parent = parent if parent else Globals.base.pixel2d
        self._dragging = False
        self._drag_offset = Vec2(0)
        self._pos = Vec2(0)

    def center_on_screen(self):
        """ Centers the window on screen """
        self._context_scale = 1.0 / self._parent.get_sx()
        self._context_width = Globals.native_resolution.x * self._context_scale
        self._context_height = Globals.native_resolution.y * self._context_scale
        self._set_pos(
            Vec2((self._context_width - self._width) / 2,
                 (self._context_height - self._height) / 2))

    def set_title(self, title):
        """ Sets the window title """
        self._title = title
        self._window_title.set_text(title)

    def show(self):
        """ Shows the window """
        self._visible = True
        self.center_on_screen()
        self._node.show()

    def hide(self):
        """ Hides the window """
        self._visible = False
        self._stop_drag()
        self._node.hide()

    def remove(self):
        """ Removes the window from the scene graph. You should still delete the
        instance """
        self._stop_drag()
        self._node.remove_node()

    def _create_components(self):
        """ Creates the window components """
        self._node = self._parent.attach_new_node("Window")
        self._node.set_pos(self._pos.x, 1, -self._pos.y)
        border_px = 1
        border_frame_size = (-border_px, self._width + border_px, border_px,
                             -self._height - border_px)
        self._border_frame = DirectFrame(pos=(0, 1, 0),
                                         frameSize=border_frame_size,
                                         frameColor=(24 / 255.0, 131 / 255.0,
                                                     215 / 255.0, 1),
                                         parent=self._node,
                                         state=DGG.NORMAL)
        self._background = DirectFrame(pos=(0, 1, 0),
                                       frameSize=(0, self._width, 0,
                                                  -self._height),
                                       frameColor=(0.1, 0.1, 0.1, 1.0),
                                       parent=self._node)
        self._title_bar = DirectFrame(
            pos=(0, 1, 0),
            frameSize=(0, self._width, 0, -25),
            # frameColor=(0.058, 0.058, 0.058, 1),
            frameColor=(1, 1, 1, 1),
            parent=self._node,
            state=DGG.NORMAL)
        self._window_title = Text(parent=self._node,
                                  x=8,
                                  y=17,
                                  text=self._title,
                                  size=13,
                                  color=Vec3(0.15),
                                  may_change=True)
        self._btn_close = DirectButton(relief=DGG.FLAT,
                                       pressEffect=1,
                                       pos=(self._width - 22, 1, -12),
                                       frameColor=(1.0, 0.2, 0.2, 0.5),
                                       parent=self._node,
                                       scale=(45 / 2, 1, 24 / 2),
                                       image="/$$rp/data/gui/close_window.png")

        # Init bindings
        self._btn_close.set_transparency(TransparencyAttrib.M_alpha)
        self._btn_close.bind(DGG.B1CLICK, self._request_close)
        self._btn_close.bind(DGG.WITHIN, self._on_close_btn_hover)
        self._btn_close.bind(DGG.WITHOUT, self._on_close_btn_out)
        self._title_bar.bind(DGG.B1PRESS, self._start_drag)
        self._title_bar.bind(DGG.B1RELEASE, self._stop_drag)

    def _start_drag(self, evt=None):  # pylint: disable=unused-argument
        """ Gets called when the user starts dragging the window """
        self._dragging = True
        self._node.detach_node()
        self._node.reparent_to(self._parent)
        Globals.base.taskMgr.add(self._on_tick,
                                 "UIWindowDrag",
                                 uponDeath=self._stop_drag)
        self._drag_offset = self._pos - self._get_mouse_pos()

    def _on_close_btn_hover(self, evt=None):  # pylint: disable=unused-argument
        """ Internal method when the close button got hovered """
        self._btn_close["image"] = "/$$rp/data/gui/close_window_hover.png"

    def _on_close_btn_out(self, evt=None):  # pylint: disable=unused-argument
        """ Internal method when the close button is no longer hovered """
        self._btn_close["image"] = "/$$rp/data/gui/close_window.png"

    def _request_close(self, evt=None):  # pylint: disable=unused-argument
        """ This method gets called when the close button gets clicked """
        self.hide()

    def _stop_drag(self, evt=None):  # pylint: disable=unused-argument
        """ Gets called when the user stops dragging the window """
        Globals.base.taskMgr.remove("UIWindowDrag")
        self._dragging = False

    def _get_mouse_pos(self):
        """ Internal helper function to get the mouse position, scaled by
        the context scale """
        mouse_x, mouse_y = (Globals.base.win.get_pointer(0).x,
                            Globals.base.win.get_pointer(0).y)
        return Vec2(mouse_x, mouse_y) * self._context_scale

    def _set_pos(self, pos):
        """ Moves the window to the specified position """
        self._pos = pos
        self._pos.x = max(self._pos.x, -self._width + 100)
        self._pos.y = max(self._pos.y, 25)
        self._pos.x = min(self._pos.x, self._context_width - 100)
        self._pos.y = min(self._pos.y, self._context_height - 50)
        self._node.set_pos(self._pos.x, 1, -self._pos.y)

    def _on_tick(self, task):
        """ Task which updates the window while being dragged """
        self._set_pos(self._get_mouse_pos() + self._drag_offset)
        return task.cont
예제 #9
0
class SocketBase:
    def __init__(self, node, name):
        self.socketID = uuid4()
        self.node = node
        self.name = name
        self.height = 0.2
        self.type = None
        self.value = None
        self.connected = False
        self.frame = None
        self.allowMultiConnect = False

    def enable(self):
        """Enable any elements on the node"""
        pass

    def disable(self):
        """Disable any elements on the node that could possbily interfer with
        the mouse watcher and the drag/drop feature"""
        pass

    def getValue(self):
        """Returns a string serializable value stored in this node"""
        return self.value

    def setValue(self, value):
        self.value = value

    def createPlug(self, parent):
        self.plug = DirectFrame(
            state=DGG.NORMAL,
            image="icons/Plug.png",
            image_scale=.05,
            frameColor=(0, 0, 0, 0),
            frameSize=(-0.05, 0.05, -0.05, 0.05),
            parent=parent,
        )
        self.plug.setTransparency(TransparencyAttrib.M_multisample)
        self.setupBind()

    def setupBind(self):
        self.plug.bind(DGG.B1PRESS, self.startPlug)
        self.plug.bind(DGG.B1RELEASE, self.releasePlug)
        self.plug.bind(DGG.ENTER, self.endPlug)

    def startPlug(self, event):
        base.messenger.send("startPlug", [self])
        base.messenger.send("startLineDrawing", [self.plug.getPos(render2d)])

    def endPlug(self, event):
        taskMgr.remove("delayedPlugRelease")
        base.messenger.send("endPlug", [self])
        base.messenger.send("connectPlugs")

    def releasePlug(self, event):
        base.messenger.send("stopLineDrawing")
        taskMgr.doMethodLater(0.2,
                              base.messenger.send,
                              "delayedPlugRelease",
                              extraArgs=["cancelPlug"])

    def updateConnectedNodes(self, *args):
        base.messenger.send("updateConnectedNodes", [self.node])

    def setConnected(self, connected):
        self.connected = connected
        if self.connected:
            self.plug["image"] = "icons/PlugConnectedGood.png"
        else:
            self.plug["image"] = "icons/Plug.png"
예제 #10
0
    def _render_stages(self):
        """ Renders the stages to the window """

        self._remove_components()
        entries_per_row = 6
        aspect = Globals.native_resolution.y / Globals.native_resolution.x
        entry_width = 235
        entry_height = (entry_width - 20) * aspect + 55

        # Store already processed images
        processed = set()
        index = -1
        # Iterate over all stages
        for stage_tex in self._stages:
            if stage_tex in processed:
                continue
            processed.add(stage_tex)
            index += 1
            stage_name = stage_tex.get_name()

            xoffs = index % entries_per_row
            yoffs = index // entries_per_row
            node = self._content_node.attach_new_node("Preview")
            node.set_sz(-1)
            node.set_pos(10 + xoffs * (entry_width - 14), 1,
                         yoffs * (entry_height - 14 + 10))

            r, g, b = 0.2, 0.2, 0.2
            if isinstance(stage_tex, Image):
                r, g, b = 0.2, 0.4, 0.6

            stage_name = stage_name.replace("render_pipeline_internal:", "")
            parts = stage_name.split(":")
            stage_name = parts[-1]
            DirectFrame(parent=node,
                        frameSize=(7, entry_width - 17, -7,
                                   -entry_height + 17),
                        frameColor=(r, g, b, 1.0),
                        pos=(0, 0, 0))

            frame_hover = DirectFrame(parent=node,
                                      frameSize=(0, entry_width - 10, 0,
                                                 -entry_height + 10),
                                      frameColor=(0, 0, 0, 0),
                                      pos=(0, 0, 0),
                                      state=DGG.NORMAL)
            frame_hover.bind(DGG.ENTER,
                             partial(self._on_texture_hovered, frame_hover))
            frame_hover.bind(DGG.EXIT,
                             partial(self._on_texture_blurred, frame_hover))
            frame_hover.bind(DGG.B1PRESS,
                             partial(self._on_texture_clicked, stage_tex))

            Text(text=stage_name,
                 x=15,
                 y=29,
                 parent=node,
                 size=12,
                 color=Vec3(0.8))

            # Scale image so it always fits
            w, h = stage_tex.get_x_size(), stage_tex.get_y_size()
            padd_x, padd_y = 24, 57
            scale_x = (entry_width - padd_x) / max(1, w)
            scale_y = (entry_height - padd_y) / max(1, h)
            scale_factor = min(scale_x, scale_y)

            if stage_tex.get_texture_type() == Image.TT_buffer_texture:
                scale_factor = 1
                w = entry_width - padd_x
                h = entry_height - padd_y

            preview = Sprite(image=stage_tex,
                             w=scale_factor * w,
                             h=scale_factor * h,
                             any_filter=False,
                             parent=node,
                             x=7,
                             y=40,
                             transparent=False)

            preview.set_shader_input("mipmap", 0)
            preview.set_shader_input("slice", 0)
            preview.set_shader_input("brightness", 1)
            preview.set_shader_input("tonemap", False)

            preview_shader = DisplayShaderBuilder.build(
                stage_tex, scale_factor * w, scale_factor * h)
            preview.set_shader(preview_shader)

        num_rows = (index + entries_per_row) // entries_per_row

        self._set_scroll_height(50 + (entry_height - 14 + 10) * num_rows)
예제 #11
0
class DraggableWindow(DebugObject):

    """ This is a simple draggable but not resizeable window """

    def __init__(self, width=800, height=500, title="Window", parent=None):
        DebugObject.__init__(self, "Window-" + title)
        self._width = width
        self._height = height
        self._title = title
        self._visible = True
        self._parent = parent if parent else Globals.base.pixel2d
        self._context_scale = 1.0 / parent.get_sx()
        self._context_width = Globals.base.win.get_x_size() * self._context_scale
        self._context_height = Globals.base.win.get_y_size() * self._context_scale
        self._pos = Vec2((self._context_width - self._width) / 2, (self._context_height - self._height) / 2)
        self._dragging = False
        self._drag_offset = Vec2(0)

    def set_title(self, title):
        """ Sets the window title """
        self._title = title
        self._window_title.set_text(title)

    def show(self):
        """ Shows the window """
        self._visible = True
        self._node.show()

    def hide(self):
        """ Hides the window """
        self._visible = False
        self._stop_drag()
        self._node.hide()

    def remove(self):
        """ Removes the window from the scene graph. You should still delete the
        instance """
        self._stop_drag()
        self._node.remove_node()

    def _create_components(self):
        """ Creates the window components """
        self._node = self._parent.attach_new_node("Window")
        self._node.set_pos(self._pos.x, 1, -self._pos.y)
        border_px = 1
        self._border_frame = DirectFrame(
            pos=(0, 1, 0),
            frameSize=(-border_px, self._width + border_px, border_px, -self._height - border_px),
            frameColor=(0.0, 0.0, 0.0, 1),
            parent=self._node,
            state=DGG.NORMAL,
        )
        # self._border_frame.hide()
        self._background = DirectFrame(
            pos=(0, 1, 0),
            frameSize=(0, self._width, 0, -self._height),
            frameColor=(0.098, 0.098, 0.098, 1),
            parent=self._node,
        )
        self._title_bar = DirectFrame(
            pos=(0, 1, 0),
            frameSize=(0, self._width, 0, -45),
            frameColor=(0.058, 0.058, 0.058, 1),
            parent=self._node,
            state=DGG.NORMAL,
        )
        self._window_title = BetterOnscreenText(
            parent=self._node, x=12, y=29, text=self._title, size=19, color=Vec3(0.7), may_change=True
        )
        self._btn_close = DirectButton(
            relief=DGG.FLAT,
            pressEffect=1,
            pos=(self._width - 22, 1, -22),
            frameColor=(0, 0, 0, 0),
            scale=(20, 1, 20),
            parent=self._node,
            image="Data/GUI/CloseWindow.png",
        )

        # Init bindings
        self._btn_close.set_transparency(TransparencyAttrib.M_alpha)
        self._btn_close.bind(DGG.B1CLICK, self._request_close)
        self._btn_close.bind(DGG.WITHIN, self._on_close_btn_hover)
        self._btn_close.bind(DGG.WITHOUT, self._on_close_btn_out)
        self._title_bar.bind(DGG.B1PRESS, self._start_drag)
        self._title_bar.bind(DGG.B1RELEASE, self._stop_drag)

    def _start_drag(self, evt=None):
        """ Gets called when the user starts dragging the window """
        self._dragging = True
        self._node.detach_node()
        self._node.reparent_to(self._parent)
        Globals.base.taskMgr.add(self._on_tick, "UIWindowDrag", uponDeath=self._stop_drag)
        self._drag_offset = self._pos - self._get_mouse_pos()

    def _on_close_btn_hover(self, evt=None):
        """ Internal method when the close button got hovered """
        self._btn_close["frameColor"] = (1.0, 0.2, 0.2, 1.0)

    def _on_close_btn_out(self, evt=None):
        """ Internal method when the close button is no longer hovered """
        self._btn_close["frameColor"] = (0, 0, 0, 0)

    def _request_close(self, evt=None):
        """ This method gets called when the close button gets clicked """
        self.hide()

    def _stop_drag(self, evt=None):
        """ Gets called when the user stops dragging the window """
        Globals.base.taskMgr.remove("UIWindowDrag")
        self._dragging = False

    def _get_mouse_pos(self):
        """ Internal helper function to get the mouse position, scaled by
        the context scale """
        mouse_x, mouse_y = (Globals.base.win.get_pointer(0).x, Globals.base.win.get_pointer(0).y)
        return Vec2(mouse_x, mouse_y) * self._context_scale

    def _set_pos(self, pos):
        """ Moves the window to the specified position """
        self._pos = pos
        self._pos.x = max(self._pos.x, -self._width + 100)
        self._pos.y = max(self._pos.y, 25)
        self._pos.x = min(self._pos.x, self._context_width - 100)
        self._pos.y = min(self._pos.y, self._context_height - 50)
        self._node.set_pos(self._pos.x, 1, -self._pos.y)

    def _on_tick(self, task):
        """ Task which updates the window while being dragged """
        self._set_pos(self._get_mouse_pos() + self._drag_offset)
        return task.cont
class CanvasPanel():
    def __init__(self, parent):
        self.parent = parent
        self.elementHandler = None

        color = (
            (0.8, 0.8, 0.8, 1), # Normal
            (0.9, 0.9, 1, 1), # Click
            (0.8, 0.8, 1, 1), # Hover
            (0.5, 0.5, 0.5, 1)) # Disabled
        # respect menu bar

        self.canvasScale = 1080 # min(base.getSize()[0], base.getSize()[1])

        # we default to a 1920x1080 FHD screen
        self.canvasLeft = -1920/2
        self.canvasRight = 1920/2
        self.canvasTop = 1080/2
        self.canvasBottom = -1080/2

        self.visualEditor = DirectScrolledFrame(
            frameColor=(0.25, 0.25, 0.25, 1),
            canvasSize=(self.canvasLeft, self.canvasRight, self.canvasBottom, self.canvasTop),
            scrollBarWidth=20,

            # vertical scrollbar
            verticalScroll_value=0.5,
            verticalScroll_thumb_relief=DGG.FLAT,
            verticalScroll_incButton_relief=DGG.FLAT,
            verticalScroll_decButton_relief=DGG.FLAT,
            verticalScroll_thumb_frameColor=color,
            verticalScroll_incButton_frameColor=color,
            verticalScroll_decButton_frameColor=color,

            # horizontal scrollbar
            horizontalScroll_value=0.5,
            horizontalScroll_thumb_relief=DGG.FLAT,
            horizontalScroll_incButton_relief=DGG.FLAT,
            horizontalScroll_decButton_relief=DGG.FLAT,
            horizontalScroll_thumb_frameColor=color,
            horizontalScroll_incButton_frameColor=color,
            horizontalScroll_decButton_frameColor=color,
            )

        self.scaleParent = DirectFrame(
            scale=(1,1,1)
            )

        # store which base parent should be used for the elements
        self.currentVisEditorParent = base.aspect2d
        self.visEditorInAspect2D = True

        # Layouting
        self.sizer = DirectAutoSizer(
            updateOnWindowResize=False,
            parent=parent,
            child=self.visualEditor,
            )

        # zoom scale
        self.minScale = DEFAULT_MIN_SCALE
        self.maxScale = DEFAULT_MAX_SCALE
        self.zoomInMultiplyer = 1.1
        self.zoomOutMultiplyer = 0.9

        # This frame will be the base parent for the added GUI elements
        self.elementHolder = DirectFrame(
            #frameColor=(0.25, 0.25, 0.25, 1),
            scale=LVecBase3f(self.canvasScale/2,1,self.canvasScale/2),
            parent=self.scaleParent
            )
        self.elementHolder.bind(DGG.B1RELEASE, base.messenger.send, ["mouse3"])
        # Ensure the holder frame will be streched to fill the parent
        self.scaleParentSizer = DirectAutoSizer(
            parent=self.visualEditor.canvas,
            child=self.scaleParent,
            parentGetSizeFunction=self.visualEditor.cget,
            parentGetSizeExtraArgs=["canvasSize"],
            )

        self.elementHolderSizer = DirectAutoSizer(
            parent=self.scaleParent,
            child=self.elementHolder
            )

        # The designers grid
        self.grid = DirectGrid(gridSize=50.0, gridSpacing=0.05,parent=self.elementHolder)
        self.grid.setP(90)
        self.grid.snapMarker.hide()
        self.snapToGrid = not self.grid.isHidden()

        self.canvasTopCenter = self.elementHolder.attachNewNode("canvasTopCenter")
        self.canvasBottomCenter = self.elementHolder.attachNewNode("canvasBottomCenter")
        self.canvasLeftCenter = self.elementHolder.attachNewNode("canvasLeftCenter")
        self.canvasRightCenter = self.elementHolder.attachNewNode("canvasRightCenter")

        self.canvasTopLeft = self.elementHolder.attachNewNode("canvasTopLeft")
        self.canvasTopRight = self.elementHolder.attachNewNode("canvasTopRight")
        self.canvasBottomLeft = self.elementHolder.attachNewNode("canvasBottomLeft")
        self.canvasBottomRight = self.elementHolder.attachNewNode("canvasBottomRight")

        # default to Aspect2D
        self.setVisualEditorParent(False)

        base.taskMgr.add(self.watchCanvasProps, "watch-canvas-properties", sort=50, priority=0)

    def getEditorCanvasSize(self):
        cs = self.elementHolder["frameSize"]

        if self.currentVisEditorParent == base.pixel2d:
            cs = self.visualEditor["canvasSize"]

        return cs

    def getEditorRootCanvas(self):
        return self.elementHolder

    def watchCanvasProps(self, task):
        """Watch for all properties that can be changed on the canvas and won't
        directly propagate down to the actual background, which is the element
        holder."""

        self.sizer.refresh()

        sizeChanged = False
        cs = self.getEditorCanvasSize()
        if self.canvasLeft != cs[0]:
            sizeChanged = True
        elif self.canvasRight != cs[1]:
            sizeChanged = True
        elif self.canvasBottom != cs[2]:
            sizeChanged = True
        elif self.canvasTop != cs[3]:
            sizeChanged = True

        if sizeChanged:
            width = cs[1] - cs[0]
            height = cs[3] - cs[2]

            self.canvasScale = min(width, height)

            if self.currentVisEditorParent == base.pixel2d:
                if width > height:
                    self.canvasScale *= self.visualEditor.getScale()[2]
                else:
                    self.canvasScale *= self.visualEditor.getScale()[0]
            else:
                if width > height:
                    self.canvasScale *= self.elementHolder.getScale()[2]
                else:
                    self.canvasScale *= self.elementHolder.getScale()[0]

            #TODO: the scale probably needs to be calculated dependent on the users screen size
            self.elementHolder["scale"]= LVecBase3f(self.canvasScale/2,1,self.canvasScale/2),

            self.elementHolderSizer.refresh()
            self.scaleParentSizer.refresh()
            self.setCanvasPlacers()

        if self.visualEditor["frameColor"] != self.elementHolder["frameColor"]:
            fc = self.visualEditor["frameColor"]
            self.elementHolder["frameColor"] = fc
            self.elementHolderSizer["frameColor"] = fc
            self.scaleParentSizer["frameColor"] = fc
            self.scaleParent["frameColor"] = fc
        self.visualEditor

        return task.cont

    def setCanvasPlacers(self):
        cs = self.getEditorCanvasSize()
        self.canvasLeft = cs[0]
        self.canvasRight = cs[1]
        self.canvasBottom = cs[2]
        self.canvasTop = cs[3]

        # Put the nodes in their places
        self.canvasTopCenter.setPos(0, 0, self.canvasTop)
        self.canvasBottomCenter.setPos(0, 0, self.canvasBottom)
        self.canvasLeftCenter.setPos(self.canvasLeft, 0, 0)
        self.canvasRightCenter.setPos(self.canvasRight, 0, 0)

        self.canvasTopLeft.setPos(self.canvasLeft, 0, self.canvasTop)
        self.canvasTopRight.setPos(self.canvasRight, 0, self.canvasTop)
        self.canvasBottomLeft.setPos(self.canvasLeft, 0, self.canvasBottom)
        self.canvasBottomRight.setPos(self.canvasRight, 0, self.canvasBottom)

    def getEditorPlacer(self, placerName):
        placerName = placerName.lower()
        placerName = placerName.replace("a2d", "canvas")
        if placerName == "canvasTopCenter".lower():
            return self.canvasTopCenter
        elif placerName == "canvasBottomCenter".lower():
            return self.canvasBottomCenter
        elif placerName == "canvasLeftCenter".lower():
            return self.canvasLeftCenter
        elif placerName == "canvasRightCenter".lower():
            return self.canvasRightCenter
        elif placerName == "canvasTopLeft".lower():
            return self.canvasTopLeft
        elif placerName == "canvasTopRight".lower():
            return self.canvasTopRight
        elif placerName == "canvasBottomLeft".lower():
            return self.canvasBottomLeft
        elif placerName == "canvasBottomRight".lower():
            return self.canvasBottomRight

    def setElementHandler(self, elementHandler):
        self.elementHandler = elementHandler

    def setVisualEditorCanvasSize(self, newCanvasSize):
        self.visualEditor["canvasSize"] = newCanvasSize
        self.elementHolderSizer.refresh()
        self.scaleParentSizer.refresh()
        self.setCanvasPlacers()

    def setVisualEditorParent(self, toPixel2D):
        if toPixel2D:
            # change to pixel2d
            # we default to a 1920x1080 FHD screen
            self.canvasLeft = 0
            self.canvasRight = 1920
            self.canvasBottom = -1080
            self.canvasTop = 0

            self.setVisualEditorCanvasSize((self.canvasLeft, self.canvasRight, self.canvasBottom, self.canvasTop))
            self.currentVisEditorParent = base.pixel2d

            # Speed up the setGridSpacing call by setting the size to 1
            self.grid.setGridSize(1)
            self.grid.setGridSpacing(0.05 * (self.canvasScale / 2))
            self.grid.setGridSize(1920*4)
            self.visEditorInAspect2D = False
            if self.elementHandler is not None:
                self.elementHandler.setEditorParentType(self.visEditorInAspect2D)
                self.elementHandler.setEditorCenter((self.visualEditor.getWidth()/2, 0, -self.visualEditor.getHeight()/2))
        else:
            # change to aspect2d
            # we default to a 1920x1080 FHD screen
            self.canvasLeft = -1920/2
            self.canvasRight = 1920/2
            self.canvasTop = 1080/2
            self.canvasBottom = -1080/2

            self.scaleParent.setScale(1, 1, 1)

            self.setVisualEditorCanvasSize((self.canvasLeft, self.canvasRight, self.canvasBottom, self.canvasTop))
            self.currentVisEditorParent = base.aspect2d

            # Speed up the setGridSpacing call by setting the size to 1
            self.grid.setGridSize(1)
            self.grid.setGridSpacing(0.05)
            self.grid.setGridSize(50)
            self.visEditorInAspect2D = True
            if self.elementHandler is not None:
                self.elementHandler.setEditorParentType(self.visEditorInAspect2D)
                self.elementHandler.setEditorCenter((0, 0, 0))

        # reset the zoom value
        self.resetZoom()

        self.setCanvasPlacers()

    def toggleVisualEditorParent(self):
        if self.currentVisEditorParent == base.aspect2d:
            self.setVisualEditorParent(True)
        elif self.currentVisEditorParent != base.aspect2d:
            self.setVisualEditorParent(False)

    def resizeFrame(self):
        self.sizer.refresh()

    def toggleGrid(self, enable):
        if enable:
            self.grid.show()
            self.snapToGrid = True
        else:
            self.grid.hide()
            self.snapToGrid = False

    def resetZoom(self):
        self.visualEditor["verticalScroll_range"] = (0, 1)
        self.visualEditor["horizontalScroll_range"] = (0, 1)
        if self.currentVisEditorParent != base.aspect2d:
            # we are in pixel2d
            self.getEditorRootCanvas().setScale(1,1,1)
            self.visualEditor.verticalScroll["value"] = 0
            self.visualEditor.horizontalScroll["value"] = 0

            posParentScaleX = DGH.getRealWidth(self.parent)
            self.minScale = DEFAULT_MIN_SCALE
            self.maxScale = DEFAULT_MAX_SCALE
            base.messenger.send("setZoomValeMinMax", [self.minScale, self.maxScale])
            base.messenger.send("setZoomValue", [1])
        else:
            # we are in aspect2d
            self.getEditorRootCanvas().setScale(self.canvasScale/2,1,self.canvasScale/2)
            self.visualEditor.verticalScroll["value"] = 0.5
            self.visualEditor.horizontalScroll["value"] = 0.5

            posParentScaleX = DGH.getRealWidth(self.parent)
            self.minScale = posParentScaleX * DEFAULT_MIN_SCALE
            self.maxScale = posParentScaleX * DEFAULT_MAX_SCALE
            base.messenger.send("setZoomValeMinMax", [self.minScale, self.maxScale])
            base.messenger.send("setZoomValue", [self.canvasScale/2])

    def setZoom(self, zoomValue):
        z = zoomValue
        s = self.getEditorRootCanvas().getScale()

        self.getEditorRootCanvas().setScale(z, s[1], z)

        # update scroll bars
        vr = self.visualEditor["verticalScroll_range"]
        vv = self.visualEditor.verticalScroll["value"]
        hr = self.visualEditor["horizontalScroll_range"]
        hv = self.visualEditor.horizontalScroll["value"]

        vw = vr[1] - vr[0]
        hw = hr[1] - hr[0]

        curPosVer = vv / vw * 100
        curPosHor = hv / hw * 100

        self.visualEditor["verticalScroll_range"] = (vr[0]*(z/s[0]), vr[1]*(z/s[2]))
        self.visualEditor["horizontalScroll_range"] = (hr[0]*(z/s[0]), hr[1]*(z/s[2]))

        vr = self.visualEditor["verticalScroll_range"]
        hr = self.visualEditor["horizontalScroll_range"]

        self.visualEditor.verticalScroll["value"] = (vr[1] - vr[0]) / 100 * curPosVer
        self.visualEditor.horizontalScroll["value"] = (hr[1] - hr[0]) / 100 * curPosHor

        self.elementHolderSizer.refresh()


    def zoom(self, direction):
        z = 1
        s = self.getEditorRootCanvas().getScale()
        if direction < 0 and self.getEditorRootCanvas().getScale()[0] > self.minScale:
            z = self.zoomOutMultiplyer
        elif direction > 0 and self.getEditorRootCanvas().getScale()[0] < self.maxScale:
            z = self.zoomInMultiplyer

        self.getEditorRootCanvas().setScale(s[0]*z, s[1], s[2]*z)

        base.messenger.send("setZoomValue", [self.getEditorRootCanvas().getScale()[0]])
        #print(self.getEditorRootCanvas().getScale())

        # update scroll bars
        vr = self.visualEditor["verticalScroll_range"]
        vv = self.visualEditor.verticalScroll["value"]
        hr = self.visualEditor["horizontalScroll_range"]
        hv = self.visualEditor.horizontalScroll["value"]

        vw = vr[1] - vr[0]
        hw = hr[1] - hr[0]

        curPosVer = vv / vw * 100
        curPosHor = hv / hw * 100

        self.visualEditor["verticalScroll_range"] = (vr[0]*z, vr[1]*z)
        self.visualEditor["horizontalScroll_range"] = (hr[0]*z, hr[1]*z)

        vr = self.visualEditor["verticalScroll_range"]
        hr = self.visualEditor["horizontalScroll_range"]

        self.visualEditor.verticalScroll["value"] = (vr[1] - vr[0]) / 100 * curPosVer
        self.visualEditor.horizontalScroll["value"] = (hr[1] - hr[0]) / 100 * curPosHor

        self.elementHolderSizer.refresh()

    def dragEditorFrame(self, dragEnabled):
        taskMgr.remove("dragEditorFrameTask")
        mwn = base.mouseWatcherNode
        if dragEnabled:
            t = taskMgr.add(self.dragEditorFrameTask, "dragEditorFrameTask")
            t.vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1])

    def dragEditorFrameTask(self, t):
        mwn = base.mouseWatcherNode
        if mwn.hasMouse():
            vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1])
            moveVec = t.vMouse2render2d - vMouse2render2d
            t.vMouse2render2d = vMouse2render2d
            newValue = self.visualEditor["verticalScroll_value"] - moveVec.getZ()
            if newValue <= 1 and newValue >= 0:
                self.visualEditor["verticalScroll_value"] = newValue
            elif newValue > 1:
                self.visualEditor["verticalScroll_value"] = 1
            elif newValue < 0:
                self.visualEditor["verticalScroll_value"] = 0

            newValue = self.visualEditor["horizontalScroll_value"] + moveVec.getX()
            if newValue <= 1 and newValue >= 0:
                self.visualEditor["horizontalScroll_value"] = newValue
            elif newValue > 1:
                self.visualEditor["horizontalScroll_value"] = 1
            elif newValue < 0:
                self.visualEditor["horizontalScroll_value"] = 0

        return t.cont
예제 #13
0
    def renderBuffers(self):
        self.buffersParent.node().removeAllChildren()

        posX = 0
        posY = 0

        for name in self.bufferOrder:
            target = self.buffers[name]
            for targetType in RenderTargetType.All:
                if not target.hasTarget(targetType):
                    continue
                tex = target.getTexture(targetType)
                sizeStr = str(tex.getXSize()) + " x " + str(tex.getYSize())

                if tex.getZSize() != 1:
                    sizeStr += " x " + str(tex.getZSize())

                node = DirectFrame(
                    parent=self.buffersParent,
                    frameColor=(1, 1, 1, 0.2),
                    frameSize=(-self.innerPadding,
                               self.texWidth + self.innerPadding,
                               -self.texHeight - 30 - self.innerPadding,
                               self.innerPadding + 15),
                    state=DGG.NORMAL)
                node.setPos(
                    20 + posX * (self.texWidth + self.texPadding), 0,
                    -self.paddingTop - 22 - posY *
                    (self.texHeight + self.texPadding + 44))
                node.bind(DGG.ENTER, partial(self.onMouseOver, node))
                node.bind(DGG.EXIT, partial(self.onMouseOut, node))
                node.bind(DGG.B1RELEASE, partial(self.showDetail, tex))

                aspect = tex.getYSize() / float(tex.getXSize())
                computedWidth = self.texWidth
                computedHeight = self.texWidth * aspect

                if computedHeight > self.texHeight:
                    # have to scale tex width instead
                    computedHeight = self.texHeight
                    computedWidth = tex.getXSize() / float(tex.getYSize()) * \
                        self.texHeight

                img = BetterOnscreenImage(image=tex,
                                          parent=node,
                                          x=0,
                                          y=30,
                                          w=computedWidth,
                                          h=computedHeight,
                                          transparent=False,
                                          nearFilter=False,
                                          anyFilter=False)
                txtName = BetterOnscreenText(text=name,
                                             x=0,
                                             y=0,
                                             size=15,
                                             parent=node)
                txtSizeFormat = BetterOnscreenText(text=sizeStr,
                                                   x=0,
                                                   y=20,
                                                   size=15,
                                                   parent=node,
                                                   color=Vec3(0.2))
                txtTarget = BetterOnscreenText(text=str(targetType),
                                               align="right",
                                               x=self.texWidth,
                                               y=20,
                                               size=15,
                                               parent=node,
                                               color=Vec3(0.2))

                posX += 1
                if posX > self.pageSize:
                    posY += 1
                    posX = 0