layout: Keep kind metadata in loaded layouts
It will come useful for applying per-kind styling later without having to give each layout a new stylesheet
This commit is contained in:
		@ -38,7 +38,7 @@ typedef struct _EekRendererPrivate
 | 
			
		||||
    LevelKeyboard *keyboard;
 | 
			
		||||
    PangoContext *pcontext;
 | 
			
		||||
    GtkCssProvider *css_provider;
 | 
			
		||||
    GtkStyleContext *layout_context;
 | 
			
		||||
    GtkStyleContext *view_context;
 | 
			
		||||
    GtkStyleContext *button_context; // TODO: maybe move a copy to each button
 | 
			
		||||
 | 
			
		||||
    gdouble border_width;
 | 
			
		||||
@ -131,7 +131,7 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
    EekColor foreground;
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_foreground_color (priv->layout_context, &foreground);
 | 
			
		||||
    eek_renderer_get_foreground_color (priv->view_context, &foreground);
 | 
			
		||||
 | 
			
		||||
    EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard));
 | 
			
		||||
 | 
			
		||||
@ -142,11 +142,11 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /* Paint the background covering the entire widget area */
 | 
			
		||||
    gtk_render_background (priv->layout_context,
 | 
			
		||||
    gtk_render_background (priv->view_context,
 | 
			
		||||
                           data.cr,
 | 
			
		||||
                           0, 0,
 | 
			
		||||
                           priv->allocation_width, priv->allocation_height);
 | 
			
		||||
    gtk_render_frame (priv->layout_context,
 | 
			
		||||
    gtk_render_frame (priv->view_context,
 | 
			
		||||
                      data.cr,
 | 
			
		||||
                      0, 0,
 | 
			
		||||
                      priv->allocation_width, priv->allocation_height);
 | 
			
		||||
@ -596,7 +596,7 @@ static GType new_type(char *name) {
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GType layout_type() {
 | 
			
		||||
static GType view_type() {
 | 
			
		||||
    static GType type = 0;
 | 
			
		||||
    if (!type) {
 | 
			
		||||
        type = new_type("sq_view");
 | 
			
		||||
@ -649,31 +649,6 @@ eek_renderer_init (EekRenderer *self)
 | 
			
		||||
    priv->css_provider = gtk_css_provider_new ();
 | 
			
		||||
    gtk_css_provider_load_from_resource (priv->css_provider,
 | 
			
		||||
        "/sm/puri/squeekboard/style.css");
 | 
			
		||||
 | 
			
		||||
    /* Create a style context for the layout */
 | 
			
		||||
    GtkWidgetPath *path = gtk_widget_path_new();
 | 
			
		||||
    gtk_widget_path_append_type(path, layout_type());
 | 
			
		||||
 | 
			
		||||
    priv->layout_context = gtk_style_context_new();
 | 
			
		||||
    gtk_style_context_set_path(priv->layout_context, path);
 | 
			
		||||
    gtk_widget_path_unref(path);
 | 
			
		||||
    gtk_style_context_add_provider (priv->layout_context,
 | 
			
		||||
        GTK_STYLE_PROVIDER(priv->css_provider),
 | 
			
		||||
        GTK_STYLE_PROVIDER_PRIORITY_USER);
 | 
			
		||||
 | 
			
		||||
    /* Create a style context for the buttons */
 | 
			
		||||
    path = gtk_widget_path_new();
 | 
			
		||||
    gtk_widget_path_append_type(path, layout_type());
 | 
			
		||||
    gtk_widget_path_append_type(path, button_type());
 | 
			
		||||
    priv->button_context = gtk_style_context_new ();
 | 
			
		||||
    gtk_style_context_set_path(priv->button_context, path);
 | 
			
		||||
    gtk_widget_path_unref(path);
 | 
			
		||||
 | 
			
		||||
    gtk_style_context_set_parent(priv->button_context, priv->layout_context);
 | 
			
		||||
    gtk_style_context_set_state (priv->button_context, GTK_STATE_FLAG_NORMAL);
 | 
			
		||||
    gtk_style_context_add_provider (priv->button_context,
 | 
			
		||||
        GTK_STYLE_PROVIDER(priv->css_provider),
 | 
			
		||||
        GTK_STYLE_PROVIDER_PRIORITY_USER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -702,6 +677,37 @@ eek_renderer_new (LevelKeyboard  *keyboard,
 | 
			
		||||
                         NULL);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
    priv->keyboard = keyboard;
 | 
			
		||||
 | 
			
		||||
    /* Create a style context for the layout */
 | 
			
		||||
    GtkWidgetPath *path = gtk_widget_path_new();
 | 
			
		||||
    gtk_widget_path_append_type(path, view_type());
 | 
			
		||||
 | 
			
		||||
    priv->view_context = gtk_style_context_new();
 | 
			
		||||
    gtk_style_context_set_path(priv->view_context, path);
 | 
			
		||||
    gtk_widget_path_unref(path);
 | 
			
		||||
    if (squeek_layout_get_kind(priv->keyboard->layout) == ARRANGEMENT_KIND_WIDE) {
 | 
			
		||||
        gtk_style_context_add_class(priv->view_context, "wide");
 | 
			
		||||
    }
 | 
			
		||||
    gtk_style_context_add_provider (priv->view_context,
 | 
			
		||||
        GTK_STYLE_PROVIDER(priv->css_provider),
 | 
			
		||||
        GTK_STYLE_PROVIDER_PRIORITY_USER);
 | 
			
		||||
    printf("view: %s\n", gtk_style_context_to_string(priv->view_context, GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE));
 | 
			
		||||
 | 
			
		||||
    /* Create a style context for the buttons */
 | 
			
		||||
    path = gtk_widget_path_new();
 | 
			
		||||
    gtk_widget_path_append_type(path, view_type());
 | 
			
		||||
    if (squeek_layout_get_kind(priv->keyboard->layout) == ARRANGEMENT_KIND_WIDE) {
 | 
			
		||||
        gtk_widget_path_iter_add_class(path, -1, "wide");
 | 
			
		||||
    }
 | 
			
		||||
    gtk_widget_path_append_type(path, button_type());
 | 
			
		||||
    priv->button_context = gtk_style_context_new ();
 | 
			
		||||
    gtk_style_context_set_path(priv->button_context, path);
 | 
			
		||||
    gtk_widget_path_unref(path);
 | 
			
		||||
    gtk_style_context_set_parent(priv->button_context, priv->view_context);
 | 
			
		||||
    gtk_style_context_set_state (priv->button_context, GTK_STATE_FLAG_NORMAL);
 | 
			
		||||
    gtk_style_context_add_provider (priv->button_context,
 | 
			
		||||
        GTK_STYLE_PROVIDER(priv->css_provider),
 | 
			
		||||
        GTK_STYLE_PROVIDER_PRIORITY_USER);
 | 
			
		||||
    return renderer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@
 | 
			
		||||
LevelKeyboard *
 | 
			
		||||
eek_xml_layout_real_create_keyboard (const char *keyboard_type,
 | 
			
		||||
                                     EekboardContextService *manager,
 | 
			
		||||
                                     enum layout_type t)
 | 
			
		||||
                                     enum squeek_arrangement_kind t)
 | 
			
		||||
{
 | 
			
		||||
    struct squeek_layout *layout = squeek_load_layout(keyboard_type, t);
 | 
			
		||||
    squeek_layout_place_contents(layout);
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,6 @@ G_BEGIN_DECLS
 | 
			
		||||
LevelKeyboard *
 | 
			
		||||
eek_xml_layout_real_create_keyboard (const char *keyboard_type,
 | 
			
		||||
                                     EekboardContextService *manager,
 | 
			
		||||
                                     enum layout_type t);
 | 
			
		||||
                                     enum squeek_arrangement_kind t);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_XML_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
@ -81,7 +81,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_
 | 
			
		||||
static LevelKeyboard *
 | 
			
		||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
                                               const gchar            *keyboard_type,
 | 
			
		||||
                                               enum layout_type t)
 | 
			
		||||
                                               enum squeek_arrangement_kind t)
 | 
			
		||||
{
 | 
			
		||||
    LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(keyboard_type, self, t);
 | 
			
		||||
    if (!keyboard) {
 | 
			
		||||
@ -227,7 +227,7 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_service_update_layout(EekboardContextService *context, enum layout_type t)
 | 
			
		||||
eekboard_context_service_update_layout(EekboardContextService *context, enum squeek_arrangement_kind t)
 | 
			
		||||
{
 | 
			
		||||
    g_autofree gchar *keyboard_type = NULL;
 | 
			
		||||
    g_autofree gchar *keyboard_layout = NULL;
 | 
			
		||||
 | 
			
		||||
@ -106,6 +106,6 @@ void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
 | 
			
		||||
                                               uint32_t hint,
 | 
			
		||||
                                               uint32_t purpose);
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_service_update_layout(EekboardContextService *context, enum layout_type t);
 | 
			
		||||
eekboard_context_service_update_layout(EekboardContextService *context, enum squeek_arrangement_kind t);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_CONTEXT_SERVICE_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										105
									
								
								src/data.rs
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								src/data.rs
									
									
									
									
									
								
							@ -17,6 +17,7 @@ use ::keyboard::{
 | 
			
		||||
    KeyState, PressType,
 | 
			
		||||
    generate_keymap, generate_keycodes, FormattingError
 | 
			
		||||
};
 | 
			
		||||
use ::layout::ArrangementKind;
 | 
			
		||||
use ::resources;
 | 
			
		||||
use ::util::c::as_str;
 | 
			
		||||
use ::util::hash_map_map;
 | 
			
		||||
@ -41,15 +42,16 @@ pub mod c {
 | 
			
		||||
        type_: u32,
 | 
			
		||||
    ) -> *mut ::layout::Layout {
 | 
			
		||||
        let type_ = match type_ {
 | 
			
		||||
            0 => LayoutType::Base,
 | 
			
		||||
            1 => LayoutType::Wide,
 | 
			
		||||
            0 => ArrangementKind::Base,
 | 
			
		||||
            1 => ArrangementKind::Wide,
 | 
			
		||||
            _ => panic!("Bad enum value"),
 | 
			
		||||
        };
 | 
			
		||||
        let name = as_str(&name)
 | 
			
		||||
            .expect("Bad layout name")
 | 
			
		||||
            .expect("Empty layout name");
 | 
			
		||||
 | 
			
		||||
        let layout = load_layout_with_fallback(&name, type_);
 | 
			
		||||
        let (kind, layout) = load_layout_data_with_fallback(&name, type_);
 | 
			
		||||
        let layout = ::layout::Layout::new(layout, kind);
 | 
			
		||||
        Box::into_raw(Box::new(layout))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -76,20 +78,6 @@ impl fmt::Display for LoadError {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub enum LayoutType {
 | 
			
		||||
    Base = 0,
 | 
			
		||||
    Wide = 1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl LayoutType {
 | 
			
		||||
    fn apply_to_name(&self, name: String) -> String {
 | 
			
		||||
        match self {
 | 
			
		||||
            LayoutType::Base => name,
 | 
			
		||||
            LayoutType::Wide => name + "_wide",
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, PartialEq)]
 | 
			
		||||
enum DataSource {
 | 
			
		||||
    File(PathBuf),
 | 
			
		||||
@ -106,41 +94,66 @@ impl fmt::Display for DataSource {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Lists possible sources, with 0 as the most preferred one
 | 
			
		||||
/// Trying order: native lang of the right kind, native base,
 | 
			
		||||
/// fallback lang of the right kind, fallback base
 | 
			
		||||
fn list_layout_sources(
 | 
			
		||||
    name: &str,
 | 
			
		||||
    type_: LayoutType,
 | 
			
		||||
    kind: ArrangementKind,
 | 
			
		||||
    keyboards_path: Option<PathBuf>,
 | 
			
		||||
) -> Vec<DataSource> {
 | 
			
		||||
) -> Vec<(ArrangementKind, DataSource)> {
 | 
			
		||||
    let mut ret = Vec::new();
 | 
			
		||||
    {
 | 
			
		||||
        let mut add_by_name = |name: &str| {
 | 
			
		||||
        fn name_with_arrangement(name: String, kind: &ArrangementKind)
 | 
			
		||||
            -> String
 | 
			
		||||
        {
 | 
			
		||||
            match kind {    
 | 
			
		||||
                ArrangementKind::Base => name,
 | 
			
		||||
                ArrangementKind::Wide => name + "_wide",
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut add_by_name = |name: &str, kind: &ArrangementKind| {
 | 
			
		||||
            if let Some(path) = keyboards_path.clone() {
 | 
			
		||||
                ret.push(DataSource::File(
 | 
			
		||||
                ret.push((
 | 
			
		||||
                    kind.clone(),
 | 
			
		||||
                    DataSource::File(
 | 
			
		||||
                        path.join(name.to_owned()).with_extension("yaml")
 | 
			
		||||
                    )
 | 
			
		||||
                ))
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            ret.push(DataSource::Resource(name.into()));
 | 
			
		||||
            ret.push((
 | 
			
		||||
                kind.clone(),
 | 
			
		||||
                DataSource::Resource(name.into())
 | 
			
		||||
            ));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        match &type_ {
 | 
			
		||||
            LayoutType::Base => {},
 | 
			
		||||
            type_ => add_by_name(&type_.apply_to_name(name.into())),
 | 
			
		||||
        match &kind {
 | 
			
		||||
            ArrangementKind::Base => {},
 | 
			
		||||
            kind => add_by_name(
 | 
			
		||||
                &name_with_arrangement(name.into(), &kind),
 | 
			
		||||
                &kind,
 | 
			
		||||
            ),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        add_by_name(name);
 | 
			
		||||
        add_by_name(name, &ArrangementKind::Base);
 | 
			
		||||
 | 
			
		||||
        match &type_ {
 | 
			
		||||
            LayoutType::Base => {},
 | 
			
		||||
            type_ => add_by_name(&type_.apply_to_name(FALLBACK_LAYOUT_NAME.into())),
 | 
			
		||||
        match &kind {
 | 
			
		||||
            ArrangementKind::Base => {},
 | 
			
		||||
            kind => add_by_name(
 | 
			
		||||
                &name_with_arrangement(FALLBACK_LAYOUT_NAME.into(), &kind),
 | 
			
		||||
                &kind,
 | 
			
		||||
            ),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        add_by_name(FALLBACK_LAYOUT_NAME);
 | 
			
		||||
        add_by_name(FALLBACK_LAYOUT_NAME, &ArrangementKind::Base);
 | 
			
		||||
    }
 | 
			
		||||
    ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn load_layout(source: DataSource) -> Result<::layout::Layout, LoadError> {
 | 
			
		||||
fn load_layout_data(source: DataSource)
 | 
			
		||||
    -> Result<::layout::LayoutData, LoadError>
 | 
			
		||||
{
 | 
			
		||||
    match source {
 | 
			
		||||
        DataSource::File(path) => {
 | 
			
		||||
            Layout::from_file(path.clone())
 | 
			
		||||
@ -158,16 +171,16 @@ fn load_layout(source: DataSource) -> Result<::layout::Layout, LoadError> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn load_layout_with_fallback(
 | 
			
		||||
fn load_layout_data_with_fallback(
 | 
			
		||||
    name: &str,
 | 
			
		||||
    type_: LayoutType,
 | 
			
		||||
) -> ::layout::Layout {
 | 
			
		||||
    kind: ArrangementKind,
 | 
			
		||||
) -> (ArrangementKind, ::layout::LayoutData) {
 | 
			
		||||
    let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
 | 
			
		||||
        .map(PathBuf::from)
 | 
			
		||||
        .or_else(|| xdg::data_path("squeekboard/keyboards"));
 | 
			
		||||
    
 | 
			
		||||
    for source in list_layout_sources(name, type_, path) {
 | 
			
		||||
        let layout = load_layout(source.clone());
 | 
			
		||||
    for (kind, source) in list_layout_sources(name, kind, path) {
 | 
			
		||||
        let layout = load_layout_data(source.clone());
 | 
			
		||||
        match layout {
 | 
			
		||||
            Err(e) => match (e, source) {
 | 
			
		||||
                (
 | 
			
		||||
@ -182,7 +195,7 @@ fn load_layout_with_fallback(
 | 
			
		||||
                    source, e
 | 
			
		||||
                ),
 | 
			
		||||
            },
 | 
			
		||||
            Ok(layout) => return layout,
 | 
			
		||||
            Ok(layout) => return (kind, layout),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -292,7 +305,9 @@ impl Layout {
 | 
			
		||||
        serde_yaml::from_reader(infile).map_err(Error::Yaml)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn build(self) -> Result<::layout::Layout, FormattingError> {
 | 
			
		||||
    pub fn build(self)
 | 
			
		||||
        -> Result<::layout::LayoutData, FormattingError>
 | 
			
		||||
    {
 | 
			
		||||
        let button_names = self.views.values()
 | 
			
		||||
            .flat_map(|rows| {
 | 
			
		||||
                rows.iter()
 | 
			
		||||
@ -399,15 +414,12 @@ impl Layout {
 | 
			
		||||
            )})
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        Ok(::layout::Layout {
 | 
			
		||||
            current_view: "base".into(),
 | 
			
		||||
        Ok(::layout::LayoutData {
 | 
			
		||||
            views: views,
 | 
			
		||||
            keymap_str: {
 | 
			
		||||
                CString::new(keymap_str)
 | 
			
		||||
                    .expect("Invalid keymap string generated")
 | 
			
		||||
            },
 | 
			
		||||
            locked_keys: HashSet::new(),
 | 
			
		||||
            pressed_keys: HashSet::new(),
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -701,13 +713,16 @@ mod tests {
 | 
			
		||||
    /// First fallback should be to builtin, not to FALLBACK_LAYOUT_NAME
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn fallbacks_order() {
 | 
			
		||||
        let sources = list_layout_sources("nb", LayoutType::Base, None);
 | 
			
		||||
        let sources = list_layout_sources("nb", ArrangementKind::Base, None);
 | 
			
		||||
        
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            sources,
 | 
			
		||||
            vec!(
 | 
			
		||||
                DataSource::Resource("nb".into()),
 | 
			
		||||
                DataSource::Resource(FALLBACK_LAYOUT_NAME.into()),
 | 
			
		||||
                (ArrangementKind::Base, DataSource::Resource("nb".into())),
 | 
			
		||||
                (
 | 
			
		||||
                    ArrangementKind::Base,
 | 
			
		||||
                    DataSource::Resource(FALLBACK_LAYOUT_NAME.into())
 | 
			
		||||
                ),
 | 
			
		||||
            )
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -9,9 +9,9 @@
 | 
			
		||||
#include "src/keyboard.h"
 | 
			
		||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
 | 
			
		||||
 | 
			
		||||
enum layout_type {
 | 
			
		||||
    LAYOUT_TYPE_BASE = 0,
 | 
			
		||||
    LAYOUT_TYPE_WIDE = 1,
 | 
			
		||||
enum squeek_arrangement_kind {
 | 
			
		||||
    ARRANGEMENT_KIND_BASE = 0,
 | 
			
		||||
    ARRANGEMENT_KIND_WIDE = 1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct squeek_button;
 | 
			
		||||
@ -59,6 +59,7 @@ struct squeek_view *squeek_layout_get_current_view(struct squeek_layout*);
 | 
			
		||||
 | 
			
		||||
struct squeek_layout *squeek_load_layout(const char *name, uint32_t type);
 | 
			
		||||
const char *squeek_layout_get_keymap(const struct squeek_layout*);
 | 
			
		||||
enum squeek_arrangement_kind squeek_layout_get_kind(const struct squeek_layout *);
 | 
			
		||||
void squeek_layout_free(struct squeek_layout*);
 | 
			
		||||
 | 
			
		||||
void squeek_layout_release(struct squeek_layout *layout, struct zwp_virtual_keyboard_v1 *virtual_keyboard, uint32_t timestamp, EekGtkKeyboard *ui_keyboard);
 | 
			
		||||
 | 
			
		||||
@ -203,6 +203,13 @@ pub mod c {
 | 
			
		||||
        layout.keymap_str.as_ptr()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_layout_get_kind(layout: *const Layout) -> u32 {
 | 
			
		||||
        let layout = unsafe { &*layout };
 | 
			
		||||
        layout.kind.clone() as u32
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_layout_free(layout: *mut Layout) {
 | 
			
		||||
@ -687,10 +694,18 @@ impl View {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The physical characteristic of layout for the purpose of styling
 | 
			
		||||
#[derive(Clone, PartialEq, Debug)]
 | 
			
		||||
pub enum ArrangementKind {
 | 
			
		||||
    Base = 0,
 | 
			
		||||
    Wide = 1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: split into sth like
 | 
			
		||||
// Arrangement (views) + details (keymap) + State (keys)
 | 
			
		||||
/// State of the UI, contains the backend as well
 | 
			
		||||
pub struct Layout {
 | 
			
		||||
    pub kind: ArrangementKind,
 | 
			
		||||
    pub current_view: String,
 | 
			
		||||
    // Views own the actual buttons which have state
 | 
			
		||||
    // Maybe they should own UI only,
 | 
			
		||||
@ -706,6 +721,12 @@ pub struct Layout {
 | 
			
		||||
    pub locked_keys: HashSet<::util::Pointer<RefCell<KeyState>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// A builder structure for picking up layout data from storage
 | 
			
		||||
pub struct LayoutData {
 | 
			
		||||
    pub views: HashMap<String, Box<View>>,
 | 
			
		||||
    pub keymap_str: CString,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct NoSuchView;
 | 
			
		||||
 | 
			
		||||
// Unfortunately, changes are not atomic due to mutability :(
 | 
			
		||||
@ -713,6 +734,16 @@ struct NoSuchView;
 | 
			
		||||
// The usage of &mut on Rc<RefCell<KeyState>> doesn't mean anything special.
 | 
			
		||||
// Cloning could also be used.
 | 
			
		||||
impl Layout {
 | 
			
		||||
    pub fn new(data: LayoutData, kind: ArrangementKind) -> Layout {
 | 
			
		||||
        Layout {
 | 
			
		||||
            kind,
 | 
			
		||||
            current_view: "base".to_owned(),
 | 
			
		||||
            views: data.views,
 | 
			
		||||
            keymap_str: data.keymap_str,
 | 
			
		||||
            pressed_keys: HashSet::new(),
 | 
			
		||||
            locked_keys: HashSet::new(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fn get_current_view(&self) -> &Box<View> {
 | 
			
		||||
        self.views.get(&self.current_view).expect("Selected nonexistent view")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,6 @@
 | 
			
		||||
 * This could be done using GResource, but that would need additional work.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const KEYBOARDS: &[(*const str, *const str)] = &[
 | 
			
		||||
    ("us", include_str!("../data/keyboards/us.yaml")),
 | 
			
		||||
    ("us_wide", include_str!("../data/keyboards/us_wide.yaml")),
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ struct _ServerContextService {
 | 
			
		||||
    GtkWidget *widget;
 | 
			
		||||
    guint hiding;
 | 
			
		||||
    guint last_requested_height;
 | 
			
		||||
    enum layout_type last_type;
 | 
			
		||||
    enum squeek_arrangement_kind last_type;
 | 
			
		||||
 | 
			
		||||
    gdouble size_constraint_landscape[2];
 | 
			
		||||
    gdouble size_constraint_portrait[2];
 | 
			
		||||
@ -128,12 +128,12 @@ calculate_height(int32_t width)
 | 
			
		||||
    return height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum layout_type get_type(uint32_t width, uint32_t height) {
 | 
			
		||||
enum squeek_arrangement_kind get_type(uint32_t width, uint32_t height) {
 | 
			
		||||
    (void)height;
 | 
			
		||||
    if (width < 540) {
 | 
			
		||||
        return LAYOUT_TYPE_BASE;
 | 
			
		||||
        return ARRANGEMENT_KIND_BASE;
 | 
			
		||||
    }
 | 
			
		||||
    return LAYOUT_TYPE_WIDE;
 | 
			
		||||
    return ARRANGEMENT_KIND_WIDE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -146,7 +146,7 @@ on_surface_configure(PhoshLayerSurface *surface, ServerContextService *context)
 | 
			
		||||
                 "configured-height", &height,
 | 
			
		||||
                 NULL);
 | 
			
		||||
    // check if the change would switch types
 | 
			
		||||
    enum layout_type new_type = get_type((uint32_t)width, (uint32_t)height);
 | 
			
		||||
    enum squeek_arrangement_kind new_type = get_type((uint32_t)width, (uint32_t)height);
 | 
			
		||||
    if (context->last_type != new_type) {
 | 
			
		||||
        context->last_type = new_type;
 | 
			
		||||
        eekboard_context_service_update_layout(EEKBOARD_CONTEXT_SERVICE(context), context->last_type);
 | 
			
		||||
@ -374,7 +374,7 @@ server_context_service_new ()
 | 
			
		||||
    return EEKBOARD_CONTEXT_SERVICE(g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum layout_type server_context_service_get_layout_type(EekboardContextService *service)
 | 
			
		||||
enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService *service)
 | 
			
		||||
{
 | 
			
		||||
    return SERVER_CONTEXT_SERVICE(service)->last_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@ G_BEGIN_DECLS
 | 
			
		||||
typedef struct _ServerContextService ServerContextService;
 | 
			
		||||
 | 
			
		||||
EekboardContextService *server_context_service_new ();
 | 
			
		||||
enum layout_type server_context_service_get_layout_type(EekboardContextService*);
 | 
			
		||||
enum squeek_arrangement_kind server_context_service_get_layout_type(EekboardContextService*);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* SERVER_CONTEXT_SERVICE_H */
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user