CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-imgui

Cython-based Python bindings for dear imgui - a bloat-free immediate mode graphical user interface library

Pending
Overview
Eval results
Files

drawing.mddocs/

Drawing and Graphics

Low-level drawing capabilities for custom graphics, shapes, text rendering, and advanced visual effects using draw lists. The drawing system provides direct access to ImGui's rendering pipeline for creating custom visualizations and graphics.

Capabilities

Draw List Access

Functions to obtain draw list objects for different rendering layers.

def get_window_draw_list():
    """Get draw list for current window (most common)."""

def get_background_draw_list():
    """Get background draw list (renders behind all windows)."""

def get_foreground_draw_list():
    """Get foreground draw list (renders in front of all windows)."""

Clipping and Scissoring

Functions to control rendering regions and clipping rectangles.

def push_clip_rect(clip_rect_min_x: float, clip_rect_min_y: float, clip_rect_max_x: float, clip_rect_max_y: float, intersect_with_current_clip_rect: bool) -> None:
    """Push clip rectangle onto stack."""

def pop_clip_rect() -> None:
    """Pop clip rectangle from stack."""

Item Rectangle Queries

Functions to query bounding rectangles of the last drawn item.

def get_item_rect_min() -> tuple[float, float]:
    """Get minimum point of last item's bounding rectangle."""

def get_item_rect_max() -> tuple[float, float]:
    """Get maximum point of last item's bounding rectangle."""

def get_item_rect_size() -> tuple[float, float]:
    """Get size of last item's bounding rectangle."""

def set_item_allow_overlap() -> None:
    """Allow last item to be overlapped by subsequent items."""

def is_rect_visible(width: float, height: float) -> bool:
    """Test if rectangle of given size is visible."""

Draw List Methods

Methods available on draw list objects for drawing primitives.

class _DrawList:
    """ImGui draw list for custom rendering."""
    
    def add_line(self, p1: tuple[float, float], p2: tuple[float, float], color: int, thickness: float = 1.0) -> None:
        """Draw a line between two points."""
    
    def add_rect(self, p_min: tuple[float, float], p_max: tuple[float, float], color: int, rounding: float = 0.0, flags: int = 0, thickness: float = 1.0) -> None:
        """Draw a rectangle outline."""
    
    def add_rect_filled(self, p_min: tuple[float, float], p_max: tuple[float, float], color: int, rounding: float = 0.0, flags: int = 0) -> None:
        """Draw a filled rectangle."""
    
    def add_quad(self, p1: tuple[float, float], p2: tuple[float, float], p3: tuple[float, float], p4: tuple[float, float], color: int, thickness: float = 1.0) -> None:
        """Draw a quadrilateral outline."""
    
    def add_quad_filled(self, p1: tuple[float, float], p2: tuple[float, float], p3: tuple[float, float], p4: tuple[float, float], color: int) -> None:
        """Draw a filled quadrilateral."""
    
    def add_triangle(self, p1: tuple[float, float], p2: tuple[float, float], p3: tuple[float, float], color: int, thickness: float = 1.0) -> None:
        """Draw a triangle outline."""
    
    def add_triangle_filled(self, p1: tuple[float, float], p2: tuple[float, float], p3: tuple[float, float], color: int) -> None:
        """Draw a filled triangle."""
    
    def add_circle(self, center: tuple[float, float], radius: float, color: int, num_segments: int = 0, thickness: float = 1.0) -> None:
        """Draw a circle outline."""
    
    def add_circle_filled(self, center: tuple[float, float], radius: float, color: int, num_segments: int = 0) -> None:
        """Draw a filled circle."""
    
    def add_ngon(self, center: tuple[float, float], radius: float, color: int, num_segments: int, thickness: float = 1.0) -> None:
        """Draw a regular N-gon outline."""
    
    def add_ngon_filled(self, center: tuple[float, float], radius: float, color: int, num_segments: int) -> None:
        """Draw a filled regular N-gon."""
    
    def add_text(self, pos: tuple[float, float], color: int, text: str) -> None:
        """Draw text at specified position."""
    
    def add_polyline(self, points: list[tuple[float, float]], color: int, flags: int, thickness: float) -> None:
        """Draw a polyline (connected line segments)."""
    
    def add_convex_poly_filled(self, points: list[tuple[float, float]], color: int) -> None:
        """Draw a filled convex polygon."""
    
    def add_bezier_cubic(self, p1: tuple[float, float], p2: tuple[float, float], p3: tuple[float, float], p4: tuple[float, float], color: int, thickness: float, num_segments: int = 0) -> None:
        """Draw a cubic Bezier curve."""
    
    def add_bezier_quadratic(self, p1: tuple[float, float], p2: tuple[float, float], p3: tuple[float, float], color: int, thickness: float, num_segments: int = 0) -> None:
        """Draw a quadratic Bezier curve."""
    
    def add_image(self, texture_id: int, p_min: tuple[float, float], p_max: tuple[float, float], uv_min: tuple[float, float] = (0, 0), uv_max: tuple[float, float] = (1, 1), color: int = 0xFFFFFFFF) -> None:
        """Draw a textured rectangle."""
    
    def add_image_quad(self, texture_id: int, p1: tuple[float, float], p2: tuple[float, float], p3: tuple[float, float], p4: tuple[float, float], uv1: tuple[float, float] = (0, 0), uv2: tuple[float, float] = (1, 0), uv3: tuple[float, float] = (1, 1), uv4: tuple[float, float] = (0, 1), color: int = 0xFFFFFFFF) -> None:
        """Draw a textured quadrilateral."""
    
    def add_image_rounded(self, texture_id: int, p_min: tuple[float, float], p_max: tuple[float, float], uv_min: tuple[float, float], uv_max: tuple[float, float], color: int, rounding: float, flags: int = 0) -> None:
        """Draw a textured rectangle with rounded corners."""
    
    def path_clear(self) -> None:
        """Clear the current path."""
    
    def path_line_to(self, pos: tuple[float, float]) -> None:
        """Add a point to the current path."""
    
    def path_line_to_merge_duplicate(self, pos: tuple[float, float]) -> None:
        """Add a point to path, merging if duplicate."""
    
    def path_fill_convex(self, color: int) -> None:
        """Fill the current path as a convex shape."""
    
    def path_stroke(self, color: int, flags: int, thickness: float) -> None:
        """Stroke the current path with specified color and thickness."""

