Skip to content

Commit

Permalink
Add yakui-sdl3 for sdl3 bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
LPGhatguy committed Jan 23, 2025
1 parent 724f9c1 commit 12a6e2d
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 0 deletions.
11 changes: 11 additions & 0 deletions crates/yakui-sdl3/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "yakui-sdl3"
description = "sdl3 bindings for yakui"
version = "0.1.0"
license = "MIT OR Apache-2.0"
repository = "https://github.com/SecondHalfGames/yakui"
edition = "2021"

[dependencies]
yakui-core = { path = "../yakui-core", version = "0.3.0" }
sdl3 = "0.14.0"
107 changes: 107 additions & 0 deletions crates/yakui-sdl3/src/keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use sdl3::keyboard::{Mod, Scancode};
use yakui_core::input::{KeyCode, Modifiers};

pub fn from_sdl_scancode(key: Scancode) -> Option<KeyCode> {
Some(match key {
Scancode::Space => KeyCode::Space,
Scancode::Backspace => KeyCode::Backspace,
Scancode::Delete => KeyCode::Delete,
Scancode::Return => KeyCode::Enter,
Scancode::KpEnter => KeyCode::NumpadEnter,
Scancode::Tab => KeyCode::Tab,
Scancode::Left => KeyCode::ArrowLeft,
Scancode::Right => KeyCode::ArrowRight,
Scancode::Escape => KeyCode::Escape,
Scancode::Home => KeyCode::Home,
Scancode::End => KeyCode::End,
Scancode::Up => KeyCode::ArrowUp,
Scancode::Down => KeyCode::ArrowDown,
Scancode::PageUp => KeyCode::PageUp,
Scancode::PageDown => KeyCode::PageDown,

Scancode::A => KeyCode::KeyA,
Scancode::B => KeyCode::KeyB,
Scancode::C => KeyCode::KeyC,
Scancode::D => KeyCode::KeyD,
Scancode::E => KeyCode::KeyE,
Scancode::F => KeyCode::KeyF,
Scancode::G => KeyCode::KeyG,
Scancode::H => KeyCode::KeyH,
Scancode::I => KeyCode::KeyI,
Scancode::J => KeyCode::KeyJ,
Scancode::K => KeyCode::KeyK,
Scancode::L => KeyCode::KeyL,
Scancode::M => KeyCode::KeyM,
Scancode::N => KeyCode::KeyN,
Scancode::O => KeyCode::KeyO,
Scancode::P => KeyCode::KeyP,
Scancode::Q => KeyCode::KeyQ,
Scancode::R => KeyCode::KeyR,
Scancode::S => KeyCode::KeyS,
Scancode::T => KeyCode::KeyT,
Scancode::U => KeyCode::KeyU,
Scancode::V => KeyCode::KeyV,
Scancode::W => KeyCode::KeyW,
Scancode::X => KeyCode::KeyX,
Scancode::Y => KeyCode::KeyY,
Scancode::Z => KeyCode::KeyZ,
Scancode::_0 => KeyCode::Digit0,
Scancode::_1 => KeyCode::Digit1,
Scancode::_2 => KeyCode::Digit2,
Scancode::_3 => KeyCode::Digit3,
Scancode::_4 => KeyCode::Digit4,
Scancode::_5 => KeyCode::Digit5,
Scancode::_6 => KeyCode::Digit6,
Scancode::_7 => KeyCode::Digit7,
Scancode::_8 => KeyCode::Digit8,
Scancode::_9 => KeyCode::Digit9,
Scancode::F1 => KeyCode::F1,
Scancode::F2 => KeyCode::F2,
Scancode::F3 => KeyCode::F3,
Scancode::F4 => KeyCode::F4,
Scancode::F5 => KeyCode::F5,
Scancode::F6 => KeyCode::F6,
Scancode::F7 => KeyCode::F7,
Scancode::F8 => KeyCode::F8,
Scancode::F9 => KeyCode::F9,
Scancode::F10 => KeyCode::F10,
Scancode::F11 => KeyCode::F11,
Scancode::F12 => KeyCode::F12,
Scancode::F13 => KeyCode::F13,
Scancode::F14 => KeyCode::F14,
Scancode::F15 => KeyCode::F15,
Scancode::F16 => KeyCode::F16,
Scancode::F17 => KeyCode::F17,
Scancode::F18 => KeyCode::F18,
Scancode::F19 => KeyCode::F19,
Scancode::F20 => KeyCode::F20,
Scancode::F21 => KeyCode::F21,
Scancode::F22 => KeyCode::F22,
Scancode::F23 => KeyCode::F23,
Scancode::F24 => KeyCode::F24,

_ => return None,
})
}

