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

_______________________________________________
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list

Reply via email to