From 0b9fa0713dd4e2297e5efc808178c0cd26d2842d Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Thu, 16 Jul 2015 22:23:22 +0200 Subject: First stab at making buttons editable... Still have to add a dialogue where the actual editing can take place... --- keymaps/default/test2.layout | 5 +- rcm-client-receive.c | 146 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 127 insertions(+), 24 deletions(-) diff --git a/keymaps/default/test2.layout b/keymaps/default/test2.layout index 3a49506..c1ff8dc 100644 --- a/keymaps/default/test2.layout +++ b/keymaps/default/test2.layout @@ -20,7 +20,7 @@ Map=nec:0xf00f0013:KEY_LEFT Map=nec:0xf00f0014:KEY_RIGHT [Layout] -Rows=7 +Rows=8 Cols=3 Button=KEY_NUMERIC_1 Button=KEY_NUMERIC_2 @@ -35,6 +35,9 @@ Button=Blank Button=KEY_NUMERIC_0 Button=Blank Button=Blank +Button=Blank +Button=Blank +Button=Blank Button=KEY_UP Button=Blank Button=KEY_LEFT diff --git a/rcm-client-receive.c b/rcm-client-receive.c index 734bc31..47a45ab 100644 --- a/rcm-client-receive.c +++ b/rcm-client-receive.c @@ -15,8 +15,14 @@ #define WINDOW_WIDTH 300 #define WINDOW_HEIGHT 300 +enum rcbutton_type { + RCBUTTON_TYPE_NORMAL, + RCBUTTON_TYPE_BLANK +}; + struct rcbutton { char *name; + enum rcbutton_type type; GtkWidget *button; }; @@ -39,10 +45,10 @@ struct state { static struct state state; -#if 0 static void -quick_message(GtkWindow *parent, gchar *message) +quick_message(GtkWidget *widget, gchar *message) { + GtkWindow *parent = GTK_WINDOW(gtk_widget_get_toplevel(widget)); GtkWidget *dialog, *label, *content_area; GtkDialogFlags flags; @@ -56,7 +62,6 @@ quick_message(GtkWindow *parent, gchar *message) gtk_container_add(GTK_CONTAINER(content_area), label); gtk_widget_show_all(dialog); } -#endif /* Hacky McHack - Estimate the size needed for a button with ABCDEF */ static int @@ -127,7 +132,6 @@ create_button_img(GtkWidget *button, const char *keycode) surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, img_size, img_size); ct = cairo_create(surface); - layout = pango_cairo_create_layout(ct); gtk_style_context_get(gtk_widget_get_style_context(button), gtk_widget_get_state_flags(button), @@ -135,26 +139,50 @@ create_button_img(GtkWidget *button, const char *keycode) GTK_STYLE_PROPERTY_COLOR, &color, NULL); - pango_layout_set_font_description(layout, font_description); - pango_font_description_free(font_description); - gdk_cairo_set_source_rgba(ct, color); gdk_rgba_free(color); - pango_layout_set_text(layout, label, -1); - - pango_layout_get_pixel_size(layout, &pw, &ph); + if (!strcmp(keycode, "KEY_RESERVED")) { + x = (float)img_size / 2.0f; + y = (float)img_size / 2.0f; + cairo_set_line_width(ct, 2); + cairo_translate(ct, x, y); + + cairo_arc(ct, 0, 0, x - 2 - REMOTE_BUTTON_PADDING * 2.0f, 0, 2 * M_PI); + cairo_stroke(ct); + + cairo_set_line_width(ct, 3); + cairo_move_to(ct, -x + 3 + REMOTE_BUTTON_PADDING * 4.0f, 0); + cairo_line_to(ct, x - 3 - REMOTE_BUTTON_PADDING * 4.0f, 0); + cairo_stroke(ct); + cairo_move_to(ct, 0, -y + 3 + REMOTE_BUTTON_PADDING * 4.0f); + cairo_line_to(ct, 0, y - 3 - REMOTE_BUTTON_PADDING * 4.0f); + cairo_stroke(ct); + + } else { + if (!strncmp(label, "KEY_NUMERIC_", strlen("KEY_NUMERIC_"))) + label += strlen("KEY_NUMERIC_"); + else if (!strncmp(label, "KEY_", strlen("KEY_"))) + label += strlen("KEY_"); + + layout = pango_cairo_create_layout(ct); + pango_layout_set_font_description(layout, font_description); + pango_font_description_free(font_description); + pango_layout_set_text(layout, label, -1); + pango_layout_get_pixel_size(layout, &pw, &ph); + + scale_x = ((float)img_size - REMOTE_BUTTON_PADDING * 2.0f) / (float)pw; + scale_y = ((float)img_size - REMOTE_BUTTON_PADDING * 2.0f) / (float)ph; + scale = scale_x < scale ? scale_x : scale; + scale = scale_y < scale ? scale_y : scale; + x = (float)img_size / 2.0f - ((float)pw / 2.0f) * scale; + y = (float)img_size / 2.0f - ((float)ph / 2.0f) * scale; + cairo_move_to(ct, x, y); + cairo_scale(ct, scale, scale); + pango_cairo_show_layout(ct, layout); + g_object_unref(layout); + } - scale_x = ((float)img_size - REMOTE_BUTTON_PADDING * 2.0f) / (float)pw; - scale_y = ((float)img_size - REMOTE_BUTTON_PADDING * 2.0f) / (float)ph; - scale = scale_x < scale ? scale_x : scale; - scale = scale_y < scale ? scale_y : scale; - x = (float)img_size / 2.0f - ((float)pw / 2.0f) * scale; - y = (float)img_size / 2.0f - ((float)ph / 2.0f) * scale; - cairo_move_to(ct, x, y); - cairo_scale(ct, scale, scale); - pango_cairo_show_layout(ct, layout); - g_object_unref(layout); cairo_destroy(ct); lik->cairo_surface = surface; @@ -163,6 +191,53 @@ out: gtk_button_set_image(GTK_BUTTON(button), img); } +static void +edit_button(GtkButton *button, gpointer user_data) +{ + struct rcbutton *rcb = user_data; + gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); + + if (!state.editing || !active) + return; + + switch (rcb->type) { + case RCBUTTON_TYPE_NORMAL: + quick_message(GTK_WIDGET(button), "Asked to edit a button\n"); + break; + case RCBUTTON_TYPE_BLANK: + quick_message(GTK_WIDGET(button), "Asked to add a button\n"); + break; + default: + break; + } + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), false); +} + +static struct rcbutton * +new_blank_add(GtkGrid *grid, guint x, guint y) +{ + struct rcbutton *rcb; + GtkWidget *revealer; + GtkWidget *button; + + rcb = g_malloc0(sizeof(*rcb)); + rcb->type = RCBUTTON_TYPE_BLANK; + revealer = gtk_revealer_new(); + gtk_revealer_set_reveal_child(GTK_REVEALER(revealer), false); + gtk_revealer_set_transition_type(GTK_REVEALER(revealer), GTK_REVEALER_TRANSITION_TYPE_CROSSFADE); + gtk_grid_attach(grid, revealer, x, y, 1, 1); + + button = gtk_toggle_button_new(); + g_signal_connect(button, "clicked", G_CALLBACK(edit_button), rcb); + gtk_widget_set_sensitive(button, true); + gtk_widget_set_tooltip_text(button, "Add key"); + gtk_container_add(GTK_CONTAINER(revealer), button); + create_button_img(button, "KEY_RESERVED"); + rcb->button = revealer; + return rcb; +} + static struct rcbutton * new_button_add(GtkGrid *grid, const gchar *protocol, guint64 scancode, const char *keycode, GdkRGBA *color, guint x, guint y) @@ -171,8 +246,10 @@ new_button_add(GtkGrid *grid, const gchar *protocol, guint64 scancode, gchar *tooltip; rcb = g_malloc0(sizeof(*rcb)); + rcb->type = RCBUTTON_TYPE_NORMAL; rcb->name = strdup(keycode); rcb->button = gtk_toggle_button_new(); + g_signal_connect(rcb->button, "clicked", G_CALLBACK(edit_button), rcb); gtk_widget_set_sensitive(rcb->button, false); tooltip = g_strdup_printf("Protocol: %s\nScancode: 0x%08" PRIx64 "\nKeycode : %s", protocol, scancode, keycode); gtk_widget_set_tooltip_text(rcb->button, tooltip); @@ -298,6 +375,7 @@ set_edit_keymap(bool editing) for (l = state.remotes; l; l = l->next) { struct remote *remote = l->data; + GList *b; if (editing) { remote->edit_button = gtk_button_new_with_label("Resize"); @@ -309,6 +387,22 @@ set_edit_keymap(bool editing) gtk_widget_destroy(remote->edit_button); remote->edit_button = NULL; } + + for (b = remote->buttons; b; b = b->next) { + struct rcbutton *rcb = b->data; + + switch (rcb->type) { + case RCBUTTON_TYPE_BLANK: + gtk_revealer_set_reveal_child(GTK_REVEALER(rcb->button), editing); + break; + case RCBUTTON_TYPE_NORMAL: + gtk_widget_set_sensitive(rcb->button, editing); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rcb->button), false); + break; + default: + break; + } + } } } @@ -342,7 +436,7 @@ void rcng_client_receive_keypress(GDBusObject *obj, const gchar *keycode, bool p unsigned affected = 0; /* FIXME: Use object path, this is just test code */ - if (!state.active) + if (!state.active || state.editing) return; for (l = state.remotes; l; l = l->next) { @@ -352,6 +446,9 @@ void rcng_client_receive_keypress(GDBusObject *obj, const gchar *keycode, bool p for (button = remote->buttons; button; button = button->next) { struct rcbutton *rcb = button->data; + if (rcb->type != RCBUTTON_TYPE_NORMAL) + continue; + if (strcmp(keycode, rcb->name)) continue; @@ -423,9 +520,12 @@ get_keymap(RCDevice *object, const gchar *keymap_name) keycode, NULL, col, row); remote->buttons = g_list_append(remote->buttons, rcb); printf("Got a button: %s:0x%08" PRIx64 ":%s\n", protocol, scancode, keycode); - } else if (!strcmp(type, "blank")) + } else if (!strcmp(type, "blank")) { + struct rcbutton *rcb; + rcb = new_blank_add(GTK_GRID(grid), col, row); + remote->buttons = g_list_append(remote->buttons, rcb); printf("Got a blank\n"); - else + } else printf("Error: unknown type: %s (treating as blank)\n", type); col++; -- cgit v1.2.3