eekkey: Dropped in favor of Button
Each Button has a KeyState, which may be shared with other buttons. The list of pressed and locked buttons is used as a list of keys, causing a search for the button in the current view.
This commit is contained in:
		@ -28,9 +28,20 @@ pub mod c {
 | 
			
		||||
    /// Since C doesn't respect borrowing rules,
 | 
			
		||||
    /// RefCell will enforce them dynamically (only 1 writer/many readers)
 | 
			
		||||
    /// Rc is implied and will ensure timely dropping
 | 
			
		||||
    #[repr(transparent)]
 | 
			
		||||
    pub struct CKeyState(*const RefCell<KeyState>);
 | 
			
		||||
    
 | 
			
		||||
    impl Clone for CKeyState {
 | 
			
		||||
        fn clone(&self) -> Self {
 | 
			
		||||
            CKeyState(self.0.clone())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl CKeyState {
 | 
			
		||||
        fn unwrap(self) -> Rc<RefCell<KeyState>> {
 | 
			
		||||
        pub fn wrap(state: Rc<RefCell<KeyState>>) -> CKeyState {
 | 
			
		||||
            CKeyState(Rc::into_raw(state))
 | 
			
		||||
        }
 | 
			
		||||
        pub fn unwrap(self) -> Rc<RefCell<KeyState>> {
 | 
			
		||||
            unsafe { Rc::from_raw(self.0) }
 | 
			
		||||
        }
 | 
			
		||||
        fn to_owned(self) -> KeyState {
 | 
			
		||||
@ -67,7 +78,7 @@ pub mod c {
 | 
			
		||||
                symbol: None,
 | 
			
		||||
            }
 | 
			
		||||
        ));
 | 
			
		||||
        CKeyState(Rc::into_raw(state))
 | 
			
		||||
        CKeyState::wrap(state)
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
@ -195,8 +206,8 @@ pub mod c {
 | 
			
		||||
    fn squeek_key_get_symbol(key: CKeyState) -> *const symbol::Symbol {
 | 
			
		||||
        key.borrow_mut(|key| {
 | 
			
		||||
            match key.symbol {
 | 
			
		||||
                /// This pointer stays after the function exits,
 | 
			
		||||
                /// so it must reference borrowed data and not any copy
 | 
			
		||||
                // This pointer stays after the function exits,
 | 
			
		||||
                // so it must reference borrowed data and not any copy
 | 
			
		||||
                Some(ref symbol) => symbol as *const symbol::Symbol,
 | 
			
		||||
                None => ptr::null(),
 | 
			
		||||
            }
 | 
			
		||||
@ -239,13 +250,51 @@ pub mod c {
 | 
			
		||||
            .expect("Couldn't convert string")
 | 
			
		||||
            .into_raw()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
        #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_get_action_name(
 | 
			
		||||
        key_name: *const c_char,
 | 
			
		||||
        key: CKeyState,
 | 
			
		||||
    ) -> *const c_char {
 | 
			
		||||
        let key_name = as_cstr(&key_name)
 | 
			
		||||
            .expect("Missing key name")
 | 
			
		||||
            .to_str()
 | 
			
		||||
            .expect("Bad key name");
 | 
			
		||||
 | 
			
		||||
        let symbol_name = match key.to_owned().symbol {
 | 
			
		||||
            Some(ref symbol) => match &symbol.action {
 | 
			
		||||
                symbol::Action::Submit { text: Some(text), .. } => {
 | 
			
		||||
                    Some(
 | 
			
		||||
                        text.clone()
 | 
			
		||||
                            .into_string().expect("Bad symbol")
 | 
			
		||||
                    )
 | 
			
		||||
                },
 | 
			
		||||
                _ => None
 | 
			
		||||
            },
 | 
			
		||||
            None => {
 | 
			
		||||
                eprintln!("Key {} has no symbol", key_name);
 | 
			
		||||
                None
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let inner = match symbol_name {
 | 
			
		||||
            Some(name) => format!("[ {} ]", name),
 | 
			
		||||
            _ => format!("[ ]"),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        CString::new(format!("        key <{}> {{ {} }};\n", key_name, inner))
 | 
			
		||||
            .expect("Couldn't convert string")
 | 
			
		||||
            .into_raw()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct KeyState {
 | 
			
		||||
    pressed: bool,
 | 
			
		||||
    locked: bool,
 | 
			
		||||
    keycode: u32,
 | 
			
		||||
    pub pressed: bool,
 | 
			
		||||
    pub locked: bool,
 | 
			
		||||
    pub keycode: u32,
 | 
			
		||||
    // TODO: remove the optionality of a symbol
 | 
			
		||||
    symbol: Option<symbol::Symbol>,
 | 
			
		||||
    pub symbol: Option<symbol::Symbol>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								src/layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/layout.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
#ifndef __LAYOUT_H
 | 
			
		||||
#define __LAYOUT_H
 | 
			
		||||
 | 
			
		||||
#include "inttypes.h"
 | 
			
		||||
 | 
			
		||||
#include "eek/eek-container.h"
 | 
			
		||||
#include "src/keyboard.h"
 | 
			
		||||
 | 
			
		||||
struct squeek_button;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
struct squeek_buttons;
 | 
			
		||||
 | 
			
		||||
typedef void (*ButtonCallback) (struct squeek_button *button, gpointer user_data);
 | 
			
		||||
 | 
			
		||||
struct squeek_buttons *squeek_buttons_new();
 | 
			
		||||
void squeek_buttons_free(struct squeek_buttons*);
 | 
			
		||||
void squeek_buttons_foreach(const struct squeek_buttons*,
 | 
			
		||||
                            ButtonCallback   callback,
 | 
			
		||||
                            gpointer      user_data);
 | 
			
		||||
struct squeek_button *squeek_buttons_find_by_position(
 | 
			
		||||
    const struct squeek_buttons *buttons,
 | 
			
		||||
    double x, double y,
 | 
			
		||||
    double origin_x, double origin_y,
 | 
			
		||||
    double angle);
 | 
			
		||||
void squeek_buttons_add(struct squeek_buttons*, const struct squeek_button* button);
 | 
			
		||||
void squeek_buttons_remove_key(struct squeek_buttons*, const struct squeek_key* key);
 | 
			
		||||
*/
 | 
			
		||||
struct squeek_button *squeek_button_new(uint32_t keycode, uint32_t oref);
 | 
			
		||||
struct squeek_button *squeek_button_new_with_state(const struct squeek_button* source);
 | 
			
		||||
uint32_t squeek_button_get_oref(const struct squeek_button*);
 | 
			
		||||
EekBounds squeek_button_get_bounds(const struct squeek_button*);
 | 
			
		||||
void squeek_button_set_bounds(struct squeek_button* button, EekBounds bounds);
 | 
			
		||||
 | 
			
		||||
struct squeek_symbol *squeek_button_get_symbol (
 | 
			
		||||
    const struct squeek_button *button);
 | 
			
		||||
struct squeek_key *squeek_button_get_key(struct squeek_button*);
 | 
			
		||||
uint32_t *squeek_button_has_key(const struct squeek_button* button,
 | 
			
		||||
                                const struct squeek_key *key);
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										147
									
								
								src/layout.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/layout.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
			
		||||
use std::cell::RefCell;
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
 | 
			
		||||
use ::symbol::*;
 | 
			
		||||
use ::keyboard::*;
 | 
			
		||||
 | 
			
		||||
/// Gathers stuff defined in C or called by C
 | 
			
		||||
pub mod c {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    use std::ptr;
 | 
			
		||||
 | 
			
		||||
    // The following defined in C
 | 
			
		||||
    
 | 
			
		||||
    /// The index in the relevant outline table
 | 
			
		||||
    #[repr(C)]
 | 
			
		||||
    #[derive(Clone)]
 | 
			
		||||
    pub struct OutlineRef(u32);
 | 
			
		||||
    
 | 
			
		||||
    /// Defined in eek-types.h
 | 
			
		||||
    #[repr(C)]
 | 
			
		||||
    #[derive(Clone)]
 | 
			
		||||
    pub struct Bounds {
 | 
			
		||||
        x: f64,
 | 
			
		||||
        y: f64,
 | 
			
		||||
        width: f64,
 | 
			
		||||
        height: f64
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_new(keycode: u32, oref: u32) -> *mut ::layout::Button {
 | 
			
		||||
        let state: Rc<RefCell<::keyboard::KeyState>> = Rc::new(RefCell::new(
 | 
			
		||||
            ::keyboard::KeyState {
 | 
			
		||||
                pressed: false,
 | 
			
		||||
                locked: false,
 | 
			
		||||
                keycode: keycode,
 | 
			
		||||
                symbol: None,
 | 
			
		||||
            }
 | 
			
		||||
        ));
 | 
			
		||||
        Box::into_raw(Box::new(::layout::Button {
 | 
			
		||||
            oref: OutlineRef(oref),
 | 
			
		||||
            bounds: None,
 | 
			
		||||
            state: state,
 | 
			
		||||
        }))
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_new_with_state(source: *mut ::layout::Button) -> *mut ::layout::Button {
 | 
			
		||||
        let source = unsafe { &*source };
 | 
			
		||||
        let button = Box::new(source.clone());
 | 
			
		||||
        Box::into_raw(button)
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_oref(button: *const ::layout::Button) -> u32 {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        button.oref.0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Bounds transparently mapped to C, therefore no pointer needed
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_bounds(button: *const ::layout::Button) -> Bounds {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        match &button.bounds {
 | 
			
		||||
            Some(bounds) => bounds.clone(),
 | 
			
		||||
            None => panic!("Button doesn't have any bounds yet"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Set bounds by consuming the value
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_set_bounds(button: *mut ::layout::Button, bounds: Bounds) {
 | 
			
		||||
        let button = unsafe { &mut *button };
 | 
			
		||||
        button.bounds = Some(bounds);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Borrow a new reference to key state. Doesn't need freeing
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_key(
 | 
			
		||||
        button: *mut ::layout::Button
 | 
			
		||||
    ) -> ::keyboard::c::CKeyState {
 | 
			
		||||
        let button = unsafe { &mut *button };
 | 
			
		||||
        ::keyboard::c::CKeyState::wrap(button.state.clone())
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Really should just return the label
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_symbol(
 | 
			
		||||
        button: *const ::layout::Button,
 | 
			
		||||
    ) -> *const Symbol {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        let state = button.state.borrow();
 | 
			
		||||
        match state.symbol {
 | 
			
		||||
            Some(ref symbol) => symbol as *const Symbol,
 | 
			
		||||
            None => ptr::null(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_has_key(
 | 
			
		||||
        button: *const ::layout::Button,
 | 
			
		||||
        state: ::keyboard::c::CKeyState,
 | 
			
		||||
    ) -> u32 {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        let state = state.unwrap();
 | 
			
		||||
        let equal = Rc::ptr_eq(&button.state, &state);
 | 
			
		||||
        Rc::into_raw(state); // Prevent dropping
 | 
			
		||||
        equal as u32
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[cfg(test)]
 | 
			
		||||
    mod test {
 | 
			
		||||
        use super::*;
 | 
			
		||||
        
 | 
			
		||||
        #[test]
 | 
			
		||||
        fn button_has_key() {
 | 
			
		||||
            let button = squeek_button_new(0, 0);
 | 
			
		||||
            let state = squeek_button_get_key(button);
 | 
			
		||||
            assert_eq!(squeek_button_has_key(button, state.clone()), 1);
 | 
			
		||||
            let other_button = squeek_button_new(0, 0);
 | 
			
		||||
            assert_eq!(squeek_button_has_key(other_button, state.clone()), 0);
 | 
			
		||||
            let other_state = ::keyboard::c::squeek_key_new(0);
 | 
			
		||||
            assert_eq!(squeek_button_has_key(button, other_state), 0);
 | 
			
		||||
            let shared_button = squeek_button_new_with_state(button);
 | 
			
		||||
            assert_eq!(squeek_button_has_key(shared_button, state), 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The graphical representation of a button
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
pub struct Button {
 | 
			
		||||
    oref: c::OutlineRef,
 | 
			
		||||
    /// TODO: abolish Option, buttons should be created with bounds fully formed
 | 
			
		||||
    bounds: Option<c::Bounds>,
 | 
			
		||||
    /// current state, shared with other buttons
 | 
			
		||||
    pub state: Rc<RefCell<KeyState>>,
 | 
			
		||||
}
 | 
			
		||||
@ -3,5 +3,6 @@ mod bitflags;
 | 
			
		||||
 | 
			
		||||
mod imservice;
 | 
			
		||||
mod keyboard;
 | 
			
		||||
mod layout;
 | 
			
		||||
mod symbol;
 | 
			
		||||
mod util;
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,6 @@ sources = [
 | 
			
		||||
  '../eek/eek-container.c',
 | 
			
		||||
  '../eek/eek-element.c',
 | 
			
		||||
  '../eek/eek-gtk-keyboard.c',
 | 
			
		||||
  '../eek/eek-key.c',
 | 
			
		||||
  '../eek/eek-keyboard.c',
 | 
			
		||||
  '../eek/eek-keyboard-drawing.c',
 | 
			
		||||
  '../eek/eek-keysym.c',
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user