From 15833323aef12508c0f1242661cde5919cf89da0 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 26 Sep 2019 12:30:21 +0000 Subject: [PATCH 1/3] styling: Use same context for the entire rendering of a button --- eek/eek-renderer.c | 64 ++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index 70ca8e31..3236efb8 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 EekColor default_foreground_color; EekColor default_background_color; @@ -179,35 +179,14 @@ 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_button_outline (cairo_t *cr, + GtkStyleContext *ctx, + const struct squeek_button *button) { - 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 @@ -223,6 +202,22 @@ render_button (EekRenderer *self, PangoRectangle extents = { 0, }; EekColor foreground; + 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); + + /* render outline */ EekBounds bounds = squeek_button_get_bounds(place->button); @@ -249,7 +244,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_button_outline (cr, ctx, place->button); cairo_restore (cr); cairo_destroy (cr); @@ -262,7 +257,7 @@ render_button (EekRenderer *self, 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); @@ -311,6 +306,7 @@ render_button (EekRenderer *self, foreground.blue, foreground.alpha); + gtk_style_context_set_state(ctx, GTK_STATE_FLAG_NORMAL); pango_cairo_show_layout (cr, layout); cairo_restore (cr); g_object_unref (layout); @@ -640,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 From 6fd7ab7405af5d33f4aba76ce04aa4697b3680db Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 26 Sep 2019 12:43:50 +0000 Subject: [PATCH 2/3] rendering: Generalize outline rendering --- eek/eek-renderer.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index 3236efb8..db23a94c 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -179,12 +179,10 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view) } static void -render_button_outline (cairo_t *cr, - GtkStyleContext *ctx, - const struct squeek_button *button) +render_outline (cairo_t *cr, + GtkStyleContext *ctx, + EekBounds bounds) { - EekBounds bounds = squeek_button_get_bounds(button); - gtk_render_background (ctx, cr, 0, 0, bounds.width, bounds.height); gtk_render_frame (ctx, cr, 0, 0, bounds.width, bounds.height); } @@ -244,7 +242,7 @@ render_button (EekRenderer *self, cairo_save (cr); eek_renderer_apply_transformation_for_button (self, cr, place, 1.0, FALSE); - render_button_outline (cr, ctx, place->button); + render_outline (cr, ctx, bounds); cairo_restore (cr); cairo_destroy (cr); From e513cb9b547e8f0394ef0ebf1e04d92b588b73a8 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 26 Sep 2019 13:28:31 +0000 Subject: [PATCH 3/3] style: Use outline name as CSS class --- data/style.css | 52 +++++------------------------------ eek/eek-renderer.c | 67 +++++++++++++++++++++++++++------------------- src/data.rs | 1 + src/layout.h | 1 + src/layout.rs | 15 +++++++---- 5 files changed, 59 insertions(+), 77 deletions(-) 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 db23a94c..b6b34b9f 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -187,34 +187,17 @@ render_outline (cairo_t *cr, 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; - - 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); - + EekRendererPrivate *priv = eek_renderer_get_instance_private (self); /* render outline */ EekBounds bounds = squeek_button_get_bounds(place->button); @@ -225,6 +208,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; @@ -251,7 +235,6 @@ render_button (EekRenderer *self, (gpointer)place->button, outline_surface); } - cairo_set_source_surface (cr, outline_surface, 0.0, 0.0); cairo_paint (cr); @@ -286,7 +269,6 @@ render_button (EekRenderer *self, return; } } - /* render label */ layout = pango_cairo_create_layout (cr); eek_renderer_real_render_button_label (self, layout, place->button); @@ -303,11 +285,42 @@ render_button (EekRenderer *self, foreground.green, foreground.blue, foreground.alpha); - - gtk_style_context_set_state(ctx, GTK_STATE_FLAG_NORMAL); 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); } /** diff --git a/src/data.rs b/src/data.rs index 595b20df..c23bb1a0 100644 --- a/src/data.rs +++ b/src/data.rs @@ -476,6 +476,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 a0009b47..7f3fd2fd 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" @@ -502,6 +504,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, }) @@ -565,6 +568,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>, }