Merge branch 'pin-keyboard' into 'master'
Use special pin keyboard See merge request World/Phosh/squeekboard!492
This commit is contained in:
		
							
								
								
									
										6
									
								
								data/common.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								data/common.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					/* Theme independent style */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sq_view.pin sq_button {
 | 
				
			||||||
 | 
					    border-radius: 0px;
 | 
				
			||||||
 | 
					    margin: 1px 1px 1px 1px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								data/keyboards/pin/us.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								data/keyboards/pin/us.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					margins: { top: 4, side: 0, bottom: 4 }
 | 
				
			||||||
 | 
					outlines:
 | 
				
			||||||
 | 
					    default: { width: 120, height: 52 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					views:
 | 
				
			||||||
 | 
					    base:
 | 
				
			||||||
 | 
					        - "1 2 3"
 | 
				
			||||||
 | 
					        - "4 5 6"
 | 
				
			||||||
 | 
					        - "7 8 9"
 | 
				
			||||||
 | 
					        - "BackSpace 0 Return"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					buttons:
 | 
				
			||||||
 | 
					    BackSpace:
 | 
				
			||||||
 | 
					        icon: "edit-clear-symbolic"
 | 
				
			||||||
 | 
					        action: erase
 | 
				
			||||||
 | 
					    Return:
 | 
				
			||||||
 | 
					        icon: "key-enter"
 | 
				
			||||||
 | 
					        keysym: "Return"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
<gresources>
 | 
					<gresources>
 | 
				
			||||||
  <gresource prefix="/sm/puri/squeekboard">
 | 
					  <gresource prefix="/sm/puri/squeekboard">
 | 
				
			||||||
 | 
					   <file compressed="true">common.css</file>
 | 
				
			||||||
   <file compressed="true">style.css</file>
 | 
					   <file compressed="true">style.css</file>
 | 
				
			||||||
   <file compressed="true">style-Adwaita:dark.css</file>
 | 
					   <file compressed="true">style-Adwaita:dark.css</file>
 | 
				
			||||||
   <file compressed="true" preprocess="xml-stripblanks">popup.ui</file>
 | 
					   <file compressed="true" preprocess="xml-stripblanks">popup.ui</file>
 | 
				
			||||||
 | 
				
			|||||||
@ -58,3 +58,5 @@ sq_button.small {
 | 
				
			|||||||
    background: #1c71d8;
 | 
					    background: #1c71d8;
 | 
				
			||||||
    border-color: #3584e4;
 | 
					    border-color: #3584e4;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@import url("resource:///sm/puri/squeekboard/common.css");
 | 
				
			||||||
 | 
				
			|||||||
@ -61,3 +61,5 @@ sq_button.small {
 | 
				
			|||||||
    background: mix(@theme_selected_bg_color, @theme_bg_color, 0.4); /*#1c71d8;*/
 | 
					    background: mix(@theme_selected_bg_color, @theme_bg_color, 0.4); /*#1c71d8;*/
 | 
				
			||||||
    border-color: @borders; /*#3584e4;*/
 | 
					    border-color: @borders; /*#3584e4;*/
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@import url("resource:///sm/puri/squeekboard/common.css");
 | 
				
			||||||
 | 
				
			|||||||
@ -315,6 +315,7 @@ eek_renderer_new (LevelKeyboard  *keyboard,
 | 
				
			|||||||
    renderer_init(renderer);
 | 
					    renderer_init(renderer);
 | 
				
			||||||
    renderer->pcontext = pcontext;
 | 
					    renderer->pcontext = pcontext;
 | 
				
			||||||
    g_object_ref (renderer->pcontext);
 | 
					    g_object_ref (renderer->pcontext);
 | 
				
			||||||
 | 
					    const char *purpose_class = "normal";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Create a style context for the layout */
 | 
					    /* Create a style context for the layout */
 | 
				
			||||||
    GtkWidgetPath *path = gtk_widget_path_new();
 | 
					    GtkWidgetPath *path = gtk_widget_path_new();
 | 
				
			||||||
@ -336,6 +337,55 @@ eek_renderer_new (LevelKeyboard  *keyboard,
 | 
				
			|||||||
    if (squeek_layout_get_kind(keyboard->layout) == ARRANGEMENT_KIND_WIDE) {
 | 
					    if (squeek_layout_get_kind(keyboard->layout) == ARRANGEMENT_KIND_WIDE) {
 | 
				
			||||||
        gtk_widget_path_iter_add_class(path, -1, "wide");
 | 
					        gtk_widget_path_iter_add_class(path, -1, "wide");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    /* Add style classes based on purpose */
 | 
				
			||||||
 | 
					    switch (squeek_layout_get_purpose (keyboard->layout)) {
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL:
 | 
				
			||||||
 | 
					        purpose_class = "normal";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_ALPHA:
 | 
				
			||||||
 | 
					        purpose_class = "alpha";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS:
 | 
				
			||||||
 | 
					        purpose_class = "digits";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
 | 
				
			||||||
 | 
					        purpose_class = "number";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
 | 
				
			||||||
 | 
					        purpose_class = "phone";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL:
 | 
				
			||||||
 | 
					        purpose_class = "url";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_EMAIL:
 | 
				
			||||||
 | 
					        purpose_class = "email";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NAME:
 | 
				
			||||||
 | 
					        purpose_class = "name";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PASSWORD:
 | 
				
			||||||
 | 
					        purpose_class = "password";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PIN:
 | 
				
			||||||
 | 
					        purpose_class = "pin";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATE:
 | 
				
			||||||
 | 
					        purpose_class = "date";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TIME:
 | 
				
			||||||
 | 
					        purpose_class = "time";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DATETIME:
 | 
				
			||||||
 | 
					        purpose_class = "datetime";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_TERMINAL:
 | 
				
			||||||
 | 
					        purpose_class = "terminal";
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        g_warning ("Unknown input purpose %d", squeek_layout_get_purpose(keyboard->layout));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    gtk_widget_path_iter_add_class(path, -1, purpose_class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gtk_widget_path_append_type(path, button_type());
 | 
					    gtk_widget_path_append_type(path, button_type());
 | 
				
			||||||
    renderer->button_context = gtk_style_context_new ();
 | 
					    renderer->button_context = gtk_style_context_new ();
 | 
				
			||||||
    gtk_style_context_set_path(renderer->button_context, path);
 | 
					    gtk_style_context_set_path(renderer->button_context, path);
 | 
				
			||||||
 | 
				
			|||||||
@ -61,7 +61,7 @@ pub mod c {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (kind, layout) = load_layout_data_with_fallback(&name, type_, variant, overlay_str);
 | 
					        let (kind, layout) = load_layout_data_with_fallback(&name, type_, variant, overlay_str);
 | 
				
			||||||
        let layout = ::layout::Layout::new(layout, kind);
 | 
					        let layout = ::layout::Layout::new(layout, kind, variant);
 | 
				
			||||||
        Box::into_raw(Box::new(layout))
 | 
					        Box::into_raw(Box::new(layout))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -168,9 +168,9 @@ fn get_directory_string(
 | 
				
			|||||||
        None => match content_purpose {
 | 
					        None => match content_purpose {
 | 
				
			||||||
            ContentPurpose::Number => Special("number"),
 | 
					            ContentPurpose::Number => Special("number"),
 | 
				
			||||||
            ContentPurpose::Digits => Special("number"),
 | 
					            ContentPurpose::Digits => Special("number"),
 | 
				
			||||||
            ContentPurpose::Pin => Special("number"),
 | 
					 | 
				
			||||||
            ContentPurpose::Phone => Special("number"),
 | 
					            ContentPurpose::Phone => Special("number"),
 | 
				
			||||||
            ContentPurpose::Terminal => Special("terminal"),
 | 
					            ContentPurpose::Terminal => Special("terminal"),
 | 
				
			||||||
 | 
					            ContentPurpose::Pin => Special("pin"),
 | 
				
			||||||
            _ => Default,
 | 
					            _ => Default,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        Some(overlay) => Special(overlay),
 | 
					        Some(overlay) => Special(overlay),
 | 
				
			||||||
 | 
				
			|||||||
@ -233,7 +233,7 @@ bitflags!{
 | 
				
			|||||||
/// use rs::imservice::ContentPurpose;
 | 
					/// use rs::imservice::ContentPurpose;
 | 
				
			||||||
/// assert_eq!(ContentPurpose::Alpha as u32, 1);
 | 
					/// assert_eq!(ContentPurpose::Alpha as u32, 1);
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Copy, Clone)]
 | 
				
			||||||
pub enum ContentPurpose {
 | 
					pub enum ContentPurpose {
 | 
				
			||||||
    Normal = 0,
 | 
					    Normal = 0,
 | 
				
			||||||
    Alpha = 1,
 | 
					    Alpha = 1,
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,7 @@ struct transformation squeek_layout_calculate_transformation(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct squeek_layout *squeek_load_layout(const char *name, uint32_t type, uint32_t variant_type, const char *overlay_name);
 | 
					struct squeek_layout *squeek_load_layout(const char *name, uint32_t type, uint32_t variant_type, const char *overlay_name);
 | 
				
			||||||
enum squeek_arrangement_kind squeek_layout_get_kind(const struct squeek_layout *);
 | 
					enum squeek_arrangement_kind squeek_layout_get_kind(const struct squeek_layout *);
 | 
				
			||||||
 | 
					uint32_t squeek_layout_get_purpose(const struct squeek_layout *);
 | 
				
			||||||
void squeek_layout_free(struct squeek_layout*);
 | 
					void squeek_layout_free(struct squeek_layout*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void squeek_layout_release(struct squeek_layout *layout,
 | 
					void squeek_layout_release(struct squeek_layout *layout,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,17 +1,17 @@
 | 
				
			|||||||
/*!
 | 
					/*!
 | 
				
			||||||
 * Layout-related data.
 | 
					 * Layout-related data.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 * The `View` contains `Row`s and each `Row` contains `Button`s.
 | 
					 * The `View` contains `Row`s and each `Row` contains `Button`s.
 | 
				
			||||||
 * They carry data relevant to their positioning only,
 | 
					 * They carry data relevant to their positioning only,
 | 
				
			||||||
 * except the Button, which also carries some data
 | 
					 * except the Button, which also carries some data
 | 
				
			||||||
 * about its appearance and function.
 | 
					 * about its appearance and function.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 * The layout is determined bottom-up, by measuring `Button` sizes,
 | 
					 * The layout is determined bottom-up, by measuring `Button` sizes,
 | 
				
			||||||
 * deriving `Row` sizes from them, and then centering them within the `View`.
 | 
					 * deriving `Row` sizes from them, and then centering them within the `View`.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 * That makes the `View` position immutable,
 | 
					 * That makes the `View` position immutable,
 | 
				
			||||||
 * and therefore different than the other positions.
 | 
					 * and therefore different than the other positions.
 | 
				
			||||||
 * 
 | 
					 *
 | 
				
			||||||
 * Note that it might be a better idea
 | 
					 * Note that it might be a better idea
 | 
				
			||||||
 * to make `View` position depend on its contents,
 | 
					 * to make `View` position depend on its contents,
 | 
				
			||||||
 * and let the renderer scale and center it within the widget.
 | 
					 * and let the renderer scale and center it within the widget.
 | 
				
			||||||
@ -32,6 +32,8 @@ use ::manager;
 | 
				
			|||||||
use ::submission::{ Submission, SubmitData, Timestamp };
 | 
					use ::submission::{ Submission, SubmitData, Timestamp };
 | 
				
			||||||
use ::util::find_max_double;
 | 
					use ::util::find_max_double;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ::imservice::ContentPurpose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Traits
 | 
					// Traits
 | 
				
			||||||
use std::borrow::Borrow;
 | 
					use std::borrow::Borrow;
 | 
				
			||||||
use ::logging::Warn;
 | 
					use ::logging::Warn;
 | 
				
			||||||
@ -64,7 +66,7 @@ pub mod c {
 | 
				
			|||||||
        pub x: f64,
 | 
					        pub x: f64,
 | 
				
			||||||
        pub y: f64,
 | 
					        pub y: f64,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    impl Add for Point {
 | 
					    impl Add for Point {
 | 
				
			||||||
        type Output = Self;
 | 
					        type Output = Self;
 | 
				
			||||||
        fn add(self, other: Self) -> Self {
 | 
					        fn add(self, other: Self) -> Self {
 | 
				
			||||||
@ -81,7 +83,7 @@ pub mod c {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    impl Sub<&Point> for Point {
 | 
					    impl Sub<&Point> for Point {
 | 
				
			||||||
        type Output = Point;
 | 
					        type Output = Point;
 | 
				
			||||||
        fn sub(self, other: &Point) -> Point {
 | 
					        fn sub(self, other: &Point) -> Point {
 | 
				
			||||||
@ -152,14 +154,14 @@ pub mod c {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    // This is constructed only in C, no need for warnings
 | 
					    // This is constructed only in C, no need for warnings
 | 
				
			||||||
    #[allow(dead_code)]
 | 
					    #[allow(dead_code)]
 | 
				
			||||||
    #[repr(transparent)]
 | 
					    #[repr(transparent)]
 | 
				
			||||||
    pub struct LevelKeyboard(*const c_void);
 | 
					    pub struct LevelKeyboard(*const c_void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
 | 
					    // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    /// Positions the layout contents within the available space.
 | 
					    /// Positions the layout contents within the available space.
 | 
				
			||||||
    /// The origin of the transformation is the point inside the margins.
 | 
					    /// The origin of the transformation is the point inside the margins.
 | 
				
			||||||
    #[no_mangle]
 | 
					    #[no_mangle]
 | 
				
			||||||
@ -183,6 +185,13 @@ pub mod c {
 | 
				
			|||||||
        layout.kind.clone() as u32
 | 
					        layout.kind.clone() as u32
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[no_mangle]
 | 
				
			||||||
 | 
					    pub extern "C"
 | 
				
			||||||
 | 
					    fn squeek_layout_get_purpose(layout: *const Layout) -> u32 {
 | 
				
			||||||
 | 
					        let layout = unsafe { &*layout };
 | 
				
			||||||
 | 
					        layout.purpose.clone() as u32
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[no_mangle]
 | 
					    #[no_mangle]
 | 
				
			||||||
    pub extern "C"
 | 
					    pub extern "C"
 | 
				
			||||||
    fn squeek_layout_free(layout: *mut Layout) {
 | 
					    fn squeek_layout_free(layout: *mut Layout) {
 | 
				
			||||||
@ -271,7 +280,7 @@ pub mod c {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            let state = layout.find_button_by_position(point)
 | 
					            let state = layout.find_button_by_position(point)
 | 
				
			||||||
                .map(|place| place.button.state.clone());
 | 
					                .map(|place| place.button.state.clone());
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            if let Some(state) = state {
 | 
					            if let Some(state) = state {
 | 
				
			||||||
                seat::handle_press_key(
 | 
					                seat::handle_press_key(
 | 
				
			||||||
                    layout,
 | 
					                    layout,
 | 
				
			||||||
@ -311,7 +320,7 @@ pub mod c {
 | 
				
			|||||||
            let point = ui_backend.widget_to_layout.forward(
 | 
					            let point = ui_backend.widget_to_layout.forward(
 | 
				
			||||||
                Point { x: x_widget, y: y_widget }
 | 
					                Point { x: x_widget, y: y_widget }
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            let pressed = layout.pressed_keys.clone();
 | 
					            let pressed = layout.pressed_keys.clone();
 | 
				
			||||||
            let button_info = {
 | 
					            let button_info = {
 | 
				
			||||||
                let place = layout.find_button_by_position(point);
 | 
					                let place = layout.find_button_by_position(point);
 | 
				
			||||||
@ -370,11 +379,11 @@ pub mod c {
 | 
				
			|||||||
        #[cfg(test)]
 | 
					        #[cfg(test)]
 | 
				
			||||||
        mod test {
 | 
					        mod test {
 | 
				
			||||||
            use super::*;
 | 
					            use super::*;
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            fn near(a: f64, b: f64) -> bool {
 | 
					            fn near(a: f64, b: f64) -> bool {
 | 
				
			||||||
                (a - b).abs() < ((a + b) * 0.001f64).abs()
 | 
					                (a - b).abs() < ((a + b) * 0.001f64).abs()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            #[test]
 | 
					            #[test]
 | 
				
			||||||
            fn transform_back() {
 | 
					            fn transform_back() {
 | 
				
			||||||
                let transform = Transformation {
 | 
					                let transform = Transformation {
 | 
				
			||||||
@ -413,7 +422,7 @@ pub enum Label {
 | 
				
			|||||||
/// The graphical representation of a button
 | 
					/// The graphical representation of a button
 | 
				
			||||||
#[derive(Clone, Debug)]
 | 
					#[derive(Clone, Debug)]
 | 
				
			||||||
pub struct Button {
 | 
					pub struct Button {
 | 
				
			||||||
    /// ID string, e.g. for CSS 
 | 
					    /// ID string, e.g. for CSS
 | 
				
			||||||
    pub name: CString,
 | 
					    pub name: CString,
 | 
				
			||||||
    /// Label to display to the user
 | 
					    /// Label to display to the user
 | 
				
			||||||
    pub label: Label,
 | 
					    pub label: Label,
 | 
				
			||||||
@ -573,11 +582,11 @@ impl View {
 | 
				
			|||||||
            offset: &row.0 + c::Point { x: button.0, y: 0.0 },
 | 
					            offset: &row.0 + c::Point { x: button.0, y: 0.0 },
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    pub fn get_size(&self) -> Size {
 | 
					    pub fn get_size(&self) -> Size {
 | 
				
			||||||
        self.size.clone()
 | 
					        self.size.clone()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    /// Returns positioned rows, with appropriate x offsets (centered)
 | 
					    /// Returns positioned rows, with appropriate x offsets (centered)
 | 
				
			||||||
    pub fn get_rows(&self) -> &Vec<(c::Point, Row)> {
 | 
					    pub fn get_rows(&self) -> &Vec<(c::Point, Row)> {
 | 
				
			||||||
        &self.rows
 | 
					        &self.rows
 | 
				
			||||||
@ -627,6 +636,7 @@ pub enum LatchedState {
 | 
				
			|||||||
pub struct Layout {
 | 
					pub struct Layout {
 | 
				
			||||||
    pub margins: Margins,
 | 
					    pub margins: Margins,
 | 
				
			||||||
    pub kind: ArrangementKind,
 | 
					    pub kind: ArrangementKind,
 | 
				
			||||||
 | 
					    pub purpose: ContentPurpose,
 | 
				
			||||||
    pub current_view: String,
 | 
					    pub current_view: String,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If current view is latched,
 | 
					    // If current view is latched,
 | 
				
			||||||
@ -676,7 +686,7 @@ impl fmt::Display for NoSuchView {
 | 
				
			|||||||
// The usage of &mut on Rc<RefCell<KeyState>> doesn't mean anything special.
 | 
					// The usage of &mut on Rc<RefCell<KeyState>> doesn't mean anything special.
 | 
				
			||||||
// Cloning could also be used.
 | 
					// Cloning could also be used.
 | 
				
			||||||
impl Layout {
 | 
					impl Layout {
 | 
				
			||||||
    pub fn new(data: LayoutData, kind: ArrangementKind) -> Layout {
 | 
					    pub fn new(data: LayoutData, kind: ArrangementKind, purpose: ContentPurpose) -> Layout {
 | 
				
			||||||
        Layout {
 | 
					        Layout {
 | 
				
			||||||
            kind,
 | 
					            kind,
 | 
				
			||||||
            current_view: "base".to_owned(),
 | 
					            current_view: "base".to_owned(),
 | 
				
			||||||
@ -685,6 +695,7 @@ impl Layout {
 | 
				
			|||||||
            keymaps: data.keymaps,
 | 
					            keymaps: data.keymaps,
 | 
				
			||||||
            pressed_keys: HashSet::new(),
 | 
					            pressed_keys: HashSet::new(),
 | 
				
			||||||
            margins: data.margins,
 | 
					            margins: data.margins,
 | 
				
			||||||
 | 
					            purpose,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -731,7 +742,7 @@ impl Layout {
 | 
				
			|||||||
            ),
 | 
					            ),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    pub fn calculate_transformation(
 | 
					    pub fn calculate_transformation(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        available: Size,
 | 
					        available: Size,
 | 
				
			||||||
@ -770,7 +781,7 @@ impl Layout {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    fn apply_view_transition(
 | 
					    fn apply_view_transition(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
        action: &Action,
 | 
					        action: &Action,
 | 
				
			||||||
@ -812,7 +823,7 @@ impl Layout {
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Although the state is not defined at the keys
 | 
					    /// Although the state is not defined at the keys
 | 
				
			||||||
    /// (it's in the relationship between view and action),
 | 
					    /// (it's in the relationship between view and action),
 | 
				
			||||||
    /// keys go through the following stages when clicked repeatedly: 
 | 
					    /// keys go through the following stages when clicked repeatedly:
 | 
				
			||||||
    /// unlocked+unlatched -> locked+latched -> locked+unlatched
 | 
					    /// unlocked+unlatched -> locked+latched -> locked+unlatched
 | 
				
			||||||
    /// -> unlocked+unlatched
 | 
					    /// -> unlocked+unlatched
 | 
				
			||||||
    fn process_action_for_view<'a>(
 | 
					    fn process_action_for_view<'a>(
 | 
				
			||||||
@ -906,7 +917,7 @@ mod procedures {
 | 
				
			|||||||
                })
 | 
					                })
 | 
				
			||||||
        }).collect()
 | 
					        }).collect()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    #[cfg(test)]
 | 
					    #[cfg(test)]
 | 
				
			||||||
    mod test {
 | 
					    mod test {
 | 
				
			||||||
        use super::*;
 | 
					        use super::*;
 | 
				
			||||||
@ -1113,7 +1124,7 @@ mod test {
 | 
				
			|||||||
            state: state,
 | 
					            state: state,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn latch_lock_unlock() {
 | 
					    fn latch_lock_unlock() {
 | 
				
			||||||
        let action = Action::LockView {
 | 
					        let action = Action::LockView {
 | 
				
			||||||
@ -1152,7 +1163,7 @@ mod test {
 | 
				
			|||||||
            latches: true,
 | 
					            latches: true,
 | 
				
			||||||
            looks_locked_from: vec![],
 | 
					            looks_locked_from: vec![],
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        let submit = Action::Erase;
 | 
					        let submit = Action::Erase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let view = View::new(vec![(
 | 
					        let view = View::new(vec![(
 | 
				
			||||||
@ -1194,7 +1205,8 @@ mod test {
 | 
				
			|||||||
                "base".into() => (c::Point { x: 0.0, y: 0.0 }, view.clone()),
 | 
					                "base".into() => (c::Point { x: 0.0, y: 0.0 }, view.clone()),
 | 
				
			||||||
                "locked".into() => (c::Point { x: 0.0, y: 0.0 }, view),
 | 
					                "locked".into() => (c::Point { x: 0.0, y: 0.0 }, view),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        };        
 | 
					            purpose: ContentPurpose::Normal,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Basic cycle
 | 
					        // Basic cycle
 | 
				
			||||||
        layout.apply_view_transition(&switch);
 | 
					        layout.apply_view_transition(&switch);
 | 
				
			||||||
@ -1220,14 +1232,14 @@ mod test {
 | 
				
			|||||||
            latches: true,
 | 
					            latches: true,
 | 
				
			||||||
            looks_locked_from: vec![],
 | 
					            looks_locked_from: vec![],
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        let unswitch = Action::LockView {
 | 
					        let unswitch = Action::LockView {
 | 
				
			||||||
            lock: "locked".into(),
 | 
					            lock: "locked".into(),
 | 
				
			||||||
            unlock: "unlocked".into(),
 | 
					            unlock: "unlocked".into(),
 | 
				
			||||||
            latches: false,
 | 
					            latches: false,
 | 
				
			||||||
            looks_locked_from: vec![],
 | 
					            looks_locked_from: vec![],
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        let submit = Action::Erase;
 | 
					        let submit = Action::Erase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let view = View::new(vec![(
 | 
					        let view = View::new(vec![(
 | 
				
			||||||
@ -1270,7 +1282,8 @@ mod test {
 | 
				
			|||||||
                "locked".into() => (c::Point { x: 0.0, y: 0.0 }, view.clone()),
 | 
					                "locked".into() => (c::Point { x: 0.0, y: 0.0 }, view.clone()),
 | 
				
			||||||
                "unlocked".into() => (c::Point { x: 0.0, y: 0.0 }, view),
 | 
					                "unlocked".into() => (c::Point { x: 0.0, y: 0.0 }, view),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        };        
 | 
					            purpose: ContentPurpose::Normal,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        layout.apply_view_transition(&switch);
 | 
					        layout.apply_view_transition(&switch);
 | 
				
			||||||
        assert_eq!(&layout.current_view, "locked");
 | 
					        assert_eq!(&layout.current_view, "locked");
 | 
				
			||||||
@ -1286,14 +1299,14 @@ mod test {
 | 
				
			|||||||
            latches: true,
 | 
					            latches: true,
 | 
				
			||||||
            looks_locked_from: vec![],
 | 
					            looks_locked_from: vec![],
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        let switch_again = Action::LockView {
 | 
					        let switch_again = Action::LockView {
 | 
				
			||||||
            lock: "ĄĘ".into(),
 | 
					            lock: "ĄĘ".into(),
 | 
				
			||||||
            unlock: "locked".into(),
 | 
					            unlock: "locked".into(),
 | 
				
			||||||
            latches: true,
 | 
					            latches: true,
 | 
				
			||||||
            looks_locked_from: vec![],
 | 
					            looks_locked_from: vec![],
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        let submit = Action::Erase;
 | 
					        let submit = Action::Erase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let view = View::new(vec![(
 | 
					        let view = View::new(vec![(
 | 
				
			||||||
@ -1336,7 +1349,8 @@ mod test {
 | 
				
			|||||||
                "locked".into() => (c::Point { x: 0.0, y: 0.0 }, view.clone()),
 | 
					                "locked".into() => (c::Point { x: 0.0, y: 0.0 }, view.clone()),
 | 
				
			||||||
                "ĄĘ".into() => (c::Point { x: 0.0, y: 0.0 }, view),
 | 
					                "ĄĘ".into() => (c::Point { x: 0.0, y: 0.0 }, view),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        };        
 | 
					            purpose: ContentPurpose::Normal,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Latch twice, then Ąto-unlatch across 2 levels
 | 
					        // Latch twice, then Ąto-unlatch across 2 levels
 | 
				
			||||||
        layout.apply_view_transition(&switch);
 | 
					        layout.apply_view_transition(&switch);
 | 
				
			||||||
@ -1436,6 +1450,7 @@ mod test {
 | 
				
			|||||||
            views: hashmap! {
 | 
					            views: hashmap! {
 | 
				
			||||||
                String::new() => (c::Point { x: 0.0, y: 0.0 }, view),
 | 
					                String::new() => (c::Point { x: 0.0, y: 0.0 }, view),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            purpose: ContentPurpose::Normal,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        assert_eq!(
 | 
					        assert_eq!(
 | 
				
			||||||
            layout.calculate_inner_size(),
 | 
					            layout.calculate_inner_size(),
 | 
				
			||||||
 | 
				
			|||||||
@ -93,6 +93,7 @@ static KEYBOARDS: &[(&'static str, &'static str)] = &[
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Others
 | 
					    // Others
 | 
				
			||||||
    ("number/us", include_str!("../data/keyboards/number/us.yaml")),
 | 
					    ("number/us", include_str!("../data/keyboards/number/us.yaml")),
 | 
				
			||||||
 | 
					    ("pin/us", include_str!("../data/keyboards/pin/us.yaml")),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Terminal
 | 
					    // Terminal
 | 
				
			||||||
    ("terminal/fr", include_str!("../data/keyboards/terminal/fr.yaml")),
 | 
					    ("terminal/fr", include_str!("../data/keyboards/terminal/fr.yaml")),
 | 
				
			||||||
 | 
				
			|||||||
@ -100,6 +100,7 @@ foreach layout : [
 | 
				
			|||||||
    # Block: Not languages.
 | 
					    # Block: Not languages.
 | 
				
			||||||
    'emoji/us',
 | 
					    'emoji/us',
 | 
				
			||||||
    'number/us',
 | 
					    'number/us',
 | 
				
			||||||
 | 
					    'pin/us',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
    extra = []
 | 
					    extra = []
 | 
				
			||||||
    if layout.startswith('emoji/')
 | 
					    if layout.startswith('emoji/')
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user