您的位置:首页 > 其它

GTK 背景透明button (GtkImage + EventBox)

2012-02-21 15:47 274 查看
#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();
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: