[docs]classBaseGUI:""" Base class for all ImGUI based GUIs, windows and popups The main purpose of this base is for setting a unique ID between multiple figs with identical UI elements This ID can be pushed in subclasses within the `update()` method """ID_COUNTER:int=0def__init__(self):BaseGUI.ID_COUNTER+=1self._id_counter=BaseGUI.ID_COUNTER
[docs]defupdate(self):"""must be implemented in subclass"""raiseNotImplementedError
[docs]classWindow(BaseGUI):"""Base class for imgui windows drawn within Figures"""pass
[docs]classEdgeWindow(Window):def__init__(self,figure:Figure,size:int,location:Literal["top","bottom","left","right"],title:str,window_flags:int=imgui.WindowFlags_.no_collapse|imgui.WindowFlags_.no_resize,*args,**kwargs,):""" A base class for imgui windows displayed at one of the four edges of a Figure Parameters ---------- figure: Figure Figure instance that this window will be placed in size: int width or height of the window, depending on its location location: str, "top" | "bottom" | "left" | "right" location of the window title: str window title window_flags: int window flag enum, valid flags are: .. code-block:: py imgui.WindowFlags_.no_title_bar imgui.WindowFlags_.no_resize imgui.WindowFlags_.no_move imgui.WindowFlags_.no_scrollbar imgui.WindowFlags_.no_scroll_with_mouse imgui.WindowFlags_.no_collapse imgui.WindowFlags_.always_auto_resize imgui.WindowFlags_.no_background imgui.WindowFlags_.no_saved_settings imgui.WindowFlags_.no_mouse_inputs imgui.WindowFlags_.menu_bar imgui.WindowFlags_.horizontal_scrollbar imgui.WindowFlags_.no_focus_on_appearing imgui.WindowFlags_.no_bring_to_front_on_focus imgui.WindowFlags_.always_vertical_scrollbar imgui.WindowFlags_.always_horizontal_scrollbar imgui.WindowFlags_.no_nav_inputs imgui.WindowFlags_.no_nav_focus imgui.WindowFlags_.unsaved_document imgui.WindowFlags_.no_docking imgui.WindowFlags_.no_nav imgui.WindowFlags_.no_decoration imgui.WindowFlags_.no_inputs *args additional args for the GUI **kwargs additional kwargs for teh GUI """super().__init__()iflocationnotinGUI_EDGES:f"GUI does not have a valid location, valid locations are: {GUI_EDGES}, you have passed: {location}"self._figure=figureself._size=sizeself._location=locationself._title=titleself._window_flags=window_flagsself._fa_icons=self._figure._fa_iconsself._x,self._y,self._width,self._height=self.get_rect()self._figure.canvas.add_event_handler(self._set_rect,"resize")@propertydefsize(self)->int|None:"""width or height of the edge window"""returnself._size@size.setterdefsize(self,value):ifnotisinstance(value,int):raiseTypeErrorself._size=value@propertydeflocation(self)->str:"""location of the window"""returnself._location@propertydefx(self)->int:"""canvas x position of the window"""returnself._x@propertydefy(self)->int:"""canvas y position of the window"""returnself._y@propertydefwidth(self)->int:"""with the window"""returnself._width@propertydefheight(self)->int:"""height of the window"""returnself._heightdef_set_rect(self,*args):self._x,self._y,self._width,self._height=self.get_rect()
[docs]defget_rect(self)->tuple[int,int,int,int]:""" Compute the rect that defines the area this GUI is drawn to Returns ------- int, int, int, int x_pos, y_pos, width, height """width_canvas,height_canvas=self._figure.canvas.get_logical_size()matchself._location:case"top":x_pos,y_pos=(0,0)width,height=(width_canvas,self.size)case"bottom":x_pos=0y_pos=height_canvas-self.sizewidth,height=(width_canvas,self.size)case"right":x_pos,y_pos=(width_canvas-self.size,0)ifself._figure.guis["top"]:# if there is a GUI in the top edge, make this one belowy_pos+=self._figure.guis["top"].sizewidth,height=(self.size,height_canvas)ifself._figure.guis["bottom"]isnotNone:height-=self._figure.guis["bottom"].sizecase"left":x_pos,y_pos=(0,0)ifself._figure.guis["top"]:# if there is a GUI in the top edge, make this one belowy_pos+=self._figure.guis["top"].sizewidth,height=(self.size,height_canvas)ifself._figure.guis["bottom"]isnotNone:height-=self._figure.guis["bottom"].sizereturnx_pos,y_pos,width,height
[docs]defdraw_window(self):"""helps simplify using imgui by managing window creation & position, and pushing/popping the ID"""# window position & sizeimgui.set_next_window_size((self.width,self.height))imgui.set_next_window_pos((self.x,self.y))flags=self._window_flags# begin windowimgui.begin(self._title,p_open=None,flags=flags)# push ID to prevent conflict between multiple figs with same UIimgui.push_id(self._id_counter)# draw stuff from subclass into windowself.update()# pop IDimgui.pop_id()# end the windowimgui.end()
[docs]defupdate(self):"""Implement your GUI here and it will be drawn within the window. See the GUI examples"""raiseNotImplementedError
[docs]classPopup(BaseGUI):def__init__(self,figure:Figure,*args,**kwargs):""" Base class for creating ImGUI popups within Figures Parameters ---------- figure: Figure Figure instance *args any args to pass to subclass constructor **kwargs any kwargs to pass to subclass constructor """super().__init__()self._figure=figureself._fa_icons=self._figure._fa_iconsself.is_open=False
[docs]defopen(self,pos:tuple[int,int],*args,**kwargs):"""implement in subclass"""raiseNotImplementedError