Replace the Eek theme support with GTK classes
This brings the appearance of the keyboard basically in line with what was there before. The background and key borders still need to be fixed and the text and icons should probably be drawn using the style context.
This commit is contained in:
@ -33,6 +33,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_KEYBOARD,
|
||||
PROP_PCONTEXT,
|
||||
PROP_STYLE_CONTEXT,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@ -40,6 +41,9 @@ typedef struct _EekRendererPrivate
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
PangoContext *pcontext;
|
||||
GtkCssProvider *css_provider;
|
||||
GtkStyleContext *scontext;
|
||||
GtkStyleContext *key_context;
|
||||
|
||||
EekColor default_foreground_color;
|
||||
EekColor default_background_color;
|
||||
@ -60,7 +64,6 @@ typedef struct _EekRendererPrivate
|
||||
cairo_surface_t *keyboard_surface;
|
||||
gulong symbol_index_changed_handler;
|
||||
|
||||
EekTheme *theme;
|
||||
} EekRendererPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
|
||||
@ -145,14 +148,9 @@ render_keyboard_surface (EekRenderer *renderer)
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
EekBounds bounds;
|
||||
CreateKeyboardSurfaceCallbackData data;
|
||||
EekColor foreground, background;
|
||||
EekColor foreground;
|
||||
|
||||
eek_renderer_get_foreground_color (renderer,
|
||||
EEK_ELEMENT(priv->keyboard),
|
||||
&foreground);
|
||||
eek_renderer_get_background_color (renderer,
|
||||
EEK_ELEMENT(priv->keyboard),
|
||||
&background);
|
||||
eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground);
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
|
||||
@ -164,12 +162,14 @@ render_keyboard_surface (EekRenderer *renderer)
|
||||
cairo_translate (data.cr, bounds.x, bounds.y);
|
||||
|
||||
/* blank background */
|
||||
cairo_set_source_rgba (data.cr,
|
||||
background.red,
|
||||
background.green,
|
||||
background.blue,
|
||||
background.alpha);
|
||||
cairo_paint (data.cr);
|
||||
cairo_save (data.cr);
|
||||
cairo_scale (data.cr, priv->scale, priv->scale);
|
||||
gtk_render_background (priv->scontext,
|
||||
data.cr,
|
||||
-bounds.x, -bounds.y,
|
||||
(bounds.x * 2) + bounds.width,
|
||||
(bounds.y * 2) + bounds.height);
|
||||
cairo_restore (data.cr);
|
||||
|
||||
cairo_set_source_rgba (data.cr,
|
||||
foreground.red,
|
||||
@ -196,7 +196,6 @@ render_key_outline (EekRenderer *renderer,
|
||||
EekOutline *outline;
|
||||
EekBounds bounds;
|
||||
guint oref;
|
||||
EekThemeNode *theme_node;
|
||||
EekColor foreground, background, gradient_start, gradient_end, border_color;
|
||||
EekGradientType gradient_type;
|
||||
gint border_width;
|
||||
@ -207,119 +206,17 @@ render_key_outline (EekRenderer *renderer,
|
||||
if (outline == NULL)
|
||||
return;
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(key),
|
||||
active ?
|
||||
"theme-node-pressed" :
|
||||
"theme-node");
|
||||
if (theme_node) {
|
||||
eek_theme_node_get_foreground_color (theme_node, &foreground);
|
||||
eek_theme_node_get_background_color (theme_node, &background);
|
||||
eek_theme_node_get_background_gradient (theme_node,
|
||||
&gradient_type,
|
||||
&gradient_start,
|
||||
&gradient_end);
|
||||
border_width = eek_theme_node_get_border_width (theme_node,
|
||||
EEK_SIDE_TOP);
|
||||
border_radius = eek_theme_node_get_border_radius (theme_node,
|
||||
EEK_CORNER_TOPLEFT);
|
||||
eek_theme_node_get_border_color (theme_node, EEK_SIDE_TOP,
|
||||
&border_color);
|
||||
} else {
|
||||
foreground = priv->default_foreground_color;
|
||||
background = priv->default_background_color;
|
||||
gradient_type = EEK_GRADIENT_NONE;
|
||||
border_width = (gint)round(priv->border_width);
|
||||
border_radius = -1;
|
||||
border_color.red = ABS(background.red - foreground.red) * 0.7;
|
||||
border_color.green = ABS(background.green - foreground.green) * 0.7;
|
||||
border_color.blue = ABS(background.blue - foreground.blue) * 0.7;
|
||||
border_color.alpha = foreground.alpha;
|
||||
}
|
||||
|
||||
eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
|
||||
outline = eek_outline_copy (outline);
|
||||
gtk_style_context_set_state(priv->key_context,
|
||||
active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
|
||||
|
||||
cairo_translate (cr, border_width, border_width);
|
||||
gtk_render_background (priv->key_context,
|
||||
cr,
|
||||
0, 0,
|
||||
bounds.width * priv->scale,
|
||||
bounds.height * priv->scale);
|
||||
|
||||
if (gradient_type != EEK_GRADIENT_NONE) {
|
||||
cairo_pattern_t *pat;
|
||||
gdouble cx, cy;
|
||||
|
||||
switch (gradient_type) {
|
||||
case EEK_GRADIENT_VERTICAL:
|
||||
pat = cairo_pattern_create_linear (0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
bounds.height);
|
||||
break;
|
||||
case EEK_GRADIENT_HORIZONTAL:
|
||||
pat = cairo_pattern_create_linear (0.0,
|
||||
0.0,
|
||||
bounds.width,
|
||||
0.0);
|
||||
break;
|
||||
case EEK_GRADIENT_RADIAL:
|
||||
cx = bounds.width / 2;
|
||||
cy = bounds.height / 2;
|
||||
pat = cairo_pattern_create_radial (cx,
|
||||
cy,
|
||||
0,
|
||||
cx,
|
||||
cy,
|
||||
MIN(cx, cy));
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pat,
|
||||
1,
|
||||
gradient_start.red * 0.5,
|
||||
gradient_start.green * 0.5,
|
||||
gradient_start.blue * 0.5,
|
||||
gradient_start.alpha);
|
||||
cairo_pattern_add_color_stop_rgba (pat,
|
||||
0,
|
||||
gradient_end.red,
|
||||
gradient_end.green,
|
||||
gradient_end.blue,
|
||||
gradient_end.alpha);
|
||||
cairo_set_source (cr, pat);
|
||||
cairo_pattern_destroy (pat);
|
||||
} else {
|
||||
cairo_set_source_rgba (cr,
|
||||
background.red,
|
||||
background.green,
|
||||
background.blue,
|
||||
background.alpha);
|
||||
}
|
||||
|
||||
_eek_rounded_polygon (cr,
|
||||
border_radius >= 0 ? border_radius : outline->corner_radius,
|
||||
outline->points,
|
||||
outline->num_points);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* paint the border */
|
||||
cairo_set_line_width (cr, border_width);
|
||||
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
|
||||
|
||||
cairo_set_source_rgba (cr,
|
||||
border_color.red,
|
||||
border_color.green,
|
||||
border_color.blue,
|
||||
border_color.alpha);
|
||||
|
||||
_eek_rounded_polygon (cr,
|
||||
border_radius >= 0 ? border_radius : outline->corner_radius,
|
||||
outline->points,
|
||||
outline->num_points);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_translate (cr, -border_width, -border_width);
|
||||
|
||||
eek_outline_free (outline);
|
||||
gtk_style_context_set_state(priv->key_context, GTK_STATE_FLAG_NORMAL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -386,7 +283,7 @@ render_key (EekRenderer *self,
|
||||
cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
|
||||
cairo_paint (cr);
|
||||
|
||||
eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
|
||||
eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
|
||||
/* render icon (if any) */
|
||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (!symbol)
|
||||
@ -512,12 +409,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
if (!priv->font) {
|
||||
const PangoFontDescription *base_font;
|
||||
gdouble ascii_size, size;
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(key), "theme-node");
|
||||
if (theme_node)
|
||||
base_font = eek_theme_node_get_font (theme_node);
|
||||
else
|
||||
base_font = pango_context_get_font_description (priv->pcontext);
|
||||
// FIXME: Base font size on the same size unit used for button sizing,
|
||||
// and make the default about 1/3 of the current row height
|
||||
@ -652,6 +544,10 @@ eek_renderer_set_property (GObject *object,
|
||||
priv->pcontext = g_value_get_object (value);
|
||||
g_object_ref (priv->pcontext);
|
||||
break;
|
||||
case PROP_STYLE_CONTEXT:
|
||||
priv->scontext = g_value_get_object (value);
|
||||
g_object_ref (priv->scontext);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -749,6 +645,15 @@ eek_renderer_class_init (EekRendererClass *klass)
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PCONTEXT,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_object ("style-context",
|
||||
"GTK Style Context",
|
||||
"GTK Style Context",
|
||||
GTK_TYPE_STYLE_CONTEXT,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_STYLE_CONTEXT,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -786,6 +691,24 @@ eek_renderer_init (EekRenderer *self)
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify)cairo_surface_destroy);
|
||||
|
||||
/* Create a default CSS provider and load a style sheet */
|
||||
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 keys */
|
||||
priv->key_context = gtk_style_context_new ();
|
||||
gtk_style_context_add_class (priv->key_context, "key");
|
||||
gtk_style_context_add_provider (priv->key_context,
|
||||
GTK_STYLE_PROVIDER(priv->css_provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
g_autoptr (GtkWidgetPath) path = NULL;
|
||||
path = gtk_widget_path_new ();
|
||||
gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
|
||||
gtk_style_context_set_path (priv->key_context, path);
|
||||
gtk_style_context_set_state (priv->key_context, GTK_STATE_FLAG_NORMAL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -817,11 +740,13 @@ on_symbol_index_changed (EekKeyboard *keyboard,
|
||||
|
||||
EekRenderer *
|
||||
eek_renderer_new (EekKeyboard *keyboard,
|
||||
PangoContext *pcontext)
|
||||
PangoContext *pcontext,
|
||||
GtkStyleContext *scontext)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_RENDERER,
|
||||
"keyboard", keyboard,
|
||||
"pango-context", pcontext,
|
||||
"style-context", scontext,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@ -1065,64 +990,21 @@ eek_renderer_set_default_background_color (EekRenderer *renderer,
|
||||
|
||||
void
|
||||
eek_renderer_get_foreground_color (EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
GtkStyleContext *context,
|
||||
EekColor *color)
|
||||
{
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (color);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
GtkStateFlags flags = GTK_STATE_FLAG_NORMAL;
|
||||
GdkRGBA gcolor;
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
|
||||
if (theme_node)
|
||||
eek_theme_node_get_foreground_color (theme_node, color);
|
||||
else
|
||||
memcpy (color, &priv->default_foreground_color,
|
||||
sizeof(EekColor));
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_get_background_color (EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekColor *color)
|
||||
{
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (color);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
|
||||
if (theme_node)
|
||||
eek_theme_node_get_background_color (theme_node, color);
|
||||
else
|
||||
memcpy (color, &priv->default_background_color,
|
||||
sizeof(EekColor));
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_get_background_gradient (EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekGradientType *type,
|
||||
EekColor *start,
|
||||
EekColor *end)
|
||||
{
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
g_return_if_fail (type);
|
||||
g_return_if_fail (start);
|
||||
g_return_if_fail (end);
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
|
||||
if (theme_node)
|
||||
eek_theme_node_get_background_gradient (theme_node, type, start, end);
|
||||
else
|
||||
*type = EEK_GRADIENT_NONE;
|
||||
gtk_style_context_get_color (context, flags, &gcolor);
|
||||
color->red = gcolor.red;
|
||||
color->green = gcolor.green;
|
||||
color->blue = gcolor.blue;
|
||||
color->alpha = gcolor.alpha;
|
||||
}
|
||||
|
||||
struct _FindKeyByPositionCallbackData {
|
||||
@ -1253,117 +1135,3 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
||||
&data);
|
||||
return data.key;
|
||||
}
|
||||
|
||||
struct _CreateThemeNodeData {
|
||||
EekThemeContext *context;
|
||||
EekThemeNode *parent;
|
||||
EekRenderer *renderer;
|
||||
};
|
||||
typedef struct _CreateThemeNodeData CreateThemeNodeData;
|
||||
|
||||
void
|
||||
create_theme_node_key_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateThemeNodeData *data = user_data;
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
EEK_TYPE_KEY,
|
||||
eek_element_get_name (element),
|
||||
"key",
|
||||
NULL,
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(element),
|
||||
"theme-node",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
EEK_TYPE_KEY,
|
||||
eek_element_get_name (element),
|
||||
"key",
|
||||
"active",
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(element),
|
||||
"theme-node-pressed",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
}
|
||||
|
||||
void
|
||||
create_theme_node_section_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateThemeNodeData *data = user_data;
|
||||
EekThemeNode *theme_node, *parent;
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
EEK_TYPE_SECTION,
|
||||
eek_element_get_name (element),
|
||||
"section",
|
||||
NULL,
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(element),
|
||||
"theme-node",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
parent = data->parent;
|
||||
data->parent = theme_node;
|
||||
eek_container_foreach_child (EEK_CONTAINER(element),
|
||||
create_theme_node_key_callback,
|
||||
data);
|
||||
data->parent = parent;
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_set_theme (EekRenderer *renderer,
|
||||
EekTheme *theme)
|
||||
{
|
||||
EekThemeContext *theme_context;
|
||||
EekThemeNode *theme_node;
|
||||
CreateThemeNodeData data;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_THEME(theme));
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
g_return_if_fail (priv->keyboard);
|
||||
|
||||
if (priv->theme)
|
||||
g_object_unref (priv->theme);
|
||||
priv->theme = g_object_ref (theme);
|
||||
|
||||
theme_context = eek_theme_context_new ();
|
||||
theme_node = eek_theme_node_new (theme_context,
|
||||
NULL,
|
||||
priv->theme,
|
||||
EEK_TYPE_KEYBOARD,
|
||||
"keyboard",
|
||||
"keyboard",
|
||||
NULL,
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(priv->keyboard),
|
||||
"theme-node",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
data.context = theme_context;
|
||||
data.parent = theme_node;
|
||||
data.renderer = renderer;
|
||||
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
|
||||
create_theme_node_section_callback,
|
||||
&data);
|
||||
}
|
||||
|
||||
@ -25,8 +25,6 @@
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-types.h"
|
||||
#include "eek-theme.h"
|
||||
#include "eek-theme-context.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -64,7 +62,8 @@ struct _EekRendererClass
|
||||
|
||||
GType eek_renderer_get_type (void) G_GNUC_CONST;
|
||||
EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
|
||||
PangoContext *pcontext);
|
||||
PangoContext *pcontext,
|
||||
GtkStyleContext *scontext);
|
||||
void eek_renderer_set_allocation_size
|
||||
(EekRenderer *renderer,
|
||||
gdouble width,
|
||||
@ -116,18 +115,8 @@ void eek_renderer_set_default_background_color
|
||||
const EekColor *color);
|
||||
void eek_renderer_get_foreground_color
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
GtkStyleContext *context,
|
||||
EekColor *color);
|
||||
void eek_renderer_get_background_color
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekColor *color);
|
||||
void eek_renderer_get_background_gradient
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekGradientType *type,
|
||||
EekColor *start,
|
||||
EekColor *end);
|
||||
void eek_renderer_set_border_width (EekRenderer *renderer,
|
||||
gdouble border_width);
|
||||
EekKey *eek_renderer_find_key_by_position
|
||||
@ -141,8 +130,5 @@ void eek_renderer_apply_transformation_for_key
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
void eek_renderer_set_theme (EekRenderer *renderer,
|
||||
EekTheme *theme);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_RENDERER_H */
|
||||
|
||||
Reference in New Issue
Block a user