pub fn from_sdl_modifiers(sdl_mods: Mod) -> Modifiers {
let mut mods = Modifiers::default();

if sdl_mods.intersects(Mod::LSHIFTMOD | Mod::RSHIFTMOD) {
mods |= Modifiers::SHIFT;
}

if sdl_mods.intersects(Mod::LCTRLMOD | Mod::RCTRLMOD) {
mods |= Modifiers::CONTROL;
}

if sdl_mods.intersects(Mod::LALTMOD) {
mods |= Modifiers::ALT;
}

if sdl_mods.intersects(Mod::LGUIMOD | Mod::RGUIMOD) {
mods |= Modifiers::META;
}

mods
}
127 changes: 127 additions & 0 deletions crates/yakui-sdl3/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
mod keys;

use sdl3::event::{Event as SdlEvent, WindowEvent};
use sdl3::mouse::MouseButton as SdlMouseButton;
use sdl3::sys::video::SDL_GetWindowDisplayScale;
use sdl3::video::Window;
use yakui_core::event::Event;
use yakui_core::geometry::{Rect, UVec2, Vec2};
use yakui_core::input::MouseButton;

use self::keys::from_sdl_scancode;

pub struct YakuiSdl2 {
init: Option<InitState>,
}

struct InitState {
size: UVec2,
scale: f32,
}

fn scale_factor(window: &Window) -> f32 {
unsafe { SDL_GetWindowDisplayScale(window.raw()) }
}

impl YakuiSdl2 {
pub fn new(window: &Window) -> Self {
let size = window.size().into();
let scale = scale_factor(window);

Self {
init: Some(InitState { size, scale }),
}
}

pub fn handle_event(&mut self, state: &mut yakui_core::Yakui, event: &SdlEvent) -> bool {
if let Some(init) = self.init.take() {
state.set_surface_size(init.size.as_vec2());
state.set_unscaled_viewport(Rect::from_pos_size(Vec2::ZERO, init.size.as_vec2()));
state.set_scale_factor(init.scale);
}

match event {
SdlEvent::Window { win_event, .. } => {
match win_event {
WindowEvent::Resized(x, y) => {
let size = Vec2::new(*x as f32, *y as f32);
state.set_surface_size(size);
state.set_unscaled_viewport(Rect::from_pos_size(Vec2::ZERO, size));

false
}

WindowEvent::MouseLeave => state.handle_event(Event::CursorMoved(None)),

// FIXME: scale factor changed
_ => false,
}
}

SdlEvent::MouseMotion { x, y, .. } => {
let pos = Vec2::new(*x, *y);
state.handle_event(Event::CursorMoved(Some(pos)))
}

SdlEvent::MouseButtonDown { mouse_btn, .. } => {
let button = match mouse_btn {
SdlMouseButton::Left => MouseButton::One,
SdlMouseButton::Right => MouseButton::Two,
SdlMouseButton::Middle => MouseButton::Three,
_ => return false,
};

state.handle_event(Event::MouseButtonChanged { button, down: true })
}

SdlEvent::MouseButtonUp { mouse_btn, .. } => {
let button = match mouse_btn {
SdlMouseButton::Left => MouseButton::One,
SdlMouseButton::Right => MouseButton::Two,
SdlMouseButton::Middle => MouseButton::Three,
_ => return false,
};

state.handle_event(Event::MouseButtonChanged {
button,
down: false,
})
}

SdlEvent::MouseWheel { x, y, .. } => {
// Observed logical pixels per scroll wheel increment in Windows on Chrome
const LINE_HEIGHT: f32 = 100.0 / 3.0;

state.handle_event(Event::MouseScroll {
delta: Vec2::new(*x, -*y) * LINE_HEIGHT,
})
}

SdlEvent::TextInput { text, .. } => {
for c in text.chars() {
state.handle_event(Event::TextInput(c));
}

false
}

SdlEvent::KeyDown { scancode, .. } => {
if let Some(key) = scancode.and_then(from_sdl_scancode) {
state.handle_event(Event::KeyChanged { key, down: true })
} else {
false
}
}

SdlEvent::KeyUp { scancode, .. } => {
if let Some(key) = scancode.and_then(from_sdl_scancode) {
state.handle_event(Event::KeyChanged { key, down: false })
} else {
false
}
}

_ => false,
}
}
}

0 comments on commit 12a6e2d

Please sign in to comment.