Color Utility Functions

Functions for color format conversion and manipulation.

def color_convert_u32_to_float4(color_u32: int) -> tuple[float, float, float, float]:
    """Convert U32 color to float4 RGBA."""

def color_convert_float4_to_u32(r: float, g: float, b: float, a: float) -> int:
    """Convert float4 RGBA to U32 color."""

def color_convert_rgb_to_hsv(r: float, g: float, b: float) -> tuple[float, float, float]:
    """Convert RGB to HSV color space."""

def color_convert_hsv_to_rgb(h: float, s: float, v: float) -> tuple[float, float, float]:
    """Convert HSV to RGB color space."""

def get_color_u32_idx(idx: int, alpha_mul: float = 1.0) -> int:
    """Get U32 color by style color index."""

def get_color_u32_rgba(r: float, g: float, b: float, a: float) -> int:
    """Get U32 color from RGBA float values."""

def get_color_u32(color: tuple[float, float, float, float]) -> int:
    """Get U32 color from RGBA tuple."""

Drawing Flags

Constants for controlling drawing behavior.

# Basic drawing flags
DRAW_NONE: int
DRAW_CLOSED: int                 # Connect last and first points

# Corner rounding flags
DRAW_ROUND_CORNERS_TOP_LEFT: int
DRAW_ROUND_CORNERS_TOP_RIGHT: int
DRAW_ROUND_CORNERS_BOTTOM_LEFT: int
DRAW_ROUND_CORNERS_BOTTOM_RIGHT: int
DRAW_ROUND_CORNERS_NONE: int     # Disable rounding on all corners
DRAW_ROUND_CORNERS_TOP: int      # Top left + top right
DRAW_ROUND_CORNERS_BOTTOM: int   # Bottom left + bottom right
DRAW_ROUND_CORNERS_LEFT: int     # Top left + bottom left
DRAW_ROUND_CORNERS_RIGHT: int    # Top right + bottom right
DRAW_ROUND_CORNERS_ALL: int      # All corners

# Draw list flags
DRAW_LIST_NONE: int
DRAW_LIST_ANTI_ALIASED_LINES: int
DRAW_LIST_ANTI_ALIASED_LINES_USE_TEX: int
DRAW_LIST_ANTI_ALIASED_FILL: int
DRAW_LIST_ALLOW_VTX_OFFSET: int

