当前位置: 首页 > 工具软件 > EventBox > 使用案例 >

GTK 背景透明button (GtkImage + EventBox)

昌招
2023-12-01
#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();
}


 


 类似资料: