11import ctypes , colorsys , time , sdl3 , OpenGL .GL as gl
22
3- if USE_IMGUI_BUNDLE := True :
4- from imgui_bundle .python_backends .opengl_backend import imgui , ProgrammablePipelineRenderer
5- # from imgui_bundle.python_backends.sdl3_backend import imgui, SDL3Renderer
6-
7- else :
8- from imgui .integrations .opengl import imgui , ProgrammablePipelineRenderer
9-
10- class SDL3Renderer (ProgrammablePipelineRenderer ):
11- """Basic SDL3 integration implementation."""
12- MOUSE_WHEEL_OFFSET_SCALE : float = 0.5
13-
14- @staticmethod
15- def setCustomStyle () -> None :
16- style = imgui .get_style ()
17-
18- for key , value in {
19- imgui .Col_ .text .value if USE_IMGUI_BUNDLE else imgui .COLOR_TEXT : (1.00 , 1.00 , 1.00 , 1.00 ),
20- imgui .Col_ .text_disabled .value if USE_IMGUI_BUNDLE else imgui .COLOR_TEXT_DISABLED : (0.50 , 0.50 , 0.50 , 1.00 ),
21- imgui .Col_ .window_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_WINDOW_BACKGROUND : (0.00 , 0.00 , 0.00 , 0.39 ),
22- imgui .Col_ .child_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_CHILD_BACKGROUND : (0.00 , 0.00 , 0.00 , 0.00 ),
23- imgui .Col_ .popup_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_POPUP_BACKGROUND : (0.00 , 0.00 , 0.00 , 0.63 ),
24- imgui .Col_ .border .value if USE_IMGUI_BUNDLE else imgui .COLOR_BORDER : (1.00 , 1.00 , 1.00 , 0.31 ),
25- imgui .Col_ .border_shadow .value if USE_IMGUI_BUNDLE else imgui .COLOR_BORDER_SHADOW : (0.00 , 0.00 , 0.00 , 0.00 ),
26- imgui .Col_ .frame_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_FRAME_BACKGROUND : (0.00 , 0.00 , 0.00 , 0.63 ),
27- imgui .Col_ .frame_bg_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_FRAME_BACKGROUND_HOVERED : (0.23 , 0.23 , 0.23 , 0.63 ),
28- imgui .Col_ .frame_bg_active .value if USE_IMGUI_BUNDLE else imgui .COLOR_FRAME_BACKGROUND_ACTIVE : (0.19 , 0.19 , 0.19 , 0.39 ),
29- imgui .Col_ .title_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_TITLE_BACKGROUND : (0.00 , 0.00 , 0.00 , 0.63 ),
30- imgui .Col_ .title_bg_active .value if USE_IMGUI_BUNDLE else imgui .COLOR_TITLE_BACKGROUND_ACTIVE : (0.00 , 0.00 , 0.00 , 1.00 ),
31- imgui .Col_ .title_bg_collapsed .value if USE_IMGUI_BUNDLE else imgui .COLOR_TITLE_BACKGROUND_COLLAPSED : (0.00 , 0.00 , 0.00 , 0.35 ),
32- imgui .Col_ .menu_bar_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_MENUBAR_BACKGROUND : (0.00 , 0.00 , 0.00 , 0.78 ),
33- imgui .Col_ .scrollbar_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_SCROLLBAR_BACKGROUND : (0.05 , 0.05 , 0.05 , 0.54 ),
34- imgui .Col_ .scrollbar_grab .value if USE_IMGUI_BUNDLE else imgui .COLOR_SCROLLBAR_GRAB : (0.34 , 0.34 , 0.34 , 0.63 ),
35- imgui .Col_ .scrollbar_grab_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_SCROLLBAR_GRAB_HOVERED : (0.50 , 0.50 , 0.50 , 0.63 ),
36- imgui .Col_ .scrollbar_grab_active .value if USE_IMGUI_BUNDLE else imgui .COLOR_SCROLLBAR_GRAB_ACTIVE : (0.38 , 0.38 , 0.38 , 0.63 ),
37- imgui .Col_ .check_mark .value if USE_IMGUI_BUNDLE else imgui .COLOR_CHECK_MARK : (0.22 , 0.55 , 0.74 , 1.00 ),
38- imgui .Col_ .slider_grab .value if USE_IMGUI_BUNDLE else imgui .COLOR_SLIDER_GRAB : (0.34 , 0.34 , 0.34 , 0.54 ),
39- imgui .Col_ .slider_grab_active .value if USE_IMGUI_BUNDLE else imgui .COLOR_SLIDER_GRAB_ACTIVE : (0.56 , 0.56 , 0.56 , 0.54 ),
40- imgui .Col_ .button .value if USE_IMGUI_BUNDLE else imgui .COLOR_BUTTON : (0.00 , 0.00 , 0.00 , 0.63 ),
41- imgui .Col_ .button_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_BUTTON_HOVERED : (0.20 , 0.22 , 0.23 , 0.63 ),
42- imgui .Col_ .button_active .value if USE_IMGUI_BUNDLE else imgui .COLOR_BUTTON_ACTIVE : (0.19 , 0.19 , 0.19 , 0.39 ),
43- imgui .Col_ .header .value if USE_IMGUI_BUNDLE else imgui .COLOR_HEADER : (0.20 , 0.20 , 0.20 , 0.78 ),
44- imgui .Col_ .header_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_HEADER_HOVERED : (0.29 , 0.29 , 0.29 , 0.78 ),
45- imgui .Col_ .header_active .value if USE_IMGUI_BUNDLE else imgui .COLOR_HEADER_ACTIVE : (0.19 , 0.19 , 0.19 , 0.15 ),
46- imgui .Col_ .separator .value if USE_IMGUI_BUNDLE else imgui .COLOR_SEPARATOR : (0.28 , 0.28 , 0.28 , 0.29 ),
47- imgui .Col_ .separator_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_SEPARATOR_HOVERED : (0.44 , 0.44 , 0.44 , 0.29 ),
48- imgui .Col_ .separator_active .value if USE_IMGUI_BUNDLE else imgui .COLOR_SEPARATOR_ACTIVE : (0.40 , 0.44 , 0.47 , 1.00 ),
49- imgui .Col_ .resize_grip .value if USE_IMGUI_BUNDLE else imgui .COLOR_RESIZE_GRIP : (0.28 , 0.28 , 0.28 , 0.29 ),
50- imgui .Col_ .resize_grip_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_RESIZE_GRIP_HOVERED : (0.44 , 0.44 , 0.44 , 0.29 ),
51- imgui .Col_ .resize_grip_active .value if USE_IMGUI_BUNDLE else imgui .COLOR_RESIZE_GRIP_ACTIVE : (0.40 , 0.44 , 0.47 , 1.00 ),
52- imgui .Col_ .tab .value if USE_IMGUI_BUNDLE else imgui .COLOR_TAB : (0.00 , 0.00 , 0.00 , 0.52 ),
53- imgui .Col_ .tab_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_TAB_HOVERED : (0.20 , 0.20 , 0.20 , 0.36 ),
54- imgui .Col_ .tab_selected .value if USE_IMGUI_BUNDLE else imgui .COLOR_TAB_ACTIVE : (0.14 , 0.14 , 0.14 , 1.00 ),
55- imgui .Col_ .tab_dimmed .value if USE_IMGUI_BUNDLE else imgui .COLOR_TAB_UNFOCUSED : (0.00 , 0.00 , 0.00 , 0.52 ),
56- imgui .Col_ .tab_dimmed_selected .value if USE_IMGUI_BUNDLE else imgui .COLOR_TAB_UNFOCUSED_ACTIVE : (0.14 , 0.14 , 0.14 , 1.00 ),
57- imgui .Col_ .plot_lines .value if USE_IMGUI_BUNDLE else imgui .COLOR_PLOT_LINES : (1.00 , 0.00 , 0.00 , 1.00 ),
58- imgui .Col_ .plot_lines_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_PLOT_LINES_HOVERED : (1.00 , 0.00 , 0.00 , 1.00 ),
59- imgui .Col_ .plot_histogram .value if USE_IMGUI_BUNDLE else imgui .COLOR_PLOT_HISTOGRAM : (1.00 , 0.00 , 0.00 , 1.00 ),
60- imgui .Col_ .plot_histogram_hovered .value if USE_IMGUI_BUNDLE else imgui .COLOR_PLOT_HISTOGRAM_HOVERED : (1.00 , 0.00 , 0.00 , 1.00 ),
61- imgui .Col_ .table_header_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_TABLE_HEADER_BACKGROUND : (0.00 , 0.00 , 0.00 , 0.52 ),
62- imgui .Col_ .table_border_strong .value if USE_IMGUI_BUNDLE else imgui .COLOR_TABLE_BORDER_STRONG : (0.00 , 0.00 , 0.00 , 0.52 ),
63- imgui .Col_ .table_border_light .value if USE_IMGUI_BUNDLE else imgui .COLOR_TABLE_BORDER_LIGHT : (0.28 , 0.28 , 0.28 , 0.29 ),
64- imgui .Col_ .table_row_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_TABLE_ROW_BACKGROUND : (0.00 , 0.00 , 0.00 , 0.00 ),
65- imgui .Col_ .table_row_bg_alt .value if USE_IMGUI_BUNDLE else imgui .COLOR_TABLE_ROW_BACKGROUND_ALT : (1.00 , 1.00 , 1.00 , 0.06 ),
66- imgui .Col_ .text_selected_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_TEXT_SELECTED_BACKGROUND : (0.26 , 0.59 , 0.98 , 0.35 ),
67- imgui .Col_ .drag_drop_target .value if USE_IMGUI_BUNDLE else imgui .COLOR_DRAG_DROP_TARGET : (1.00 , 1.00 , 0.00 , 0.90 ),
68- imgui .Col_ .nav_windowing_highlight .value if USE_IMGUI_BUNDLE else imgui .COLOR_NAV_WINDOWING_HIGHLIGHT : (1.00 , 1.00 , 1.00 , 0.70 ),
69- imgui .Col_ .nav_windowing_dim_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_NAV_WINDOWING_DIM_BACKGROUND : (0.80 , 0.80 , 0.80 , 0.20 ),
70- imgui .Col_ .modal_window_dim_bg .value if USE_IMGUI_BUNDLE else imgui .COLOR_MODAL_WINDOW_DIM_BACKGROUND : (0.20 , 0.20 , 0.20 , 0.35 )
71- }.items ():
72- if USE_IMGUI_BUNDLE : style .set_color_ (key , value )
73- else : style .colors [key ] = value
74-
75- style .window_padding , style .frame_padding , style .cell_padding = (6.0 , 6.0 ), (5.0 , 2.0 ), (6.0 , 6.0 )
76- style .item_spacing , style .item_inner_spacing , style .touch_extra_padding = (6.0 , 6.0 ), (6.0 , 6.0 ), (0.0 , 0.0 )
77- style .window_title_align , style .indent_spacing , style .scrollbar_size = (0.5 , 0.5 ), 25.0 , 10.0
78- style .grab_min_size , style .window_border_size , style .child_border_size = 10.0 , 1.0 , 1.0
79- style .popup_border_size , style .frame_border_size , style .tab_border_size = 1.0 , 1.0 , 1.0
80- style .window_rounding , style .child_rounding , style .frame_rounding = 5.0 , 4.0 , 2.0
81- style .popup_rounding , style .scrollbar_rounding , style .grab_rounding = 4.0 , 9.0 , 2.0
82- style .log_slider_deadzone , style .tab_rounding = 4.0 , 4.0
83-
84- def __init__ (self , window : sdl3 .LP_SDL_Window ) -> None :
85- super (SDL3Renderer , self ).__init__ ()
86-
87- self .window = window
88- self .lastTime = sdl3 .SDL_GetTicks () / 1000.0
89- sdl3 .SDL_StartTextInput (window )
90-
91- if not USE_IMGUI_BUNDLE :
92- imgui .get_io ().get_clipboard_text_fn = lambda : sdl3 .SDL_GetClipboardText ().decode ()
93- imgui .get_io ().set_clipboard_text_fn = lambda text : sdl3 .SDL_SetClipboardText (text .encode ())
94-
95- for key , value in {
96- imgui .KEY_TAB : sdl3 .SDL_SCANCODE_TAB , imgui .KEY_LEFT_ARROW : sdl3 .SDL_SCANCODE_LEFT ,
97- imgui .KEY_RIGHT_ARROW : sdl3 .SDL_SCANCODE_RIGHT , imgui .KEY_UP_ARROW : sdl3 .SDL_SCANCODE_UP ,
98- imgui .KEY_DOWN_ARROW : sdl3 .SDL_SCANCODE_DOWN , imgui .KEY_PAGE_UP : sdl3 .SDL_SCANCODE_PAGEUP ,
99- imgui .KEY_PAGE_DOWN : sdl3 .SDL_SCANCODE_PAGEDOWN , imgui .KEY_HOME : sdl3 .SDL_SCANCODE_HOME ,
100- imgui .KEY_END : sdl3 .SDL_SCANCODE_END , imgui .KEY_INSERT : sdl3 .SDL_SCANCODE_INSERT ,
101- imgui .KEY_DELETE : sdl3 .SDL_SCANCODE_DELETE , imgui .KEY_BACKSPACE : sdl3 .SDL_SCANCODE_BACKSPACE ,
102- imgui .KEY_SPACE : sdl3 .SDL_SCANCODE_SPACE , imgui .KEY_ENTER : sdl3 .SDL_SCANCODE_RETURN ,
103- imgui .KEY_ESCAPE : sdl3 .SDL_SCANCODE_ESCAPE , imgui .KEY_PAD_ENTER : sdl3 .SDL_SCANCODE_KP_ENTER ,
104- imgui .KEY_A : sdl3 .SDL_SCANCODE_A , imgui .KEY_C : sdl3 .SDL_SCANCODE_C , imgui .KEY_V : sdl3 .SDL_SCANCODE_V ,
105- imgui .KEY_X : sdl3 .SDL_SCANCODE_X , imgui .KEY_Y : sdl3 .SDL_SCANCODE_Y , imgui .KEY_Z : sdl3 .SDL_SCANCODE_Z
106- }.items (): self .io .key_map [key ] = value
107-
108- else :
109- imgui .get_platform_io ().platform_get_clipboard_text_fn = lambda _ : sdl3 .SDL_GetClipboardText ().decode ()
110- imgui .get_platform_io ().platform_set_clipboard_text_fn = lambda _ , text : sdl3 .SDL_SetClipboardText (text .encode ())
111-
112- self .key_map = {
113- sdl3 .SDL_SCANCODE_TAB : imgui .Key .tab , sdl3 .SDL_SCANCODE_LEFT : imgui .Key .left_arrow ,
114- sdl3 .SDL_SCANCODE_RIGHT : imgui .Key .right_arrow , sdl3 .SDL_SCANCODE_UP : imgui .Key .up_arrow ,
115- sdl3 .SDL_SCANCODE_DOWN : imgui .Key .down_arrow , sdl3 .SDL_SCANCODE_PAGEUP : imgui .Key .page_up ,
116- sdl3 .SDL_SCANCODE_PAGEDOWN : imgui .Key .page_down , sdl3 .SDL_SCANCODE_HOME : imgui .Key .home ,
117- sdl3 .SDL_SCANCODE_END : imgui .Key .end , sdl3 .SDL_SCANCODE_INSERT : imgui .Key .insert ,
118- sdl3 .SDL_SCANCODE_DELETE : imgui .Key .delete , sdl3 .SDL_SCANCODE_BACKSPACE : imgui .Key .backspace ,
119- sdl3 .SDL_SCANCODE_SPACE : imgui .Key .space , sdl3 .SDL_SCANCODE_RETURN : imgui .Key .enter ,
120- sdl3 .SDL_SCANCODE_ESCAPE : imgui .Key .escape , sdl3 .SDL_SCANCODE_KP_ENTER : imgui .Key .keypad_enter ,
121- sdl3 .SDL_SCANCODE_A : imgui .Key .a , sdl3 .SDL_SCANCODE_C : imgui .Key .c , sdl3 .SDL_SCANCODE_V : imgui .Key .v ,
122- sdl3 .SDL_SCANCODE_X : imgui .Key .x , sdl3 .SDL_SCANCODE_Y : imgui .Key .y , sdl3 .SDL_SCANCODE_Z : imgui .Key .z ,
123- sdl3 .SDL_SCANCODE_LCTRL : imgui .Key .mod_ctrl , sdl3 .SDL_SCANCODE_RCTRL : imgui .Key .mod_ctrl ,
124- sdl3 .SDL_SCANCODE_LSHIFT : imgui .Key .mod_shift , sdl3 .SDL_SCANCODE_RSHIFT : imgui .Key .mod_shift ,
125- sdl3 .SDL_SCANCODE_LALT : imgui .Key .mod_alt , sdl3 .SDL_SCANCODE_RALT : imgui .Key .mod_alt ,
126- sdl3 .SDL_SCANCODE_LGUI : imgui .Key .mod_super , sdl3 .SDL_SCANCODE_RGUI : imgui .Key .mod_super
127- }
128-
129- def processEvent (self , event : sdl3 .SDL_Event ) -> bool :
130- if event .type in [sdl3 .SDL_EVENT_MOUSE_WHEEL ]:
131- if not USE_IMGUI_BUNDLE : self .io .mouse_wheel = event .wheel .y * self .MOUSE_WHEEL_OFFSET_SCALE
132- else : self .io .add_mouse_wheel_event (event .wheel .x * self .MOUSE_WHEEL_OFFSET_SCALE , event .wheel .y * self .MOUSE_WHEEL_OFFSET_SCALE )
133-
134- elif event .type in [sdl3 .SDL_EVENT_MOUSE_BUTTON_UP , sdl3 .SDL_EVENT_MOUSE_BUTTON_DOWN ]:
135- buttons = [sdl3 .SDL_BUTTON_LEFT , sdl3 .SDL_BUTTON_RIGHT , sdl3 .SDL_BUTTON_MIDDLE ]
136-
137- if (button := event .button .button ) in buttons :
138- if not USE_IMGUI_BUNDLE : self .io .mouse_down [buttons .index (event .button .button )] = event .type == sdl3 .SDL_EVENT_MOUSE_BUTTON_DOWN
139- else : self .io .add_mouse_button_event (buttons .index (button ), event .type == sdl3 .SDL_EVENT_MOUSE_BUTTON_DOWN )
140-
141- elif event .type in [sdl3 .SDL_EVENT_MOUSE_MOTION ]:
142- self .io .mouse_pos = (event .motion .x , event .motion .y ) \
143- if sdl3 .SDL_GetWindowFlags (self .window ) & sdl3 .SDL_WINDOW_MOUSE_FOCUS else (- 1 , - 1 )
144-
145- elif event .type in [sdl3 .SDL_EVENT_KEY_UP , sdl3 .SDL_EVENT_KEY_DOWN ]:
146- if not USE_IMGUI_BUNDLE :
147- if event .key .scancode < sdl3 .SDL_SCANCODE_COUNT :
148- self .io .keys_down [event .key .scancode ] = event .type == sdl3 .SDL_EVENT_KEY_DOWN
149-
150- if state := sdl3 .SDL_GetModState ():
151- self .io .key_shift = (state & sdl3 .SDL_KMOD_SHIFT ) != 0
152- self .io .key_ctrl = (state & sdl3 .SDL_KMOD_CTRL ) != 0
153- self .io .key_alt = (state & sdl3 .SDL_KMOD_ALT ) != 0
154- self .io .key_super = (state & sdl3 .SDL_KMOD_GUI ) != 0
155-
156- else :
157- if (scancode := event .key .scancode ) in self .key_map :
158- self .io .add_key_event (self .key_map [scancode ], event .type == sdl3 .SDL_EVENT_KEY_DOWN )
159-
160- elif event .type in [sdl3 .SDL_EVENT_TEXT_INPUT ]:
161- for char in event .text .text .decode ("utf-8" ):
162- self .io .add_input_character (ord (char ))
163-
164- else :
165- return False
166-
167- return True
168-
169- def processInputs (self ) -> None :
170- width , height = ctypes .c_int (0 ), ctypes .c_int (0 )
171- sdl3 .SDL_GetWindowSize (self .window , ctypes .byref (width ), ctypes .byref (height ))
172- self .io .display_size , self .io .mouse_wheel = (width .value , height .value ), 0
173- if USE_IMGUI_BUNDLE : self .io .display_framebuffer_scale = (1 , 1 )
174- else : self .io .display_fb_scale = (1 , 1 )
175-
176- currentTime = sdl3 .SDL_GetTicks () / 1000.0 ; deltaTime = currentTime - self .lastTime
177- self .io .delta_time = 1.0 / 10000.0 if deltaTime <= 0.0 else deltaTime
178- self .lastTime = currentTime
3+ from imgui_bundle .python_backends .sdl3_backend import imgui , SDL3Renderer
1794
1805@sdl3 .SDL_main_func
1816def main (argc : ctypes .c_int , argv : sdl3 .LP_c_char_p ) -> ctypes .c_int :
@@ -201,19 +26,17 @@ def main(argc: ctypes.c_int, argv: sdl3.LP_c_char_p) -> ctypes.c_int:
20126 return - 1
20227
20328 imgui .create_context ()
204- if USE_IMGUI_BUNDLE : imgui .get_io ().set_ini_filename ("" )
205- else : imgui .get_io ().ini_file_name = None
206- SDL3Renderer .setCustomStyle ()
29+ imgui .get_io ().set_ini_filename ("" )
20730
20831 renderer = SDL3Renderer (window )
20932 running , hue , lastTime = True , 0.0 , time .time ()
21033 event = sdl3 .SDL_Event ()
21134
21235 while running :
213- renderer .processInputs ()
36+ renderer .process_inputs ()
21437
21538 while sdl3 .SDL_PollEvent (ctypes .byref (event )):
216- renderer .processEvent (event )
39+ renderer .process_event (event )
21740
21841 match event .type :
21942 case sdl3 .SDL_EVENT_QUIT :
@@ -239,9 +62,7 @@ def main(argc: ctypes.c_int, argv: sdl3.LP_c_char_p) -> ctypes.c_int:
23962 sdl3 .SDL_GL_SwapWindow (window )
24063
24164 renderer .shutdown ()
242-
243- if USE_IMGUI_BUNDLE :
244- imgui .destroy_context ()
65+ imgui .destroy_context ()
24566
24667 sdl3 .SDL_GL_MakeCurrent (window , None )
24768 sdl3 .SDL_GL_DestroyContext (context )
0 commit comments