shape masked widgets on gtk 2.8.x



Hello,

I've been trying for some time to develop a program that can move icons on a canvas, but if the icons are shape masked it looks very ugly. The masked area of the icon is messed up. See for yourself in the following code:

X---------------------------------------

#include <gtk/gtk.h>

GtkWidget *img_slot, *fixed_evbox;
GtkWidget *fixed;

int new_x, new_y, old_x, old_y, child_x = 150, child_y = 150, orig_x, orig_y, dx = 0, dy = 0;;
gboolean dragging=FALSE;

void set_shape_mask_from_file (GtkWidget *widget, gchar *file)
{
	GdkPixbuf *pix;
	GdkBitmap *shape_mask;
	guchar *data;
	pix = gdk_pixbuf_new_from_file (file, NULL);
	data = g_new0(guchar, gdk_pixbuf_get_width (pix) * gdk_pixbuf_get_height (pix));
	shape_mask = gdk_bitmap_create_from_data (widget->window, data, 
						  gdk_pixbuf_get_width (pix), gdk_pixbuf_get_height (pix), 100);
	gdk_pixbuf_render_threshold_alpha (pix, shape_mask, 0, 0, 0, 0, 
					   gdk_pixbuf_get_width (pix), gdk_pixbuf_get_height (pix), 100);
	gtk_widget_shape_combine_mask (widget, shape_mask, 0, 0);
}

gboolean img_event(GtkWidget *w,
		   GdkEvent *ev,
		   gpointer data)
{
	if (ev->type == GDK_BUTTON_PRESS) {
		if (ev->button.button == 1) {
			old_x = ev->button.x_root;
			old_y = ev->button.y_root;
			orig_x = ev->button.x;
			orig_y = ev->button.y;
			dx = dy = 0;
			gtk_grab_add(img_slot);
			dragging = TRUE;
			return TRUE;
		}
	}
	else if (ev->type == GDK_MOTION_NOTIFY) {
		if (ev->motion.state & GDK_BUTTON1_MASK) {      
			if (dragging) {
				new_x = ev->motion.x_root;
				new_y = ev->motion.y_root;  
				dx += new_x-old_x;
				dy += new_y-old_y;
				child_x = orig_x+dx;
				child_y = orig_y+dy;
				gtk_fixed_move (GTK_FIXED(fixed), img_slot, child_x, child_y);
				old_x = new_x;
				old_y = new_y;
				gdk_window_invalidate_rect (fixed_evbox->window, NULL, FALSE);
				gdk_window_invalidate_rect (fixed->window, NULL, FALSE);
				return TRUE;
			}
		}
	}
	else if (ev->type == GDK_EXPOSE) {
		GtkStyle *style = w->style;
		gdk_draw_rectangle (w->window, style->white_gc, TRUE, 0, 0, w->allocation.width, w->allocation.height);
		gdk_draw_line (w->window, style->black_gc, 0, 0, 
				    child_x+img_slot->allocation.width/2, 
				    child_y+img_slot->allocation.height/2);
		return TRUE;
	} 
	else if (ev->type == GDK_BUTTON_RELEASE) {
		gtk_grab_remove(gtk_grab_get_current ());
		dragging = FALSE;
		return TRUE;
	}


	return FALSE;

}

int main( int   argc,
          char *argv[] )
{
	/* GtkWidget is the storage type for widgets */
	GtkWidget *window;
	gint i;

	/* Initialise GTK */
	gtk_init (&argc, &argv);
    
	/* Create a new window */
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title (GTK_WINDOW (window), "Fixed Container");
	
	/* Here we connect the "destroy" event to a signal handler */ 
	g_signal_connect (G_OBJECT (window), "destroy",
			  G_CALLBACK (gtk_main_quit), NULL);
	
	/* Sets the border width of the window. */
	gtk_container_set_border_width (GTK_CONTAINER (window), 10);
	
	/* Create a Fixed Container */
	fixed = gtk_fixed_new ();
	fixed_evbox = gtk_event_box_new ();
	gtk_container_add (GTK_CONTAINER (fixed_evbox), fixed);
	gtk_container_add (GTK_CONTAINER (window), fixed_evbox);
	gtk_widget_show (fixed);
	
	img_slot = gtk_event_box_new ();
	{
		GtkWidget *img = gtk_image_new_from_file ("circle.png");
		gtk_widget_show(img);
		gtk_container_add (GTK_CONTAINER (img_slot), img); 
	}
	set_shape_mask_from_file (img_slot, "circle.png");

	gtk_widget_add_events (fixed_evbox, 
			       GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK);
	g_signal_connect(G_OBJECT(fixed_evbox), "event", G_CALLBACK(img_event), 0);


	/* This packs the event box into the fixed containers window. */
	gtk_fixed_put (GTK_FIXED (fixed), img_slot, 150, 150);
	/* Display the window */
	gtk_widget_show_all (window);
	/* Enter the event loop */
	gtk_main ();
	
	return 0;
} 


X--------------------------

Here the circle.png image is a big black circle (100x100) on a transparent background.
Is this a bug or I'm missing something?

Thanks,
Calin


-- 
_______________________________________________
Get your free email from http://mymail.skim.com




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]