#include <cairo.h>
#include <gtk/gtk.h>
#include <math.h>
static void
draw_round_rectangle (cairo_t * cr,
double x, double y,
double width, double height, double r)
{
cairo_move_to (cr, x + r, y);
cairo_line_to (cr, x + width - r, y);
cairo_move_to (cr, x + width, y + r);
cairo_line_to (cr, x + width, y + height - r);
cairo_move_to (cr, x + width - r, y + height);
cairo_line_to (cr, x + r, y + height);
cairo_move_to (cr, x, y + height - r);
cairo_line_to (cr, x, y + r);
cairo_arc (cr, x + r, y + r, r, M_PI, 3 * M_PI / 2.0);
cairo_arc (cr, x + width - r, y + r, r, 3 * M_PI / 2, 2 * M_PI);
cairo_arc (cr, x + width - r, y + height - r, r, 0, M_PI / 2);
cairo_arc (cr, x + r, y + height - r, r, M_PI / 2, M_PI);
}
gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, cairo_surface_t *bg)
{
cairo_t *cr;
cairo_pattern_t *pattern;
pattern = cairo_pattern_create_for_surface (bg);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
cr = gdk_cairo_create (widget->window);
cairo_set_source (cr, pattern);
cairo_paint (cr);
cairo_pattern_destroy (pattern);
cairo_destroy (cr);
return FALSE;
}
typedef struct _ImageButtonPrivate ImageButtonPrivate;
typedef struct _GroupWidget GroupWidget;
struct _ImageButtonPrivate
{
gboolean hovered;
gboolean activated;
int id;
GroupWidget *group;
};
struct _GroupWidget
{
GtkWidget *pp[16];
};
GroupWidget*
group_image_button_new ()
{
return (GroupWidget*)g_malloc0(sizeof(GroupWidget));
}
void
group_image_button_add (GroupWidget* group, GtkWidget* e)
{
int i = 0;
for(i=0; i<16; ++i)
{
if(NULL == group->pp[i]) { group->pp[i] = e; break; }
}
}
void
group_image_button_activate (GroupWidget* group, GtkWidget* e)
{
int i = 0;
for(i=0; i<16; ++i)
{
if (group->pp[i] && e != group->pp[i])
{
ImageButtonPrivate *priv;
priv = (ImageButtonPrivate*)g_object_get_data (G_OBJECT (group->pp[i]), "lmf");
if (TRUE == priv->activated)
{
priv->activated = FALSE;
gtk_widget_queue_draw (group->pp[i]);
g_print ("a");
}
}
}
}
ImageButtonPrivate *
image_button_private_new (int id, GroupWidget* group)
{
ImageButtonPrivate * p =
(ImageButtonPrivate *)g_malloc0 (sizeof (ImageButtonPrivate));
p->id = id;
p->group = group;
return p;
}
gboolean
image_button_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
cairo_t *cr;
ImageButtonPrivate *priv;
cr = gdk_cairo_create (widget->window);
priv = (ImageButtonPrivate*)g_object_get_data (G_OBJECT (widget), "lmf");
if (priv->activated || priv->hovered)
{
if (priv->activated)
cairo_set_source_rgba (cr, 1.0, 0, 0, 0.2);
else if (priv->hovered)
cairo_set_source_rgba (cr, 0, 0, 1.0, 0.2);
draw_round_rectangle (cr, event->area.x, event->area.y,
event->area.width, event->area.height,
(event->area.width + event->area.height)/16);
cairo_fill(cr);
}
cairo_destroy (cr);
return FALSE;
}
gboolean
image_button_enter (GtkWidget *widget, GdkEvent *event, gpointer data)
{
ImageButtonPrivate *priv;
priv = (ImageButtonPrivate*)g_object_get_data (G_OBJECT (widget), "lmf");
priv->hovered = TRUE;
gtk_widget_queue_draw (widget);
return FALSE;
}
gboolean
image_button_leave (GtkWidget *widget, GdkEvent *event, gpointer data)
{
ImageButtonPrivate *priv;
priv = (ImageButtonPrivate*)g_object_get_data (G_OBJECT (widget), "lmf");
priv->hovered = FALSE;
gtk_widget_queue_draw (widget);
return FALSE;
}
gboolean
image_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
ImageButtonPrivate *priv;
priv = (ImageButtonPrivate*)g_object_get_data (G_OBJECT (widget), "lmf");
priv->activated = TRUE;
group_image_button_activate (priv->group, widget);
gtk_widget_queue_draw (widget);
return FALSE;
}
GtkWidget*
image_button_new (gchar *str, gchar *png, int id, GroupWidget *group)
{
GtkWidget *evt_box;
GtkWidget *vbox;
GtkWidget *image;
GtkWidget *label;
evt_box = gtk_event_box_new ();
gtk_event_box_set_visible_window (GTK_EVENT_BOX (evt_box), FALSE);
vbox = gtk_vbox_new (FALSE, 5);
gtk_container_add (GTK_CONTAINER (evt_box), vbox);
image = gtk_image_new_from_file (png);
label = gtk_label_new (str);
gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
g_signal_connect (evt_box, "enter-notify-event", G_CALLBACK (image_button_enter), NULL);
g_signal_connect (evt_box, "leave-notify-event", G_CALLBACK (image_button_leave), NULL);
g_signal_connect (evt_box, "expose-event", G_CALLBACK (image_button_expose), NULL);
g_signal_connect (evt_box, "button-press-event", G_CALLBACK (image_button_press), NULL);
g_object_set_data (G_OBJECT (evt_box), "lmf", image_button_private_new(id, group));
group_image_button_add (group, evt_box);
return evt_box;
}
int main (int argc, char* argv[])
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *hbox_top;
GtkWidget *text_view;
GtkWidget *label_bottom;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *button3;
GtkWidget *button4;
cairo_surface_t *bg;
bg = cairo_image_surface_create_from_png("bg.png");
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(window), "colar button");
gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_set_size_request (window, 800, 600);
gtk_window_set_resizable (GTK_WINDOW(window), FALSE);
gtk_widget_set_app_paintable (window, TRUE);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
gtk_widget_add_events (window, GDK_BUTTON_PRESS_MASK);
vbox = gtk_vbox_new (FALSE, 5);
gtk_container_add (GTK_CONTAINER (window), vbox);
hbox_top = gtk_hbox_new (FALSE, 5);
text_view = gtk_text_view_new ();
label_bottom = gtk_label_new ("bottom");
gtk_box_pack_start (GTK_BOX (vbox), hbox_top, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), text_view, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (vbox), label_bottom, FALSE, FALSE, 0);
GroupWidget *group = group_image_button_new ();
button1 = image_button_new ("test1", "abc.png", 1, group);
button2 = image_button_new ("test2", "abc.png", 2, group);
button3 = image_button_new ("test3", "abc.png", 3, group);
button4 = image_button_new ("test4", "abc.png", 4, group);
gtk_box_pack_start (GTK_BOX (hbox_top), button1, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox_top), button2, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox_top), button3, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox_top), button4, FALSE, FALSE, 0);
g_signal_connect (window, "expose-event", G_CALLBACK (on_expose_event), bg);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show_all (window);
gtk_main();
}