Source code for moderngl_window.context.sdl2.window

from typing import Tuple
from ctypes import c_int
import sdl2
import sdl2.ext
import sdl2.video

from moderngl_window.context.base import BaseWindow
from moderngl_window.context.sdl2.keys import Keys


class Window(BaseWindow):
    """
    Basic window implementation using SDL2.
    """
    #: SDL2 specific key constants
    keys = Keys

    _mouse_button_map = {
        1: 1,
        3: 2,
        2: 3,
    }

[docs] def __init__(self, **kwargs): super().__init__(**kwargs) if sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) != 0: raise ValueError("Failed to initialize sdl2") sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_CONTEXT_MAJOR_VERSION, self.gl_version[0]) sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_CONTEXT_MINOR_VERSION, self.gl_version[1]) sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_CONTEXT_PROFILE_MASK, sdl2.SDL_GL_CONTEXT_PROFILE_CORE) sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG, 1) sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_DOUBLEBUFFER, 1) sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_DEPTH_SIZE, 24) sdl2.SDL_ShowCursor(sdl2.SDL_ENABLE if self.cursor else sdl2.SDL_DISABLE) if self.samples > 1: sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_MULTISAMPLEBUFFERS, 1) sdl2.video.SDL_GL_SetAttribute(sdl2.SDL_GL_MULTISAMPLESAMPLES, self.samples) flags = sdl2.SDL_WINDOW_OPENGL if self.fullscreen: flags |= sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP else: if self.resizable: flags |= sdl2.SDL_WINDOW_RESIZABLE self._window = sdl2.SDL_CreateWindow( self.title.encode(), sdl2.SDL_WINDOWPOS_UNDEFINED, sdl2.SDL_WINDOWPOS_UNDEFINED, self.width, self.height, flags, ) if not self._window: raise ValueError("Failed to create window:", sdl2.SDL_GetError()) self._context = sdl2.SDL_GL_CreateContext(self._window) sdl2.video.SDL_GL_SetSwapInterval(1 if self.vsync else 0) self.init_mgl_context() self.set_default_viewport()
@property def position(self) -> Tuple[int, int]: """Tuple[int, int]: The current window position. This property can also be set to move the window:: # Move window to 100, 100 window.position = 100, 100 """ x = c_int(0) y = c_int(0) sdl2.SDL_GetWindowPosition(self._window, x, y) return x.value, y.value @position.setter def position(self, value: Tuple[int, int]): sdl2.SDL_SetWindowPosition(self._window, value[0], value[1])
[docs] def swap_buffers(self) -> None: """Swap buffers, set viewport, trigger events and increment frame counter""" sdl2.SDL_GL_SwapWindow(self._window) self.set_default_viewport() self.process_events() self._frames += 1
[docs] def resize(self, width, height) -> None: """Resize callback Args: width: New window width height: New window height """ self._width = width self._height = height self._buffer_width, self._buffer_height = self._width, self._height self.set_default_viewport() super().resize(self._buffer_width, self._buffer_height)
def _handle_mods(self) -> None: """Update key mods""" mods = sdl2.SDL_GetModState() self._modifiers.shift = mods & sdl2.KMOD_SHIFT self._modifiers.ctrl = mods & sdl2.KMOD_CTRL
[docs] def process_events(self) -> None: """Handle all queued events in sdl2 dispatching events to standard methods""" for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_MOUSEMOTION: if self.mouse_states.any: self._mouse_drag_event_func(event.motion.x, event.motion.y) else: self._mouse_position_event_func(event.motion.x, event.motion.y) elif event.type == sdl2.SDL_MOUSEBUTTONDOWN: button = self._mouse_button_map.get(event.button.button, None) if button is not None: self._handle_mouse_button_state_change(button, True) self._mouse_release_event_func( event.motion.x, event.motion.y, button, ) elif event.type == sdl2.SDL_MOUSEBUTTONUP: button = self._mouse_button_map.get(event.button.button, None) if button is not None: self._handle_mouse_button_state_change(button, False) self._mouse_press_event_func( event.motion.x, event.motion.y, button, ) elif event.type in [sdl2.SDL_KEYDOWN, sdl2.SDL_KEYUP]: self._handle_mods() if event.key.keysym.sym == sdl2.SDLK_ESCAPE: self.close() if event.type == sdl2.SDL_KEYDOWN: self._key_pressed_map[event.key.keysym.sym] = True elif event.type == sdl2.SDL_KEYUP: self._key_pressed_map[event.key.keysym.sym] = False self._key_event_func(event.key.keysym.sym, event.type, self._modifiers) elif event.type == sdl2.SDL_TEXTINPUT: self._unicode_char_entered_func(event.text.text.decode()) elif event.type == sdl2.SDL_MOUSEWHEEL: self._mouse_scroll_event_func(float(event.wheel.x), float(event.wheel.y)) elif event.type == sdl2.SDL_QUIT: self.close() elif event.type == sdl2.SDL_WINDOWEVENT: if event.window.event == sdl2.SDL_WINDOWEVENT_RESIZED: self.resize(event.window.data1, event.window.data2)
[docs] def destroy(self) -> None: """Gracefully close the window""" sdl2.SDL_GL_DeleteContext(self._context) sdl2.SDL_DestroyWindow(self._window) sdl2.SDL_Quit()