mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-24 03:41:29 +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;
|
extern crate time;
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use {Key, KeyRepeat};
|
use {Key, KeyRepeat, InputCallback};
|
||||||
|
|
||||||
pub struct KeyHandler {
|
pub struct KeyHandler {
|
||||||
|
pub key_callback: Option<Box<InputCallback>>,
|
||||||
prev_time: f64,
|
prev_time: f64,
|
||||||
delta_time: f32,
|
delta_time: f32,
|
||||||
keys: [bool; 512],
|
keys: [bool; 512],
|
||||||
|
@ -15,6 +16,7 @@ pub struct KeyHandler {
|
||||||
impl KeyHandler {
|
impl KeyHandler {
|
||||||
pub fn new() -> KeyHandler {
|
pub fn new() -> KeyHandler {
|
||||||
KeyHandler {
|
KeyHandler {
|
||||||
|
key_callback: None,
|
||||||
keys: [false; 512],
|
keys: [false; 512],
|
||||||
keys_down_duration: [-1.0; 512],
|
keys_down_duration: [-1.0; 512],
|
||||||
prev_time: time::precise_time_s(),
|
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>> {
|
pub fn get_keys_pressed(&self, repeat: KeyRepeat) -> Option<Vec<Key>> {
|
||||||
let mut index: u16 = 0;
|
let mut index: u16 = 0;
|
||||||
let mut keys: Vec<Key> = Vec::new();
|
let mut keys: Vec<Key> = Vec::new();
|
||||||
|
|
14
src/lib.rs
14
src/lib.rs
|
@ -54,6 +54,12 @@ pub enum MouseMode {
|
||||||
Discard,
|
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;
|
extern crate libc;
|
||||||
|
|
||||||
use std::os::raw;
|
use std::os::raw;
|
||||||
|
@ -433,6 +439,14 @@ impl Window {
|
||||||
self.0.is_active()
|
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
|
/// 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.
|
/// 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;
|
OSXWindow* win = (OSXWindow*)window;
|
||||||
win->key_callback = key_callback;
|
win->key_callback = key_callback;
|
||||||
|
win->char_callback = char_callback;
|
||||||
win->rust_data = rust_data;
|
win->rust_data = rust_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ void build_submenu(NSMenu* menu, MenuDesc* desc);
|
||||||
{
|
{
|
||||||
NSView* childContentView;
|
NSView* childContentView;
|
||||||
@public void (*key_callback)(void* user_data, int key, int state);
|
@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 width;
|
||||||
@public int height;
|
@public int height;
|
||||||
@public int scale;
|
@public int scale;
|
||||||
|
|
|
@ -71,6 +71,14 @@
|
||||||
key_callback(rust_data, [event keyCode], 1);
|
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];
|
[super keyDown:event];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use {MouseButton, MouseMode, Scale, Key, KeyRepeat, WindowOptions};
|
||||||
use key_handler::KeyHandler;
|
use key_handler::KeyHandler;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use Result;
|
use Result;
|
||||||
|
use InputCallback;
|
||||||
use mouse_handler;
|
use mouse_handler;
|
||||||
use window_flags;
|
use window_flags;
|
||||||
use menu::Menu;
|
use menu::Menu;
|
||||||
|
@ -170,7 +171,9 @@ extern {
|
||||||
fn mfb_update(window: *mut c_void);
|
fn mfb_update(window: *mut c_void);
|
||||||
fn mfb_update_with_buffer(window: *mut c_void, buffer: *const c_uchar);
|
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_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_set_mouse_data(window_handle: *mut c_void, shared_data: *mut SharedData);
|
||||||
fn mfb_should_close(window: *mut c_void) -> i32;
|
fn mfb_should_close(window: *mut c_void) -> i32;
|
||||||
fn mfb_get_screen_size() -> u32;
|
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 {
|
impl Window {
|
||||||
pub fn new(name: &str, width: usize, height: usize, opts: WindowOptions) -> Result<Window> {
|
pub fn new(name: &str, width: usize, height: usize, opts: WindowOptions) -> Result<Window> {
|
||||||
let n = match CString::new(name) {
|
let n = match CString::new(name) {
|
||||||
|
@ -261,7 +277,7 @@ impl Window {
|
||||||
unsafe {
|
unsafe {
|
||||||
mfb_update_with_buffer(self.window_handle, buffer.as_ptr() as *const u8);
|
mfb_update_with_buffer(self.window_handle, buffer.as_ptr() as *const u8);
|
||||||
Self::set_mouse_data(self);
|
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 {
|
unsafe {
|
||||||
mfb_update(self.window_handle);
|
mfb_update(self.window_handle);
|
||||||
Self::set_mouse_data(self);
|
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)
|
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> {
|
pub fn is_menu_pressed(&mut self) -> Option<usize> {
|
||||||
let menu_id = unsafe { mfb_active_menu(self.window_handle) };
|
let menu_id = unsafe { mfb_active_menu(self.window_handle) };
|
||||||
|
|
||||||
|
|
|
@ -293,6 +293,11 @@ impl Window {
|
||||||
self.key_handler.is_key_pressed(key, repeat)
|
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]
|
#[inline]
|
||||||
pub fn is_open(&self) -> bool {
|
pub fn is_open(&self) -> bool {
|
||||||
unsafe { mfb_should_close(self.window_handle) == 1 }
|
unsafe { mfb_should_close(self.window_handle) == 1 }
|
||||||
|
|
|
@ -517,6 +517,11 @@ impl Window {
|
||||||
self.key_handler.is_key_down(key)
|
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]
|
#[inline]
|
||||||
pub fn set_key_repeat_delay(&mut self, delay: f32) {
|
pub fn set_key_repeat_delay(&mut self, delay: f32) {
|
||||||
self.key_handler.set_key_repeat_delay(delay)
|
self.key_handler.set_key_repeat_delay(delay)
|
||||||
|
|
Loading…
Reference in a new issue