mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 19:31:30 +11:00
Implemented callback for characters
This is so when typing input on the keyboard characters may not match the layout in non-english for example. Currently Mac has been implemented to support this.
This commit is contained in:
parent
3c3dcd7c07
commit
eaf12ebb29
|
@ -1,9 +1,10 @@
|
|||
extern crate time;
|
||||
|
||||
use std::mem;
|
||||
use {Key, KeyRepeat};
|
||||
use {Key, KeyRepeat, InputCallback};
|
||||
|
||||
pub struct KeyHandler {
|
||||
pub key_callback: Option<Box<InputCallback>>,
|
||||
prev_time: f64,
|
||||
delta_time: f32,
|
||||
keys: [bool; 512],
|
||||
|
@ -15,6 +16,7 @@ pub struct KeyHandler {
|
|||
impl KeyHandler {
|
||||
pub fn new() -> KeyHandler {
|
||||
KeyHandler {
|
||||
key_callback: None,
|
||||
keys: [false; 512],
|
||||
keys_down_duration: [-1.0; 512],
|
||||
prev_time: time::precise_time_s(),
|
||||
|
@ -65,6 +67,10 @@ impl KeyHandler {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_input_callback(&mut self, callback: Box<InputCallback>) {
|
||||
self.key_callback = Some(callback);
|
||||
}
|
||||
|
||||
pub fn get_keys_pressed(&self, repeat: KeyRepeat) -> Option<Vec<Key>> {
|
||||
let mut index: u16 = 0;
|
||||
let mut keys: Vec<Key> = Vec::new();
|
||||
|
|
14
src/lib.rs
14
src/lib.rs
|
@ -54,6 +54,12 @@ pub enum MouseMode {
|
|||
Discard,
|
||||
}
|
||||
|
||||
/// This trait can be implemented and set with ```set_input_callback``` to reieve a callback
|
||||
/// whene there is inputs incoming. Currently only support unicode chars.
|
||||
pub trait InputCallback {
|
||||
fn add_char(&mut self, uni_char: u32);
|
||||
}
|
||||
|
||||
extern crate libc;
|
||||
|
||||
use std::os::raw;
|
||||
|
@ -433,6 +439,14 @@ impl Window {
|
|||
self.0.is_active()
|
||||
}
|
||||
|
||||
///
|
||||
/// Set input callback to recive callback on char input
|
||||
///
|
||||
#[inline]
|
||||
pub fn set_input_callback(&mut self, callback: Box<InputCallback>) {
|
||||
self.0.set_input_callback(callback)
|
||||
}
|
||||
|
||||
///
|
||||
/// This allows adding menus to your windows. As menus behaves a bit diffrently depending on
|
||||
/// Operating system here is how it works. See [Menu] for description on each field.
|
||||
|
|
|
@ -315,10 +315,13 @@ uint32_t mfb_get_screen_size()
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void mfb_set_key_callback(void* window, void* rust_data, void (*key_callback)(void* user_data, int key, int state))
|
||||
void mfb_set_key_callback(void* window, void* rust_data,
|
||||
void (*key_callback)(void* user_data, int key, int state),
|
||||
void (*char_callback)(void* user_data, uint32_t key))
|
||||
{
|
||||
OSXWindow* win = (OSXWindow*)window;
|
||||
win->key_callback = key_callback;
|
||||
win->char_callback = char_callback;
|
||||
win->rust_data = rust_data;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ void build_submenu(NSMenu* menu, MenuDesc* desc);
|
|||
{
|
||||
NSView* childContentView;
|
||||
@public void (*key_callback)(void* user_data, int key, int state);
|
||||
@public void (*char_callback)(void* user_data, unsigned int key);
|
||||
@public int width;
|
||||
@public int height;
|
||||
@public int scale;
|
||||
|
|
|
@ -71,6 +71,14 @@
|
|||
key_callback(rust_data, [event keyCode], 1);
|
||||
}
|
||||
|
||||
if (char_callback) {
|
||||
NSString* characters = [event characters];
|
||||
NSUInteger i, length = [characters length];
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
char_callback(rust_data, [characters characterAtIndex:i]);
|
||||
}
|
||||
|
||||
[super keyDown:event];
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ use {MouseButton, MouseMode, Scale, Key, KeyRepeat, WindowOptions};
|
|||
use key_handler::KeyHandler;
|
||||
use error::Error;
|
||||
use Result;
|
||||
use InputCallback;
|
||||
use mouse_handler;
|
||||
use window_flags;
|
||||
use menu::Menu;
|
||||
|
@ -170,7 +171,9 @@ extern {
|
|||
fn mfb_update(window: *mut c_void);
|
||||
fn mfb_update_with_buffer(window: *mut c_void, buffer: *const c_uchar);
|
||||
fn mfb_set_position(window: *mut c_void, x: i32, y: i32);
|
||||
fn mfb_set_key_callback(window: *mut c_void, target: *mut c_void, cb: unsafe extern fn(*mut c_void, i32, i32));
|
||||
fn mfb_set_key_callback(window: *mut c_void, target: *mut c_void,
|
||||
cb: unsafe extern fn(*mut c_void, i32, i32),
|
||||
cb: unsafe extern fn(*mut c_void, u32));
|
||||
fn mfb_set_mouse_data(window_handle: *mut c_void, shared_data: *mut SharedData);
|
||||
fn mfb_should_close(window: *mut c_void) -> i32;
|
||||
fn mfb_get_screen_size() -> u32;
|
||||
|
@ -213,6 +216,19 @@ unsafe extern "C" fn key_callback(window: *mut c_void, key: i32, state: i32) {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn char_callback(window: *mut c_void, code_point: u32) {
|
||||
let win: *mut Window = mem::transmute(window);
|
||||
|
||||
// Taken from GLFW
|
||||
if code_point < 32 || (code_point > 126 && code_point < 160) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(ref mut callback) = (*win).key_handler.key_callback {
|
||||
callback.add_char(code_point);
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(name: &str, width: usize, height: usize, opts: WindowOptions) -> Result<Window> {
|
||||
let n = match CString::new(name) {
|
||||
|
@ -261,7 +277,7 @@ impl Window {
|
|||
unsafe {
|
||||
mfb_update_with_buffer(self.window_handle, buffer.as_ptr() as *const u8);
|
||||
Self::set_mouse_data(self);
|
||||
mfb_set_key_callback(self.window_handle, mem::transmute(self), key_callback);
|
||||
mfb_set_key_callback(self.window_handle, mem::transmute(self), key_callback, char_callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,7 +287,7 @@ impl Window {
|
|||
unsafe {
|
||||
mfb_update(self.window_handle);
|
||||
Self::set_mouse_data(self);
|
||||
mfb_set_key_callback(self.window_handle, mem::transmute(self), key_callback);
|
||||
mfb_set_key_callback(self.window_handle, mem::transmute(self), key_callback, char_callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,6 +357,11 @@ impl Window {
|
|||
self.key_handler.is_key_pressed(key, repeat)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_input_callback(&mut self, callback: Box<InputCallback>) {
|
||||
self.key_handler.set_input_callback(callback)
|
||||
}
|
||||
|
||||
pub fn is_menu_pressed(&mut self) -> Option<usize> {
|
||||
let menu_id = unsafe { mfb_active_menu(self.window_handle) };
|
||||
|
||||
|
|
|
@ -293,6 +293,11 @@ impl Window {
|
|||
self.key_handler.is_key_pressed(key, repeat)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_input_callback(&mut self, callback: Box<InputCallback>) {
|
||||
self.key_handler.set_input_callback(callback)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_open(&self) -> bool {
|
||||
unsafe { mfb_should_close(self.window_handle) == 1 }
|
||||
|
|
|
@ -517,6 +517,11 @@ impl Window {
|
|||
self.key_handler.is_key_down(key)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_input_callback(&mut self, callback: Box<InputCallback>) {
|
||||
self.key_handler.set_input_callback(callback)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_key_repeat_delay(&mut self, delay: f32) {
|
||||
self.key_handler.set_key_repeat_delay(delay)
|
||||
|
|
Loading…
Reference in a new issue