renderer: Render whole keyboard the same way as pressed buttons
Removed window size dependent surface.
This commit is contained in:
@ -52,7 +52,6 @@ typedef struct _EekRendererPrivate
|
||||
gint origin_y;
|
||||
|
||||
PangoFontDescription *font; // owned reference
|
||||
cairo_surface_t *keyboard_surface;
|
||||
|
||||
} EekRendererPrivate;
|
||||
|
||||
@ -62,7 +61,6 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
|
||||
static void eek_renderer_render_button_label (EekRenderer *self, cairo_t *cr, GtkStyleContext *ctx,
|
||||
const struct squeek_button *button);
|
||||
|
||||
static void invalidate (EekRenderer *renderer);
|
||||
void eek_render_button (EekRenderer *self,
|
||||
cairo_t *cr, const struct squeek_button *button,
|
||||
gboolean pressed, gboolean locked);
|
||||
@ -75,91 +73,6 @@ struct _CreateKeyboardSurfaceCallbackData {
|
||||
};
|
||||
typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData;
|
||||
|
||||
static void
|
||||
create_keyboard_surface_button_callback (struct squeek_button *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateKeyboardSurfaceCallbackData *data = user_data;
|
||||
EekBounds bounds = squeek_button_get_bounds(button);
|
||||
|
||||
cairo_save (data->cr);
|
||||
|
||||
cairo_translate (data->cr, bounds.x, bounds.y);
|
||||
cairo_rectangle (data->cr,
|
||||
0.0,
|
||||
0.0,
|
||||
bounds.width,
|
||||
bounds.height);
|
||||
cairo_clip (data->cr);
|
||||
|
||||
eek_render_button (data->renderer, data->cr, button, FALSE, FALSE);
|
||||
|
||||
cairo_restore (data->cr);
|
||||
}
|
||||
|
||||
static void
|
||||
create_keyboard_surface_row_callback (struct squeek_row *row,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateKeyboardSurfaceCallbackData *data = user_data;
|
||||
|
||||
EekBounds bounds = squeek_row_get_bounds(row);
|
||||
|
||||
cairo_save (data->cr);
|
||||
cairo_translate (data->cr, bounds.x, bounds.y);
|
||||
|
||||
gint angle = squeek_row_get_angle (row);
|
||||
cairo_rotate (data->cr, angle * G_PI / 180);
|
||||
|
||||
data->row = row;
|
||||
squeek_row_foreach(row, create_keyboard_surface_button_callback, data);
|
||||
|
||||
cairo_restore (data->cr);
|
||||
}
|
||||
|
||||
static void
|
||||
render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
CreateKeyboardSurfaceCallbackData data = {
|
||||
.cr = cairo_create (priv->keyboard_surface),
|
||||
.renderer = renderer,
|
||||
};
|
||||
|
||||
/* Paint the background covering the entire widget area */
|
||||
gtk_render_background (priv->view_context,
|
||||
data.cr,
|
||||
0, 0,
|
||||
priv->allocation_width, priv->allocation_height);
|
||||
gtk_render_frame (priv->view_context,
|
||||
data.cr,
|
||||
0, 0,
|
||||
priv->allocation_width, priv->allocation_height);
|
||||
|
||||
GdkRGBA color = {0};
|
||||
gtk_style_context_get_color (priv->view_context, GTK_STATE_FLAG_NORMAL, &color);
|
||||
cairo_set_source_rgba (data.cr,
|
||||
color.red,
|
||||
color.green,
|
||||
color.blue,
|
||||
color.alpha);
|
||||
|
||||
cairo_save (data.cr);
|
||||
|
||||
EekBounds bounds = squeek_view_get_bounds (view);
|
||||
cairo_translate (data.cr, bounds.x, bounds.y);
|
||||
|
||||
/* draw rows */
|
||||
squeek_view_foreach(view,
|
||||
create_keyboard_surface_row_callback,
|
||||
&data);
|
||||
|
||||
cairo_restore (data.cr);
|
||||
|
||||
cairo_destroy (data.cr);
|
||||
}
|
||||
|
||||
static void
|
||||
render_outline (cairo_t *cr,
|
||||
GtkStyleContext *ctx,
|
||||
@ -431,21 +344,17 @@ eek_renderer_render_keyboard (EekRenderer *self,
|
||||
g_return_if_fail (priv->allocation_width > 0.0);
|
||||
g_return_if_fail (priv->allocation_height > 0.0);
|
||||
|
||||
/* Paint the background covering the entire widget area */
|
||||
gtk_render_background (priv->view_context,
|
||||
cr,
|
||||
0, 0,
|
||||
priv->allocation_width, priv->allocation_height);
|
||||
|
||||
cairo_save(cr);
|
||||
cairo_translate (cr, priv->origin_x, priv->origin_y);
|
||||
cairo_scale (cr, priv->scale, priv->scale);
|
||||
if (priv->keyboard_surface)
|
||||
cairo_surface_destroy (priv->keyboard_surface);
|
||||
|
||||
priv->keyboard_surface = cairo_surface_create_for_rectangle (
|
||||
cairo_get_target (cr), 0, 0,
|
||||
priv->allocation_width, priv->allocation_height);
|
||||
|
||||
render_keyboard_surface (self, squeek_layout_get_current_view(priv->keyboard->layout));
|
||||
|
||||
cairo_set_source_surface (cr, priv->keyboard_surface, 0.0, 0.0);
|
||||
cairo_paint (cr);
|
||||
|
||||
squeek_draw_layout_base_view(priv->keyboard->layout, self, cr);
|
||||
squeek_layout_draw_all_changed(priv->keyboard->layout, self, cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
@ -476,6 +385,7 @@ eek_renderer_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
(void)value;
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@ -497,8 +407,7 @@ eek_renderer_dispose (GObject *object)
|
||||
priv->pcontext = NULL;
|
||||
}
|
||||
|
||||
/* this will release all allocated surfaces and font if any */
|
||||
invalidate (EEK_RENDERER(object));
|
||||
// this is where renderer-specific surfaces would be released
|
||||
|
||||
G_OBJECT_CLASS (eek_renderer_parent_class)->dispose (object);
|
||||
}
|
||||
@ -577,7 +486,6 @@ eek_renderer_init (EekRenderer *self)
|
||||
priv->scale = 1.0;
|
||||
priv->scale_factor = 1;
|
||||
priv->font = NULL;
|
||||
priv->keyboard_surface = NULL;
|
||||
|
||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||
|
||||
@ -586,17 +494,6 @@ eek_renderer_init (EekRenderer *self)
|
||||
priv->css_provider = squeek_load_style();
|
||||
}
|
||||
|
||||
static void
|
||||
invalidate (EekRenderer *renderer)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
if (priv->keyboard_surface) {
|
||||
cairo_surface_destroy (priv->keyboard_surface);
|
||||
priv->keyboard_surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EekRenderer *
|
||||
eek_renderer_new (LevelKeyboard *keyboard,
|
||||
PangoContext *pcontext)
|
||||
@ -667,7 +564,8 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
|
||||
/* Set the rendering offset in widget coordinates to center the keyboard */
|
||||
priv->origin_x = (gint)floor((width - (scale * w)) / 2);
|
||||
priv->origin_y = (gint)floor((height - (scale * h)) / 2);
|
||||
invalidate (renderer);
|
||||
|
||||
// This is where size-dependent surfaces would be released
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -75,6 +75,31 @@ mod c {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn squeek_draw_layout_base_view(
|
||||
layout: *mut Layout,
|
||||
renderer: EekRenderer,
|
||||
cr: *mut cairo_sys::cairo_t,
|
||||
) {
|
||||
let layout = unsafe { &mut *layout };
|
||||
let cr = unsafe { cairo::Context::from_raw_none(cr) };
|
||||
let view = layout.get_current_view();
|
||||
let view_position = view.bounds.get_position();
|
||||
for row in &view.rows {
|
||||
for button in &row.buttons {
|
||||
let position = &view_position
|
||||
+ row.bounds.clone().unwrap().get_position()
|
||||
+ button.bounds.get_position();
|
||||
render_button_at_position(
|
||||
renderer, &cr,
|
||||
position, button.as_ref(),
|
||||
keyboard::PressType::Released, false,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Renders a button at a position (button's own bounds ignored)
|
||||
|
||||
11
src/layout.h
11
src/layout.h
@ -21,11 +21,6 @@ int32_t squeek_row_get_angle(const struct squeek_row*);
|
||||
|
||||
EekBounds squeek_row_get_bounds(const struct squeek_row*);
|
||||
|
||||
typedef void (*ButtonCallback) (struct squeek_button *button, gpointer user_data);
|
||||
void squeek_row_foreach(struct squeek_row*,
|
||||
ButtonCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
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*);
|
||||
@ -37,11 +32,6 @@ void squeek_button_print(const struct squeek_button* button);
|
||||
|
||||
EekBounds squeek_view_get_bounds(const struct squeek_view*);
|
||||
|
||||
typedef void (*RowCallback) (struct squeek_row *row, gpointer user_data);
|
||||
void squeek_view_foreach(struct squeek_view*,
|
||||
RowCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
squeek_layout_place_contents(struct squeek_layout*);
|
||||
struct squeek_view *squeek_layout_get_current_view(struct squeek_layout*);
|
||||
@ -65,4 +55,5 @@ void squeek_layout_drag(struct squeek_layout *layout, struct zwp_virtual_keyboar
|
||||
struct transformation widget_to_layout,
|
||||
uint32_t timestamp, EekGtkKeyboard *ui_keyboard);
|
||||
void squeek_layout_draw_all_changed(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr);
|
||||
void squeek_draw_layout_base_view(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr);
|
||||
#endif
|
||||
|
||||
@ -43,10 +43,6 @@ pub mod c {
|
||||
use std::ops::Add;
|
||||
|
||||
// The following defined in C
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct UserData(*const c_void);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct EekGtkKeyboard(pub *const gtk_sys::GtkWidget);
|
||||
@ -131,9 +127,6 @@ pub mod c {
|
||||
}
|
||||
}
|
||||
|
||||
type ButtonCallback = unsafe extern "C" fn(button: *mut ::layout::Button, data: *mut UserData);
|
||||
type RowCallback = unsafe extern "C" fn(row: *mut ::layout::Row, data: *mut UserData);
|
||||
|
||||
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
|
||||
|
||||
#[no_mangle]
|
||||
@ -142,20 +135,6 @@ pub mod c {
|
||||
unsafe { &*view }.bounds.clone()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn squeek_view_foreach(
|
||||
view: *mut ::layout::View,
|
||||
callback: RowCallback,
|
||||
data: *mut UserData,
|
||||
) {
|
||||
let view = unsafe { &mut *view };
|
||||
for row in view.rows.iter_mut() {
|
||||
let row = row.as_mut() as *mut ::layout::Row;
|
||||
unsafe { callback(row, data) };
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn squeek_row_get_angle(row: *const ::layout::Row) -> i32 {
|
||||
@ -173,20 +152,6 @@ pub mod c {
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn squeek_row_foreach(
|
||||
row: *mut ::layout::Row,
|
||||
callback: ButtonCallback,
|
||||
data: *mut UserData,
|
||||
) {
|
||||
let row = unsafe { &mut *row };
|
||||
for button in row.buttons.iter_mut() {
|
||||
let button = button.as_mut() as *mut ::layout::Button;
|
||||
unsafe { callback(button, data) };
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn squeek_button_get_bounds(button: *const ::layout::Button) -> Bounds {
|
||||
|
||||
Reference in New Issue
Block a user