sdl

    MoonBit bindings for SDL

    sdl
    Download zip
    Author
    Version
    0.1.2
    License
    Apache-2.0
    Last updated
    2 hours ago
    Downloads
    15

    Dependencies

    #klaseca/sdl

    High-level MoonBit bindings for SDL 3.

    This module wraps klaseca/sdl-sys with a more MoonBit-friendly API for common application code: initialization, windows, events, trays, renderers, textures, clipboard, and message boxes.

    The API is still young and may change while the binding grows.

    #Installation

    Add the module as a dependency from another MoonBit module:

    import {
    "klaseca/sdl@0.0.1",
    }

    Native builds also need the SDL setup required by klaseca/sdl-sys: headers, link library, and runtime shared library. Consuming this module does not require running the binding generator. npm install and npm run bindgen are only needed when changing the generated sdl-sys API in this repository.

    #Application Loop

    App owns SDL initialization and shutdown for simple applications.

    fn main {
    try! @sdl.App().run(setup)
    }

    fn setup(app : @sdl.App) -> Unit raise @sdl.SdlError {
    let window = @sdl.Window(
    title="MoonBit SDL",
    width=800,
    height=480,
    resizable=true,
    )
    defer window.destroy()

    let renderer = @sdl.Renderer(window)
    defer renderer.destroy()

    app.run_loop(() => {
    renderer.set_draw_color(@sdl.Color::rgb(r=24, g=28, b=36))
    renderer.clear()
    renderer.present()
    })
    }

    ControlFlow controls how the loop waits between iterations:

    • Poll: continue immediately.
    • Wait(Int): wait for an SDL event or timeout in milliseconds.
    • Exit: stop the loop.

    Call app.exit() from a callback or loop body to stop the loop.

    #Windows

    Create a window:

    let window = @sdl.Window(
    title="MoonBit SDL",
    width=800,
    height=480,
    resizable=true,
    )
    defer window.destroy()

    Useful methods include:

    • show, hide, raise_window, minimize, maximize, restore
    • size, size_in_pixels, position, title, flags
    • set_title, set_size, set_position, set_placement, set_resizable
    • set_fullscreen, set_bordered, set_always_on_top
    • show_simple_message_box

    Use WindowPlacement for SDL-managed placement modes:

    window.set_placement(Centered)
    window.set_placement(CenteredOnDisplay(1))

    #Events

    For low-level polling, use poll_event():

    match @sdl.poll_event() {
    Some(Quit) => ()
    Some(WindowCloseRequested(event)) => println("close requested: \{event.window_id}")
    Some(_) | None => ()
    }

    App handles SDL Quit and window close requests in its run loop. Ordinary windows close the application by default. Tray-style windows can opt into hiding on close:

    let window = @sdl.Window(
    title="MoonBit SDL",
    width=800,
    height=480,
    close_behavior=Hide,
    )

    For window-specific event callbacks, use:

    let redraw = window.on(Exposed, _event => {
    renderer.clear()
    renderer.present()
    })
    defer redraw.dispose()

    WindowEvent contains the window_id, the event name, and size for events that carry window dimensions:

    let resized = window.on(Resized, event => {
    if event.size is Some(size) {
    println("window size: \{size.width}x\{size.height}")
    }
    })
    defer resized.dispose()

    Currently supported window event names are:

    • Exposed
    • Resized
    • PixelSizeChanged
    • CloseRequested

    #Rendering

    Create a renderer from a window:

    let renderer = @sdl.Renderer(window)
    defer renderer.destroy()

    renderer.set_draw_color(@sdl.Color::rgb(r=70, g=155, b=255))
    renderer.clear()
    renderer.fill_rect(x=280.0, y=160.0, w=240.0, h=160.0)
    renderer.present()

    Textures are available through Renderer::create_texture or Texture::Texture:

    let texture = renderer.create_texture(
    width=256,
    height=256,
    format=@sdl.Bgra8888,
    access=@sdl.Streaming,
    )
    defer texture.destroy()

    Use Texture::update for direct pixel uploads.

    #Tray

    Tray menus are built declaratively with Menu:

    let tray = @sdl.Tray(
    tooltip="MoonBit SDL",
    menu=@sdl.Menu()
    .button(label="Show window", on_click=() => window.show())
    .button(label="About", on_click=() => {
    window.show_simple_message_box(
    title="MoonBit SDL",
    message="Hello from tray",
    )
    })
    .checkbox(label="Enabled", checked=true)
    .separator()
    .submenu(
    label="More",
    menu=@sdl.Menu().button(label="Quit", on_click=() => app.exit()),
    ),
    )
    defer tray.destroy()

    If you use trays outside an SDL event-processing loop, call Tray::update() periodically.

    #Clipboard

    @sdl.Clipboard::set_text("Copied from MoonBit")
    let text = @sdl.Clipboard::text()

    #Error Handling

    Most high-level operations that can fail raise SdlError.

    fn open_window() -> Unit raise @sdl.SdlError {
    let window = @sdl.Window(title="Example", width=640, height=480)
    defer window.destroy()
    }

    Use normal MoonBit error propagation in functions marked raise, or try! from main for examples and experiments.

    SdlError

    pub(all) suberror SdlError {
    SdlError(String)
    } derive(Eq,
    Debug
    )

    SdlError::equal

    fn SdlError::equal(SdlError, SdlError) -> Bool

    SdlError::not_equal

    fn SdlError::not_equal(x : SdlError, y : SdlError) -> Bool

    SdlError::to_repr

    App

    type App

    App::App

    fn App::App(init_flags? : UInt, control_flow? : ControlFlow) -> App

    App::exit

    fn App::exit(self : App) -> Unit

    App::is_running

    fn App::is_running(self : App) -> Bool

    App::run

    fn App::run(self : App, setup : (App) -> Unit raise SdlError) -> Unit raise SdlError

    App::run_loop

    fn App::run_loop(self : App, update : () -> Unit raise SdlError) -> Unit raise SdlError

    BlendMode

    pub(all) enum BlendMode {
    NoBlend
    Blend
    BlendPremultiplied
    Add
    AddPremultiplied
    Mod
    Mul
    } derive(Eq,
    Debug
    )

    BlendMode::equal

    fn BlendMode::equal(BlendMode, BlendMode) -> Bool

    BlendMode::not_equal

    fn BlendMode::not_equal(x : BlendMode, y : BlendMode) -> Bool

    Clipboard

    pub type Clipboard

    Clipboard::has_text

    fn Clipboard::has_text() -> Bool

    Clipboard::set_text

    fn Clipboard::set_text(text : String) -> Unit raise SdlError

    Clipboard::text

    fn Clipboard::text() -> String

    Color

    pub(all) struct Color {
    r : Byte
    g : Byte
    b : Byte
    a : Byte
    } derive(Eq,
    Debug
    )

    Color::equal

    fn Color::equal(Color, Color) -> Bool

    Color::not_equal

    fn Color::not_equal(x : Color, y : Color) -> Bool

    Color::rgb

    fn Color::rgb(r~ : Byte, g~ : Byte, b~ : Byte) -> Color

    Color::rgba

    fn Color::rgba(r~ : Byte, g~ : Byte, b~ : Byte, a~ : Byte) -> Color

    Color::to_repr

    ControlFlow

    pub(all) enum ControlFlow {
    Poll
    Wait(Int)
    Exit
    } derive(Eq,
    Debug
    )

    ControlFlow::equal

    fn ControlFlow::equal(ControlFlow, ControlFlow) -> Bool

    ControlFlow::not_equal

    fn ControlFlow::not_equal(x : ControlFlow, y : ControlFlow) -> Bool

    Event

    pub(all) enum Event {
    Quit
    KeyDown(KeyboardEvent)
    KeyUp(KeyboardEvent)
    MouseMotion(MouseMotionEvent)
    MouseButtonDown(MouseButtonEvent)
    MouseButtonUp(MouseButtonEvent)
    TextInput(TextInputEvent)
    WindowExposed(WindowEvent)
    WindowResized(WindowEvent)
    WindowPixelSizeChanged(WindowEvent)
    WindowCloseRequested(WindowEvent)
    Other(UInt)
    } derive(Eq,
    Debug
    )

    Event::equal

    fn Event::equal(Event, Event) -> Bool

    Event::not_equal

    fn Event::not_equal(x : Event, y : Event) -> Bool

    Event::to_repr

    EventListener

    type EventListener

    EventListener::dispose

    fn EventListener::dispose(self : EventListener) -> Unit

    FRect

    pub(all) struct FRect {
    x : Float
    y : Float
    w : Float
    h : Float
    } derive(
    Debug
    )

    FRect::FRect

    fn FRect::FRect(x~ : Float, y~ : Float, w~ : Float, h~ : Float) -> FRect

    FRect::to_repr

    FSize

    pub(all) struct FSize {
    width : Float
    height : Float
    } derive(Eq,
    Debug
    )

    FSize::equal

    fn FSize::equal(FSize, FSize) -> Bool

    FSize::not_equal

    fn FSize::not_equal(x : FSize, y : FSize) -> Bool

    FSize::to_repr

    KeyboardEvent

    pub(all) struct KeyboardEvent {
    window_id : UInt
    keyboard_id : UInt
    scancode : Int
    keycode : UInt
    modifiers : UInt16
    repeat : Bool
    } derive(Eq,
    Debug
    )

    KeyboardEvent::equal

    KeyboardEvent::not_equal

    fn KeyboardEvent::not_equal(x : KeyboardEvent, y : KeyboardEvent) -> Bool

    pub struct Menu {
    // private fields
    }

    fn Menu::Menu() -> Menu

    fn Menu::append(self : Menu, menu : Menu) -> Menu

    fn Menu::button(self : Menu, label~ : String, on_click? : () -> Unit, enabled? : Bool) -> Menu

    fn Menu::checkbox(self : Menu, label~ : String, on_click? : () -> Unit, checked? : Bool, enabled? : Bool) -> Menu

    fn Menu::separator(self : Menu) -> Menu

    fn Menu::submenu(self : Menu, label~ : String, menu~ : Menu) -> Menu

    MouseButtonEvent

    pub(all) struct MouseButtonEvent {
    window_id : UInt
    mouse_id : UInt
    button : Byte
    clicks : Byte
    x : Float
    y : Float
    } derive(Eq,
    Debug
    )

    MouseButtonEvent::equal

    MouseButtonEvent::not_equal

    fn MouseButtonEvent::not_equal(x : MouseButtonEvent, y : MouseButtonEvent) -> Bool

    MouseMotionEvent

    pub(all) struct MouseMotionEvent {
    window_id : UInt
    mouse_id : UInt
    state : UInt
    x : Float
    y : Float
    xrel : Float
    yrel : Float
    } derive(Eq,
    Debug
    )

    MouseMotionEvent::equal

    MouseMotionEvent::not_equal

    fn MouseMotionEvent::not_equal(x : MouseMotionEvent, y : MouseMotionEvent) -> Bool

    PixelFormat

    pub(all) enum PixelFormat {
    Rgba8888
    Abgr8888
    Bgra8888
    Bgra32
    } derive(Eq,
    Debug
    )

    PixelFormat::equal

    fn PixelFormat::equal(PixelFormat, PixelFormat) -> Bool

    PixelFormat::not_equal

    fn PixelFormat::not_equal(x : PixelFormat, y : PixelFormat) -> Bool

    Position

    pub(all) struct Position {
    x : Int
    y : Int
    } derive(Eq,
    Debug
    )

    Position::equal

    fn Position::equal(Position, Position) -> Bool

    Position::not_equal

    fn Position::not_equal(x : Position, y : Position) -> Bool

    Position::to_repr

    Properties

    pub(all) struct Properties {
    raw : UInt
    }

    Properties::Properties

    fn Properties::Properties() -> Properties raise SdlError

    Properties::destroy

    fn Properties::destroy(self : Properties) -> Unit

    Properties::raw

    fn Properties::raw(self : Properties) -> UInt

    Properties::set_boolean

    fn Properties::set_boolean(self : Properties, name~ : Bytes, value~ : Bool?) -> Unit raise SdlError

    Properties::set_property

    fn Properties::set_property(self : Properties, property : Property) -> Unit raise SdlError

    Properties::set_string

    fn Properties::set_string(self : Properties, name~ : Bytes, value~ : String?) -> Unit raise SdlError

    Property

    pub(all) enum Property {
    StringProperty(name~ : Bytes, value~ : String)
    NumberProperty(name~ : Bytes, value~ : Int64)
    FloatProperty(name~ : Bytes, value~ : Float)
    BooleanProperty(name~ : Bytes, value~ : Bool)
    } derive(Eq,
    Debug
    )

    Property::equal

    fn Property::equal(Property, Property) -> Bool

    Property::not_equal

    fn Property::not_equal(x : Property, y : Property) -> Bool

    Property::to_repr

    Rect

    pub(all) struct Rect {
    x : Int
    y : Int
    w : Int
    h : Int
    } derive(Eq,
    Debug
    )

    Rect::Rect

    fn Rect::Rect(x~ : Int, y~ : Int, w~ : Int, h~ : Int) -> Rect

    Rect::equal

    fn Rect::equal(Rect, Rect) -> Bool

    Rect::not_equal

    fn Rect::not_equal(x : Rect, y : Rect) -> Bool

    Rect::to_repr

    Renderer

    type Renderer

    Renderer::Renderer

    fn Renderer::Renderer(window : Window, name? : String) -> Renderer raise SdlError

    Renderer::clear

    fn Renderer::clear(self : Renderer) -> Unit raise SdlError

    Renderer::create_texture

    fn Renderer::create_texture(self : Renderer, width~ : Int, height~ : Int, format? : PixelFormat, access? : TextureAccess) -> Texture raise SdlError

    Renderer::destroy

    fn Renderer::destroy(self : Renderer) -> Unit

    Renderer::fill_frect

    fn Renderer::fill_frect(self : Renderer, rect : FRect) -> Unit raise SdlError

    Renderer::fill_rect

    fn Renderer::fill_rect(self : Renderer, x~ : Float, y~ : Float, w~ : Float, h~ : Float) -> Unit raise SdlError

    Renderer::output_size

    fn Renderer::output_size(self : Renderer) -> Size raise SdlError

    Renderer::present

    fn Renderer::present(self : Renderer) -> Unit raise SdlError

    Renderer::render_texture

    fn Renderer::render_texture(self : Renderer, texture : Texture, src? : FRect, dst? : FRect) -> Unit raise SdlError

    Renderer::set_draw_color

    fn Renderer::set_draw_color(self : Renderer, color : Color) -> Unit raise SdlError

    Size

    pub(all) struct Size {
    width : Int
    height : Int
    } derive(Eq,
    Debug
    )

    Size::equal

    fn Size::equal(Size, Size) -> Bool

    Size::not_equal

    fn Size::not_equal(x : Size, y : Size) -> Bool

    Size::to_repr

    TextInputEvent

    pub(all) struct TextInputEvent {
    text : String
    } derive(Eq,
    Debug
    )

    TextInputEvent::equal

    TextInputEvent::not_equal

    fn TextInputEvent::not_equal(x : TextInputEvent, y : TextInputEvent) -> Bool

    Texture

    type Texture

    Texture::Texture

    fn Texture::Texture(renderer : Renderer, width~ : Int, height~ : Int, format? : PixelFormat, access? : TextureAccess) -> Texture raise SdlError

    Texture::destroy

    fn Texture::destroy(self : Texture) -> Unit

    Texture::raw

    Texture::set_alpha_mod

    fn Texture::set_alpha_mod(self : Texture, alpha : Byte) -> Unit raise SdlError

    Texture::set_blend_mode

    fn Texture::set_blend_mode(self : Texture, blend_mode : BlendMode) -> Unit raise SdlError

    Texture::set_color_mod

    fn Texture::set_color_mod(self : Texture, color : Color) -> Unit raise SdlError

    Texture::size

    fn Texture::size(self : Texture) -> FSize raise SdlError

    Texture::update

    fn Texture::update(self : Texture, pixels~ : Bytes, pitch~ : Int, rect? : Rect) -> Unit raise SdlError

    TextureAccess

    pub(all) enum TextureAccess {
    Static
    Streaming
    Target
    } derive(Eq,
    Debug
    )

    TextureAccess::equal

    TextureAccess::not_equal

    fn TextureAccess::not_equal(x : TextureAccess, y : TextureAccess) -> Bool

    Tray

    type Tray

    Tray::Tray

    fn Tray::Tray(tooltip~ : String, menu? : Menu) -> Tray raise SdlError

    Tray::append

    fn Tray::append(self : Tray, menu : Menu) -> Unit raise SdlError

    Tray::destroy

    fn Tray::destroy(self : Tray) -> Unit

    Tray::raw

    Tray::set_tooltip

    fn Tray::set_tooltip(self : Tray, tooltip : String) -> Unit

    Tray::update

    fn Tray::update() -> Unit

    Window

    type Window

    Window::Window

    fn Window::Window(title~ : String, width~ : Int, height~ : Int, placement? : WindowPlacement, hidden? : Bool, resizable? : Bool, borderless? : Bool, always_on_top? : Bool, high_pixel_density? : Bool, constrain_popup? : Bool, external_graphics_context? : Bool, fullscreen? : Bool, maximized? : Bool, minimized? : Bool, menu? : Bool, modal? : Bool, mouse_grabbed? : Bool, focusable? : Bool, opengl? : Bool, metal? : Bool, vulkan? : Bool, transparent? : Bool, tooltip? : Bool, utility? : Bool, custom_properties? : Array[Property], close_behavior? : WindowCloseBehavior) -> Window raise SdlError

    Window::destroy

    fn Window::destroy(self : Window) -> Unit

    Window::flags

    fn Window::flags(self : Window) -> UInt64

    Window::hide

    fn Window::hide(self : Window) -> Unit raise SdlError

    Window::id

    fn Window::id(self : Window) -> UInt raise SdlError

    Window::keyboard_grab

    fn Window::keyboard_grab(self : Window) -> Bool

    Window::maximize

    fn Window::maximize(self : Window) -> Unit raise SdlError

    Window::maximum_size

    fn Window::maximum_size(self : Window) -> Size raise SdlError

    Window::minimize

    fn Window::minimize(self : Window) -> Unit raise SdlError

    Window::minimum_size

    fn Window::minimum_size(self : Window) -> Size raise SdlError

    Window::mouse_grab

    fn Window::mouse_grab(self : Window) -> Bool

    Window::on

    fn Window::on(self : Window, name : WindowEventName, callback : (WindowEvent) -> Unit) -> EventListener raise SdlError

    Window::opacity

    fn Window::opacity(self : Window) -> Float raise SdlError

    Window::position

    fn Window::position(self : Window) -> Position raise SdlError

    Window::raise_window

    fn Window::raise_window(self : Window) -> Unit raise SdlError

    Window::raw

    Window::restore

    fn Window::restore(self : Window) -> Unit raise SdlError

    Window::set_always_on_top

    fn Window::set_always_on_top(self : Window, on_top : Bool) -> Unit raise SdlError

    Window::set_bordered

    fn Window::set_bordered(self : Window, bordered : Bool) -> Unit raise SdlError

    Window::set_close_behavior

    fn Window::set_close_behavior(self : Window, behavior : WindowCloseBehavior) -> Unit raise SdlError

    Window::set_fullscreen

    fn Window::set_fullscreen(self : Window, fullscreen : Bool) -> Unit raise SdlError

    Window::set_keyboard_grab

    fn Window::set_keyboard_grab(self : Window, grabbed : Bool) -> Unit raise SdlError

    Window::set_maximum_size

    fn Window::set_maximum_size(self : Window, width~ : Int, height~ : Int) -> Unit raise SdlError

    Window::set_minimum_size

    fn Window::set_minimum_size(self : Window, width~ : Int, height~ : Int) -> Unit raise SdlError

    Window::set_mouse_grab

    fn Window::set_mouse_grab(self : Window, grabbed : Bool) -> Unit raise SdlError

    Window::set_opacity

    fn Window::set_opacity(self : Window, opacity : Float) -> Unit raise SdlError

    Window::set_placement

    fn Window::set_placement(self : Window, placement : WindowPlacement) -> Unit raise SdlError

    Window::set_position

    fn Window::set_position(self : Window, x~ : Int, y~ : Int) -> Unit raise SdlError

    Window::set_resizable

    fn Window::set_resizable(self : Window, resizable : Bool) -> Unit raise SdlError

    Window::set_size

    fn Window::set_size(self : Window, width~ : Int, height~ : Int) -> Unit raise SdlError

    Window::set_title

    fn Window::set_title(self : Window, title : String) -> Unit raise SdlError

    Window::show

    fn Window::show(self : Window) -> Unit raise SdlError

    Window::show_simple_message_box

    fn Window::show_simple_message_box(self : Window, title~ : String, message~ : String, flags? : UInt) -> Unit raise SdlError

    Window::show_system_menu

    fn Window::show_system_menu(self : Window, x~ : Int, y~ : Int) -> Unit raise SdlError

    Window::size

    fn Window::size(self : Window) -> Size raise SdlError

    Window::size_in_pixels

    fn Window::size_in_pixels(self : Window) -> Size raise SdlError

    Window::start_text_input

    fn Window::start_text_input(self : Window) -> Unit raise SdlError

    Window::stop_text_input

    fn Window::stop_text_input(self : Window) -> Unit raise SdlError

    Window::title

    fn Window::title(self : Window) -> String

    WindowCloseBehavior

    pub(all) enum WindowCloseBehavior {
    ExitApp
    Hide
    Ignore
    } derive(Eq,
    Debug
    )

    WindowCloseBehavior::equal

    WindowCloseBehavior::not_equal

    WindowEvent

    pub(all) struct WindowEvent {
    window_id : UInt
    name : WindowEventName
    size : Size?
    } derive(Eq,
    Debug
    )

    WindowEvent::equal

    fn WindowEvent::equal(WindowEvent, WindowEvent) -> Bool

    WindowEvent::not_equal

    fn WindowEvent::not_equal(x : WindowEvent, y : WindowEvent) -> Bool

    WindowEventName

    pub(all) enum WindowEventName {
    Exposed
    Resized
    PixelSizeChanged
    CloseRequested
    } derive(Eq,
    Debug
    )

    WindowEventName::equal

    WindowEventName::not_equal

    fn WindowEventName::not_equal(x : WindowEventName, y : WindowEventName) -> Bool

    WindowPlacement

    pub(all) enum WindowPlacement {
    Positioned(Position)
    Centered
    CenteredOnDisplay(UInt)
    Undefined
    UndefinedOnDisplay(UInt)
    } derive(Eq,
    Debug
    )

    WindowPlacement::equal

    WindowPlacement::not_equal

    fn WindowPlacement::not_equal(x : WindowPlacement, y : WindowPlacement) -> Bool

    INIT_AUDIO

    let INIT_AUDIO : UInt

    INIT_CAMERA

    let INIT_CAMERA : UInt

    INIT_EVENTS

    let INIT_EVENTS : UInt

    INIT_GAMEPAD

    let INIT_GAMEPAD : UInt

    INIT_HAPTIC

    let INIT_HAPTIC : UInt

    INIT_JOYSTICK

    let INIT_JOYSTICK : UInt

    INIT_SENSOR

    let INIT_SENSOR : UInt

    INIT_VIDEO

    let INIT_VIDEO : UInt

    MESSAGEBOX_ERROR

    let MESSAGEBOX_ERROR : UInt

    MESSAGEBOX_INFORMATION

    let MESSAGEBOX_INFORMATION : UInt

    MESSAGEBOX_WARNING

    let MESSAGEBOX_WARNING : UInt

    TRAYENTRY_BUTTON

    let TRAYENTRY_BUTTON : UInt

    TRAYENTRY_CHECKBOX

    let TRAYENTRY_CHECKBOX : UInt

    TRAYENTRY_CHECKED

    let TRAYENTRY_CHECKED : UInt

    TRAYENTRY_DISABLED

    let TRAYENTRY_DISABLED : UInt

    TRAYENTRY_SUBMENU

    let TRAYENTRY_SUBMENU : UInt

    add_event_watch

    fn add_event_watch(callback : (Event) -> Unit) -> EventListener raise SdlError

    delay

    fn delay(milliseconds : UInt) -> Unit

    init_lib

    fn init_lib(flags : UInt) -> Unit raise SdlError

    poll_event

    fn poll_event() -> Event?

    quit

    fn quit() -> Unit