Place keys after symbols have been read, skipping blank keys

This commit is contained in:
David Boddie
2019-07-18 17:45:51 +02:00
parent 7b41466a77
commit f6d4ca0387
4 changed files with 100 additions and 69 deletions

View File

@ -67,3 +67,64 @@ eek_keyboard_new (EekboardContextService *manager,
initial_width, initial_width,
initial_height); initial_height);
} }
const double section_spacing = 7.0;
struct place_data {
double desired_width;
double current_offset;
EekKeyboard *keyboard;
};
static void
section_placer(EekElement *element, gpointer user_data)
{
struct place_data *data = (struct place_data*)user_data;
EekBounds section_bounds = {0};
eek_element_get_bounds(element, &section_bounds);
section_bounds.width = data->desired_width;
eek_element_set_bounds(element, &section_bounds);
// Sections are rows now. Gather up all the keys and adjust their bounds.
eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
eek_element_get_bounds(element, &section_bounds);
section_bounds.y = data->current_offset;
eek_element_set_bounds(element, &section_bounds);
data->current_offset += section_bounds.height + section_spacing;
}
static void
section_counter(EekElement *element, gpointer user_data) {
double *total_height = user_data;
EekBounds section_bounds = {0};
eek_element_get_bounds(element, &section_bounds);
*total_height += section_bounds.height + section_spacing;
}
void
eek_layout_place_sections(EekKeyboard *keyboard)
{
/* Order rows */
// This needs to be done after outlines, because outlines define key sizes
// TODO: do this only for rows without bounds
// The keyboard width is given by the user via screen size. The height will be given dynamically.
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
EekBounds keyboard_bounds = {0};
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
struct place_data placer_data = {
.desired_width = keyboard_bounds.width,
.current_offset = 0,
.keyboard = keyboard,
};
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
double total_height = 0;
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
keyboard_bounds.height = total_height;
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
}

View File

@ -55,5 +55,7 @@ struct _EekLayoutClass
GType eek_layout_get_type (void) G_GNUC_CONST; GType eek_layout_get_type (void) G_GNUC_CONST;
void eek_layout_place_sections(EekKeyboard *keyboard);
G_END_DECLS G_END_DECLS
#endif /* EEK_LAYOUT_H */ #endif /* EEK_LAYOUT_H */

View File

@ -482,8 +482,23 @@ eek_section_create_key (EekSection *section,
row); row);
} }
static void keysizer(EekElement *element, gpointer user_data) { const double keyspacing = 4.0;
struct keys_info {
uint count;
double total_width;
double biggest_height;
};
static void
keysizer(EekElement *element, gpointer user_data)
{
EekKey *key = EEK_KEY(element); EekKey *key = EEK_KEY(element);
/* Skip keys without symbols for the current level. */
if (!eek_key_get_symbol(key))
return;
EekKeyboard *keyboard = EEK_KEYBOARD(user_data); EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
uint oref = eek_key_get_oref (key); uint oref = eek_key_get_oref (key);
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref); EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
@ -514,13 +529,15 @@ static void keysizer(EekElement *element, gpointer user_data) {
} }
} }
struct keys_info { static void
uint count; keycounter (EekElement *element, gpointer user_data)
double total_width; {
double biggest_height; EekKey *key = EEK_KEY(element);
};
/* Skip keys without symbols for the current level. */
if (!eek_key_get_symbol(key))
return;
static void keycounter (EekElement *element, gpointer user_data) {
struct keys_info *data = user_data; struct keys_info *data = user_data;
data->count++; data->count++;
EekBounds key_bounds = {0}; EekBounds key_bounds = {0};
@ -531,9 +548,15 @@ static void keycounter (EekElement *element, gpointer user_data) {
} }
} }
const double keyspacing = 4.0; static void
keyplacer(EekElement *element, gpointer user_data)
{
EekKey *key = EEK_KEY(element);
/* Skip keys without symbols for the current level. */
if (!eek_key_get_symbol(key))
return;
static void keyplacer(EekElement *element, gpointer user_data) {
double *current_offset = user_data; double *current_offset = user_data;
EekBounds key_bounds = {0}; EekBounds key_bounds = {0};
eek_element_get_bounds(element, &key_bounds); eek_element_get_bounds(element, &key_bounds);
@ -543,7 +566,8 @@ static void keyplacer(EekElement *element, gpointer user_data) {
*current_offset += key_bounds.width + keyspacing; *current_offset += key_bounds.width + keyspacing;
} }
void eek_section_place_keys(EekSection *section, EekKeyboard *keyboard) void
eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
{ {
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard); eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);

View File

@ -1136,63 +1136,6 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
g_slice_free (EekXmlKeyboardDesc, desc); g_slice_free (EekXmlKeyboardDesc, desc);
} }
struct place_data {
double desired_width;
double current_offset;
EekKeyboard *keyboard;
};
const double section_spacing = 7.0;
static void section_placer(EekElement *element, gpointer user_data) {
struct place_data *data = (struct place_data*)user_data;
EekBounds section_bounds = {0};
eek_element_get_bounds(element, &section_bounds);
section_bounds.width = data->desired_width;
eek_element_set_bounds(element, &section_bounds);
// Sections are rows now. Gather up all the keys and adjust their bounds.
eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
eek_element_get_bounds(element, &section_bounds);
section_bounds.y = data->current_offset;
eek_element_set_bounds(element, &section_bounds);
data->current_offset += section_bounds.height + section_spacing;
}
static void section_counter(EekElement *element, gpointer user_data) {
double *total_height = user_data;
EekBounds section_bounds = {0};
eek_element_get_bounds(element, &section_bounds);
*total_height += section_bounds.height + section_spacing;
}
static void place_sections(EekKeyboard *keyboard)
{
/* Order rows */
// This needs to be done after outlines, because outlines define key sizes
// TODO: do this only for rows without bounds
// The keyboard width is given by the user via screen size. The height will be given dynamically.
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
EekBounds keyboard_bounds = {0};
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
struct place_data placer_data = {
.desired_width = keyboard_bounds.width,
.current_offset = 0,
.keyboard = keyboard,
};
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
double total_height = 0;
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
keyboard_bounds.height = total_height;
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
}
static gboolean static gboolean
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error) parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
{ {
@ -1247,8 +1190,6 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
} }
g_hash_table_destroy (oref_hash); g_hash_table_destroy (oref_hash);
place_sections(keyboard);
geometry_parse_data_free (data); geometry_parse_data_free (data);
return TRUE; return TRUE;
} }
@ -1336,6 +1277,9 @@ parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
return FALSE; return FALSE;
} }
symbols_parse_data_free (data); symbols_parse_data_free (data);
eek_layout_place_sections(keyboard);
return TRUE; return TRUE;
} }