Usage Examples

Basic Shape Drawing

import imgui

# Get draw list for current window
draw_list = imgui.get_window_draw_list()

# Get current cursor position as starting point
cursor_pos = imgui.get_cursor_screen_pos()
canvas_pos = cursor_pos
canvas_size = (200, 200)

# Reserve space for drawing
imgui.dummy(*canvas_size)

# Colors
white = imgui.get_color_u32_rgba(1.0, 1.0, 1.0, 1.0)
red = imgui.get_color_u32_rgba(1.0, 0.0, 0.0, 1.0)
green = imgui.get_color_u32_rgba(0.0, 1.0, 0.0, 1.0)
blue = imgui.get_color_u32_rgba(0.0, 0.0, 1.0, 1.0)

# Draw rectangle
draw_list.add_rect(
    (canvas_pos[0] + 10, canvas_pos[1] + 10),
    (canvas_pos[0] + 60, canvas_pos[1] + 60),
    red, 0.0, 0, 2.0
)

# Draw filled rectangle
draw_list.add_rect_filled(
    (canvas_pos[0] + 70, canvas_pos[1] + 10),
    (canvas_pos[0] + 120, canvas_pos[1] + 60),
    green
)

# Draw circle
draw_list.add_circle(
    (canvas_pos[0] + 50, canvas_pos[1] + 100),
    30, blue, 0, 2.0
)

# Draw filled circle
draw_list.add_circle_filled(
    (canvas_pos[0] + 120, canvas_pos[1] + 100),
    25, red
)

Interactive Drawing Canvas

# Interactive drawing example
drawing_canvas_size = (400, 300)
canvas_pos = imgui.get_cursor_screen_pos()

# Reserve space for canvas
imgui.invisible_button("canvas", *drawing_canvas_size)
draw_list = imgui.get_window_draw_list()

# Draw canvas background
canvas_color = imgui.get_color_u32_rgba(0.1, 0.1, 0.1, 1.0)
draw_list.add_rect_filled(
    canvas_pos,
    (canvas_pos[0] + drawing_canvas_size[0], canvas_pos[1] + drawing_canvas_size[1]),
    canvas_color
)

# Handle mouse drawing
if imgui.is_item_hovered() and imgui.is_mouse_down(0):
    mouse_pos = imgui.get_mouse_pos()
    # Check if mouse is within canvas bounds
    if (canvas_pos[0] <= mouse_pos[0] <= canvas_pos[0] + drawing_canvas_size[0] and
        canvas_pos[1] <= mouse_pos[1] <= canvas_pos[1] + drawing_canvas_size[1]):
        
        # Draw at mouse position
        brush_color = imgui.get_color_u32_rgba(1.0, 1.0, 1.0, 1.0)
        draw_list.add_circle_filled(mouse_pos, 3, brush_color)

# Canvas border
border_color = imgui.get_color_u32_rgba(0.5, 0.5, 0.5, 1.0)
draw_list.add_rect(
    canvas_pos,
    (canvas_pos[0] + drawing_canvas_size[0], canvas_pos[1] + drawing_canvas_size[1]),
    border_color
)

Complex Shape Drawing

# Draw complex shapes
draw_list = imgui.get_window_draw_list()
start_pos = imgui.get_cursor_screen_pos()

# Draw a star shape using path
draw_list.path_clear()
center = (start_pos[0] + 100, start_pos[1] + 100)
outer_radius = 50
inner_radius = 25
num_points = 5

import math

for i in range(num_points * 2):
    angle = i * math.pi / num_points
    radius = outer_radius if i % 2 == 0 else inner_radius
    x = center[0] + radius * math.cos(angle)
    y = center[1] + radius * math.sin(angle)
    draw_list.path_line_to((x, y))

# Fill the star
star_color = imgui.get_color_u32_rgba(1.0, 1.0, 0.0, 1.0)
draw_list.path_fill_convex(star_color)

# Reserve space
imgui.dummy(200, 200)

Bezier Curves and Advanced Shapes

# Draw Bezier curves
draw_list = imgui.get_window_draw_list()
start_pos = imgui.get_cursor_screen_pos()

# Cubic Bezier curve
p1 = (start_pos[0] + 20, start_pos[1] + 100)
p2 = (start_pos[0] + 60, start_pos[1] + 20)
p3 = (start_pos[0] + 140, start_pos[1] + 180)
p4 = (start_pos[0] + 180, start_pos[1] + 100)

