from direct.showbase.DirectObject import DirectObject from panda3d.core import NodePath from imgui_bundle import imgui, imgui_ctx class PlacePanel(DirectObject): def __init__(self, nodePath: NodePath, active=True): DirectObject.__init__(self) self.nodePath: NodePath = nodePath self.__currentNodePath: NodePath = nodePath self.active = active self.scaleUniform = True scale = self.nodePath.getScale() if scale[0] != scale[1] or \ scale[0] != scale[2] or \ scale[1] != scale[2]: self.scaleUniform = False self.windowPos = None self.accept('imgui-new-frame', self.__draw) def __del__(self): self.ignoreAll() def __draw(self): if not self.active: return if not self.nodePath: # Must've gotten deleted. self.active = False return pos = self.nodePath.getPos() hpr = self.nodePath.getHpr() scale = self.nodePath.getScale() # This is done to silence the "has no color set" warnings. color = (1.0, 1.0, 1.0, 1.0) if self.nodePath.hasColor(): color = self.nodePath.getColor() colorScale = (1.0, 1.0, 1.0, 1.0) if self.nodePath.hasColorScale(): colorScale = self.nodePath.getColorScale() if self.windowPos and (self.nodePath != self.__currentNodePath): imgui.set_next_window_pos(self.windowPos) self.__currentNodePath = self.nodePath with imgui_ctx.begin(f"Node Placer \"{self.nodePath.getName()}\"", True) as (_, windowOpen): if not windowOpen: # Close has been clicked. self.active = False return self.windowPos = imgui.get_window_pos() with imgui_ctx.begin_group(): imgui.text("Position") imgui.push_item_width(50) xChanged, xValue = imgui.drag_float("X", pos[0], v_speed=0.05, format='%.3f') yChanged, yValue = imgui.drag_float("Y", pos[1], v_speed=0.05, format='%.3f') zChanged, zValue = imgui.drag_float("Z", pos[2], v_speed=0.05, format='%.3f') imgui.pop_item_width() if xChanged: self.nodePath.setX(xValue) elif yChanged: self.nodePath.setY(yValue) elif zChanged: self.nodePath.setZ(zValue) imgui.same_line(spacing=20) with imgui_ctx.begin_group(): imgui.text("Orientation") imgui.push_item_width(50) hChanged, hValue = imgui.drag_float("H", hpr[0], v_speed=0.05, format='%.3f') pChanged, pValue = imgui.drag_float("P", hpr[1], v_speed=0.05, format='%.3f') rChanged, rValue = imgui.drag_float("R", hpr[2], v_speed=0.05, format='%.3f') imgui.pop_item_width() if hChanged: self.nodePath.setH(hValue) elif pChanged: self.nodePath.setP(pValue) elif rChanged: self.nodePath.setR(rValue) imgui.same_line(spacing=20) with imgui_ctx.begin_group(): imgui.text("Scaling") imgui.push_item_width(50) sxChanged, sxValue = imgui.drag_float("X##scale", scale[0], v_speed=0.05, format='%.3f') syChanged, syValue = imgui.drag_float("Y##scale", scale[1], v_speed=0.05, format='%.3f') szChanged, szValue = imgui.drag_float("Z##scale", scale[2], v_speed=0.05, format='%.3f') uniformBoxClicked, _ = imgui.checkbox("Uniform Scaling", self.scaleUniform) imgui.pop_item_width() if uniformBoxClicked: self.scaleUniform = not self.scaleUniform if sxChanged: if self.scaleUniform: self.nodePath.setScale(sxValue) else: self.nodePath.setSx(sxValue) elif syChanged: if self.scaleUniform: self.nodePath.setScale(syValue) else: self.nodePath.setSy(syValue) elif szChanged: if self.scaleUniform: self.nodePath.setScale(szValue) else: self.nodePath.setSz(szValue) # Colors colorChanged, newColor = imgui.color_edit4('Color', color, imgui.ColorEditFlags_.float.value) if colorChanged: self.nodePath.setColor(*newColor) colorScaleChanged, newColorScale = imgui.color_edit4('Color Scale', colorScale, imgui.ColorEditFlags_.float.value) if colorScaleChanged: self.nodePath.setColorScale(*newColorScale) imgui.separator() # Copy buttons if imgui.button("Copy setPosHprScale()"): imgui.open_popup("posHprScaleMenu") with imgui_ctx.begin_popup("posHprScaleMenu") as posHprScaleMenuOpened: if posHprScaleMenuOpened: for string in ( f".setPosHpr(({pos[0]:.2f}, {pos[1]:.2f}, {pos[2]:.2f}), ({hpr[0]:.2f}, {hpr[1]:.2f}, {hpr[2]:.2f}))", f".setPosHprScale(({pos[0]:.2f}, {pos[1]:.2f}, {pos[2]:.2f}), ({hpr[0]:.2f}, {hpr[1]:.2f}, {hpr[2]:.2f}), ({scale[0]:.2f}, {scale[1]:.2f}, {scale[2]:.2f}))", "", f".setPos(({pos[0]:.2f}, {pos[1]:.2f}, {pos[2]:.2f}))", f".setHpr(({hpr[0]:.2f}, {hpr[1]:.2f}, {hpr[2]:.2f}))", f".setScale(({scale[0]:.2f}, {scale[1]:.2f}, {scale[2]:.2f}))", "", f".setX({pos[0]:.2f})", f".setY({pos[1]:.2f})", f".setZ({pos[2]:.2f})", "", f".setH({hpr[0]:.2f})", f".setP({hpr[1]:.2f})", f".setR({hpr[2]:.2f})", "", f".setSx({scale[0]:.2f})", f".setSy({scale[1]:.2f})", f".setSz({scale[2]:.2f})", "", f".posHprInterval(1, ({pos[0]:.2f}, {pos[1]:.2f}, {pos[2]:.2f}), ({hpr[0]:.2f}, {hpr[1]:.2f}, {hpr[2]:.2f}), blendType='easeInOut'),", f".scaleInterval(1, ({scale[0]:.2f}, {scale[1]:.2f}, {scale[2]:.2f}), blendType='easeInOut'),", f".posHprScaleInterval(1, ({pos[0]:.2f}, {pos[1]:.2f}, {pos[2]:.2f}), ({hpr[0]:.2f}, {hpr[1]:.2f}, {hpr[2]:.2f}), ({scale[0]:.2f}, {scale[1]:.2f}, {scale[2]:.2f}), blendType='easeInOut'),", "", f"Func(node.setScale, ({scale[0]:.2f}, {scale[1]:.2f}, {scale[2]:.2f})),", f"Func(node.setPosHpr, ({pos[0]:.2f}, {pos[1]:.2f}, {pos[2]:.2f}), ({hpr[0]:.2f}, {hpr[1]:.2f}, {hpr[2]:.2f})),", f"Func(node.setPosHprScale, ({pos[0]:.2f}, {pos[1]:.2f}, {pos[2]:.2f}), ({hpr[0]:.2f}, {hpr[1]:.2f}, {hpr[2]:.2f}), ({scale[0]:.2f}, {scale[1]:.2f}, {scale[2]:.2f})),", ): if not string: imgui.separator() continue clicked, _ = imgui.menu_item(string, "", False) if clicked: imgui.set_clipboard_text(string) imgui.close_current_popup() imgui.same_line(spacing=20) if imgui.button("Copy setColor()"): imgui.open_popup("colorMenu") with imgui_ctx.begin_popup("colorMenu") as colorMenuOpened: if colorMenuOpened: for string in ( f".setColor(({colorScale[0]:.2f}, {color[1]:.2f}, {color[2]:.2f}))", "", f".colorInterval(1, ({color[0]:.2f}, {color[1]:.2f}, {color[2]:.2f}), blendType='easeInOut'),", "", f"Func(node.setColor, ({color[0]:.2f}, {color[1]:.2f}, {color[2]:.2f}))," ): if not string: imgui.separator() continue clicked, _ = imgui.menu_item(string, "", False) if clicked: imgui.set_clipboard_text(string) imgui.close_current_popup() imgui.same_line(spacing=20) if imgui.button("Copy setColorScale()"): imgui.open_popup("colorScaleMenu") with imgui_ctx.begin_popup("colorScaleMenu") as colorScaleMenuOpened: if colorScaleMenuOpened: for string in ( f".setColorScale(({colorScale[0]:.2f}, {colorScale[1]:.2f}, {colorScale[2]:.2f}))", "", f".colorScaleInterval(1, ({colorScale[0]:.2f}, {colorScale[1]:.2f}, {colorScale[2]:.2f}), blendType='easeInOut'),", "", f"Func(node.setColorScale, ({colorScale[0]:.2f}, {colorScale[1]:.2f}, {colorScale[2]:.2f}))," ): if not string: imgui.separator() continue clicked, _ = imgui.menu_item(string, "", False) if clicked: imgui.set_clipboard_text(string) imgui.close_current_popup()