diff --git a/data/style.css b/data/style.css index ab90eaf1..f4b45dcb 100644 --- a/data/style.css +++ b/data/style.css @@ -18,6 +18,13 @@ button:active { border-color: #716e78; } +button.altline, +button.special, +button.wide { + background: #2b292f; + border-color: #3e3a44 +} + #Return { background: #1c71d8; border-color: #1a5fb4 @@ -27,48 +34,3 @@ button:active { background: #1c71d8; border-color: #3584e4; } - -#Shift_L { - background: #2b292f; - border-color: #3e3a44 -} - -#Shift_L:active { - background: #1c71d8; - border-color: #3584e4; -} - -#show_numbers { - background: #2b292f; - border-color: #3e3a44 -} - -#show_letters { - background: #2b292f; - border-color: #3e3a44 -} - -#show_symbols { - background: #2b292f; - border-color: #3e3a44 -} - -#show_numbers_from_symbols { - background: #2b292f; - border-color: #3e3a44 -} - -#preferences { - background: #2b292f; - border-color: #3e3a44 -} - -#period { - background: #2b292f; - border-color: #3e3a44 -} - -#BackSpace { - background: #2b292f; - border-color: #3e3a44 -} diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index d4c6c4bd..391e335c 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -38,7 +38,7 @@ typedef struct _EekRendererPrivate PangoContext *pcontext; GtkCssProvider *css_provider; GtkStyleContext *layout_context; - GtkStyleContext *button_context; + GtkStyleContext *button_context; // TODO: maybe move a copy to each button gdouble border_width; @@ -170,49 +170,25 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view) } static void -render_button_outline (EekRenderer *renderer, - cairo_t *cr, - const struct squeek_button *button, - gboolean active) +render_outline (cairo_t *cr, + GtkStyleContext *ctx, + EekBounds bounds) { - EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer); - EekBounds bounds = squeek_button_get_bounds(button); - - /* Set the name of the button on the widget path, using the name obtained - from the button's symbol. */ - g_autoptr (GtkWidgetPath) path = NULL; - path = gtk_widget_path_copy (gtk_style_context_get_path (priv->button_context)); - const char *name = squeek_button_get_name(button); - gtk_widget_path_iter_set_name (path, -1, name); - - /* Update the style context with the updated widget path. */ - gtk_style_context_set_path (priv->button_context, path); - - /* Set the state to take into account whether the button is active - (pressed) or normal. */ - gtk_style_context_set_state(priv->button_context, - active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL); - - gtk_render_background (priv->button_context, - cr, 0, 0, bounds.width, bounds.height); - gtk_render_frame (priv->button_context, - cr, 0, 0, bounds.width, bounds.height); - - gtk_style_context_set_state(priv->button_context, GTK_STATE_FLAG_NORMAL); + gtk_render_background (ctx, cr, 0, 0, bounds.width, bounds.height); + gtk_render_frame (ctx, cr, 0, 0, bounds.width, bounds.height); } -static void -render_button (EekRenderer *self, - cairo_t *cr, - struct button_place *place, - gboolean active) -{ - EekRendererPrivate *priv = eek_renderer_get_instance_private (self); +static void render_button_in_context(EekRenderer *self, + cairo_t *cr, + GtkStyleContext *ctx, + struct button_place *place, + gboolean active) { cairo_surface_t *outline_surface; GHashTable *outline_surface_cache; PangoLayout *layout; PangoRectangle extents = { 0, }; EekColor foreground; + EekRendererPrivate *priv = eek_renderer_get_instance_private (self); /* render outline */ EekBounds bounds = squeek_button_get_bounds(place->button); @@ -223,6 +199,7 @@ render_button (EekRenderer *self, outline_surface_cache = priv->outline_surface_cache; outline_surface = g_hash_table_lookup (outline_surface_cache, place->button); + if (!outline_surface) { cairo_t *cr; @@ -240,7 +217,7 @@ render_button (EekRenderer *self, cairo_save (cr); eek_renderer_apply_transformation_for_button (self, cr, place, 1.0, FALSE); - render_button_outline (self, cr, place->button, active); + render_outline (cr, ctx, bounds); cairo_restore (cr); cairo_destroy (cr); @@ -249,11 +226,10 @@ render_button (EekRenderer *self, (gpointer)place->button, outline_surface); } - cairo_set_source_surface (cr, outline_surface, 0.0, 0.0); cairo_paint (cr); - eek_renderer_get_foreground_color (self, priv->button_context, &foreground); + eek_renderer_get_foreground_color (self, ctx, &foreground); /* render icon (if any) */ const char *icon_name = squeek_button_get_icon_name(place->button); @@ -284,7 +260,6 @@ render_button (EekRenderer *self, return; } } - /* render label */ layout = pango_cairo_create_layout (cr); eek_renderer_real_render_button_label (self, layout, place->button); @@ -301,10 +276,42 @@ render_button (EekRenderer *self, foreground.green, foreground.blue, foreground.alpha); - pango_cairo_show_layout (cr, layout); cairo_restore (cr); g_object_unref (layout); + +} + +static void +render_button (EekRenderer *self, + cairo_t *cr, + struct button_place *place, + gboolean active) +{ + EekRendererPrivate *priv = eek_renderer_get_instance_private (self); + + GtkStyleContext *ctx = priv->button_context; + /* Set the name of the button on the widget path, using the name obtained + from the button's symbol. */ + g_autoptr (GtkWidgetPath) path = NULL; + path = gtk_widget_path_copy (gtk_style_context_get_path (ctx)); + const char *name = squeek_button_get_name(place->button); + gtk_widget_path_iter_set_name (path, -1, name); + + /* Update the style context with the updated widget path. */ + gtk_style_context_set_path (ctx, path); + /* Set the state to take into account whether the button is active + (pressed) or normal. */ + gtk_style_context_set_state(ctx, + active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL); + const char *outline_name = squeek_button_get_outline_name(place->button); + gtk_style_context_add_class(ctx, outline_name); + + render_button_in_context(self, cr, ctx, place, active); + + // Save and restore functions don't work if gtk_render_* was used in between + gtk_style_context_set_state(ctx, GTK_STATE_FLAG_NORMAL); + gtk_style_context_remove_class(ctx, outline_name); } /** @@ -629,24 +636,30 @@ eek_renderer_init (EekRenderer *self) gtk_css_provider_load_from_resource (priv->css_provider, "/sm/puri/squeekboard/style.css"); - /* Create a style context for keys */ + /* 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); - gtk_widget_path_unref(path); } static void diff --git a/src/data.rs b/src/data.rs index 0fb1f280..0e4c428c 100644 --- a/src/data.rs +++ b/src/data.rs @@ -480,6 +480,7 @@ fn create_button( ::layout::Button { name: cname, + outline_name: CString::new(outline_name).expect("Bad outline"), // TODO: do layout before creating buttons bounds: ::layout::c::Bounds { x: outline.bounds.x, diff --git a/src/layout.h b/src/layout.h index ca1ea8f7..70c87665 100644 --- a/src/layout.h +++ b/src/layout.h @@ -32,6 +32,7 @@ EekBounds squeek_button_get_bounds(const struct squeek_button*); const char *squeek_button_get_label(const struct squeek_button*); const char *squeek_button_get_icon_name(const struct squeek_button*); const char *squeek_button_get_name(const struct squeek_button*); +const char *squeek_button_get_outline_name(const struct squeek_button*); struct squeek_key *squeek_button_get_key(const struct squeek_button*); uint32_t *squeek_button_has_key(const struct squeek_button* button, diff --git a/src/layout.rs b/src/layout.rs index f47dee3f..14abb511 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -40,11 +40,6 @@ pub mod c { #[repr(transparent)] pub struct UserData(*const c_void); - /// The index in the relevant outline table - #[repr(C)] - #[derive(Clone, Debug)] - pub struct OutlineRef(u32); - /// Defined in eek-types.h #[repr(C)] #[derive(Clone, Debug)] @@ -194,6 +189,13 @@ pub mod c { let button = unsafe { &*button }; button.name.as_ptr() } + + #[no_mangle] + pub extern "C" + fn squeek_button_get_outline_name(button: *const Button) -> *const c_char { + let button = unsafe { &*button }; + button.outline_name.as_ptr() + } #[no_mangle] pub extern "C" @@ -509,6 +511,7 @@ pub mod c { bounds: c::Bounds { x: 0f64, y: 0f64, width: 0f64, height: 0f64 }, + outline_name: CString::new("test").unwrap(), label: Label::Text(CString::new(name).unwrap()), state: state, }) @@ -571,6 +574,8 @@ pub struct Button { /// TODO: position the buttons before they get initial bounds /// Position relative to some origin (i.e. parent/row) pub bounds: c::Bounds, + /// The name of the visual class applied + pub outline_name: CString, /// current state, shared with other buttons pub state: Rc>, }