curve_color = imgui.get_color_u32_rgba(0.0, 1.0, 1.0, 1.0)
draw_list.add_bezier_cubic(p1, p2, p3, p4, curve_color, 2.0)

# Draw control points
point_color = imgui.get_color_u32_rgba(1.0, 0.0, 0.0, 1.0)
for point in [p1, p2, p3, p4]:
    draw_list.add_circle_filled(point, 3, point_color)

# Quadratic Bezier
q1 = (start_pos[0] + 220, start_pos[1] + 100)
q2 = (start_pos[0] + 260, start_pos[1] + 40)
q3 = (start_pos[0] + 300, start_pos[1] + 100)

draw_list.add_bezier_quadratic(q1, q2, q3, curve_color, 2.0)

imgui.dummy(320, 200)

Text and Advanced Drawing

# Custom text rendering and graphics
draw_list = imgui.get_window_draw_list()
pos = imgui.get_cursor_screen_pos()

# Draw text with custom positioning
text_color = imgui.get_color_u32_rgba(1.0, 1.0, 1.0, 1.0)
draw_list.add_text((pos[0] + 10, pos[1] + 10), text_color, "Custom Text")

# Draw a gradient-like effect using multiple rectangles
gradient_width = 200
gradient_height = 50

for i in range(gradient_width):
    alpha = i / gradient_width
    color = imgui.get_color_u32_rgba(alpha, 0.5, 1.0 - alpha, 1.0)
    draw_list.add_line(
        (pos[0] + i, pos[1] + 40),
        (pos[0] + i, pos[1] + 40 + gradient_height),
        color, 1.0
    )

imgui.dummy(220, 100)

Background and Foreground Drawing

# Draw on background layer (behind all windows)
bg_draw_list = imgui.get_background_draw_list()
screen_size = imgui.get_main_viewport().size

# Draw grid pattern on background
grid_color = imgui.get_color_u32_rgba(0.2, 0.2, 0.2, 0.5)
grid_size = 50

for x in range(0, int(screen_size[0]), grid_size):
    bg_draw_list.add_line((x, 0), (x, screen_size[1]), grid_color)

for y in range(0, int(screen_size[1]), grid_size):
    bg_draw_list.add_line((0, y), (screen_size[0], y), grid_color)

# Draw on foreground layer (in front of all windows)
fg_draw_list = imgui.get_foreground_draw_list()
mouse_pos = imgui.get_mouse_pos()

# Draw crosshair at mouse position
crosshair_color = imgui.get_color_u32_rgba(1.0, 0.0, 0.0, 0.8)
crosshair_size = 20

fg_draw_list.add_line(
    (mouse_pos[0] - crosshair_size, mouse_pos[1]),
    (mouse_pos[0] + crosshair_size, mouse_pos[1]),
    crosshair_color, 2.0
)
fg_draw_list.add_line(
    (mouse_pos[0], mouse_pos[1] - crosshair_size),
    (mouse_pos[0], mouse_pos[1] + crosshair_size),
    crosshair_color, 2.0
)

Clipping and Masking

# Drawing with clipping regions
draw_list = imgui.get_window_draw_list()
pos = imgui.get_cursor_screen_pos()

# Set up clipping region
clip_min = (pos[0] + 20, pos[1] + 20)
clip_max = (pos[0] + 180, pos[1] + 180)

draw_list.push_clip_rect(clip_min[0], clip_min[1], clip_max[0], clip_max[1], True)

# Draw shapes that will be clipped
large_circle_color = imgui.get_color_u32_rgba(0.8, 0.2, 0.8, 1.0)
draw_list.add_circle_filled((pos[0] + 100, pos[1] + 100), 80, large_circle_color)

# Draw clipping region border (this won't be clipped)
draw_list.pop_clip_rect()
border_color = imgui.get_color_u32_rgba(1.0, 1.0, 0.0, 1.0)
draw_list.add_rect(clip_min, clip_max, border_color, 0.0, 0, 2.0)

imgui.dummy(200, 200)

Install with Tessl CLI

npx tessl i tessl/pypi-imgui

docs

drawing.md

index.md

input.md

integrations.md

layout.md

menus.md

styling.md

tables.md

tabs.md

widgets.md

windows.md

tile.json