GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Apr 18, 2014 9:01 pm

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Cairo drawing problems.
PostPosted: Fri Mar 02, 2012 7:21 am 
Offline

Joined: Fri Mar 02, 2012 6:58 am
Posts: 3
Hello, i'm trying to draw a ball (on a gtk drawing area widget) and to move it.

But i have a couple of troubles here:
1) It draw a ball, but don't move it (in case of using the 1-time function call)
2) It don't draw ball (in case of using g_timeout_add, with the same arguments)

Here is the code

Code:
#include <gtk/gtk.h>
#include <cairo.h>
#include <glib.h>
//size of the window is 480*800
GtkDrawingArea *canvas;
GtkWidget *window;

static GtkWidget*

create_window(void) {
    GtkWidget *window;
    GtkBuilder *builder;


    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "/Users/student/Desktop/GTK/form.glade", NULL);

    canvas = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "canvas"));

 
    gtk_builder_connect_signals(builder, NULL);

   
    window = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
   
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_window_set_position(window, GTK_WIN_POS_CENTER);
    g_object_unref(builder);
    return window;


}

int razmer = 9;

void DebugMessage() {
     printf ("Characters: %c %c \n", 'a', 65);

}

gboolean Repaint() {
    cairo_t *cr;
    GtkWidget *wid = GTK_WIDGET(canvas);
    GdkWindow *win = gtk_widget_get_window(wid);
    cr = gdk_cairo_create(win);
    cairo_set_line_width(cr, 1);

    //drawing Rectangle, we need it for making a kind of "repaint" function.
    cairo_rectangle(cr, 0, 0, 800, 480);
    cairo_set_source_rgb(cr, 0, 0.8, 2);
    cairo_fill(cr);
    cairo_stroke_preserve(cr);

    return TRUE;
}

struct _MoveBallParams {
    int xPosition;
    int yPosition;
    int xMove;
    int yMove;
};


typedef struct _MoveBallParams MoveBallParams;

gboolean MoveBall(gpointer t) {
    Repaint();
    cairo_t *cr;
    GtkWidget *wid = GTK_WIDGET(canvas);
    GdkWindow *win = gtk_widget_get_window(wid);
    MoveBallParams *temp = (MoveBallParams*)t;
    cr = gdk_cairo_create(win);
    cairo_set_line_width(cr, 1);
    int size = 9; //size of the ball
    cairo_set_source_rgb(cr, 0, 0, 0);
    cairo_arc(cr, temp->yPosition, temp->xPosition, size, 0, 2 * 3.14);
    cairo_stroke_preserve(cr);
    cairo_fill(cr);
    temp->yPosition += temp->yMove;
    temp->xPosition +=temp->xMove;
    DebugMessage(); //just to debug and see the circle is working
    return TRUE;
}



void
start_draw(GtkButton *button,
        gpointer data) {
    MoveBallParams temp = {100, 100, 3, 3};

    g_timeout_add(50,MoveBall,&temp); //nothing happens here
    //MoveBall(&temp); //uncomment it, and you'l see that ball drawings OK, but i don't move after pressing the button again and again
   

}

int
main(int argc, char *argv[]) {
    GtkWidget *window;
    GtkWidget *builder;
    gtk_init(&argc, &argv); //запуск GTK

    window = create_window();
    gtk_widget_show(window);
   
    gtk_main();
    return 0;
}


Maybe anybody have some ideas ? Ths


Top
 Profile  
 
 Post subject: Re: Cairo drawing problems.
PostPosted: Fri Mar 02, 2012 7:50 am 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 709
Location: UK
Hello,

Drawing into a GtkDrawingArea via Cairo should be done via a "expose-event" signal on GTK v2 and "draw" signal on GTK 3. When you need the drawing area to be re-drawn you will need to tell GTK that by calling gdk_window_invalidate_rect () or similar to force a re-draw.

_________________
E.


Top
 Profile  
 
 Post subject: Re: Cairo drawing problems.
PostPosted: Fri Mar 02, 2012 10:16 am 
Offline

Joined: Fri Mar 02, 2012 6:58 am
Posts: 3
Ok, but maybe you have any idea, why moving don't work ?)


Top
 Profile  
 
 Post subject: Re: Cairo drawing problems.
PostPosted: Fri Mar 02, 2012 7:58 pm 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 709
Location: UK
OK I have now had a bit of time to re-write your code, it does require GTK+ v3. Below is how you should write the call backs for the signal "draw" and using a time-out to set the position of the ball and request a re-draw to update the displayed position of the ball. I have added a little extra to bounce the ball around :-)

I do hope it is clear, any questions just ask.

Code:
#include <gtk/gtk.h>
#include <cairo.h>
#include <glib.h>

GtkDrawingArea *canvas;

struct _MoveBallParams {
    int xPosition;
    int yPosition;
    int xMove;
    int yMove;
};

typedef struct _MoveBallParams MoveBallParams;

MoveBallParams temp = {100, 100, 3, 3};

/*
* Call back for the "draw" signal.
* Draw the ball where we are told to and in the Cairo region given to use by GTK
*/
gboolean
cb_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
    MoveBallParams *t = (MoveBallParams *) user_data;

    cairo_set_line_width(cr, 1);

    //drawing Rectangle, we need it for making a kind of "repaint" function.
    cairo_rectangle(cr, 0, 0, 800, 480);
    cairo_set_source_rgb(cr, 0, 0.8, 2);
    cairo_fill(cr);
    cairo_stroke_preserve(cr);

    cairo_set_line_width(cr, 1);
    cairo_set_source_rgb(cr, 0, 0, 0);
    cairo_arc(cr, t->xPosition, t->yPosition, 9, 0, 2 * 3.14);
    cairo_stroke_preserve(cr);
    cairo_fill(cr);

    return TRUE;
}

/*
* Timeout call back.
* Move the position of our ball and tell GTK to re-draw the drawing area
*/
gboolean
cb_timeout(gpointer user_data)
{
    MoveBallParams *t = (MoveBallParams *) user_data;
    GdkWindow *win;

    t->xPosition += t->xMove;
    t->yPosition += t->yMove;

    if (t->xPosition < 0 || t->xPosition > 800)
        t->xMove *= -1;

    if (t->yPosition < 0 || t->yPosition > 480)
        t->yMove *= -1;

    win = gtk_widget_get_window(GTK_WIDGET(canvas));
    if (win) {
        GtkAllocation allocation;

        gtk_widget_get_allocation(GTK_WIDGET(canvas), &allocation);
        gdk_window_invalidate_rect(win, &allocation, FALSE);
    }

    return TRUE;
}

/* Create our window and connect the signals */

static GtkWidget*
create_window(void)
{
    GtkWidget *window;
    GtkBuilder *builder;

    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "form.glade", NULL);

    canvas = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "canvas"));

    gtk_builder_connect_signals(builder, NULL);
   
    window = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));

    g_signal_connect(canvas, "draw", G_CALLBACK(cb_draw), &temp);
    g_timeout_add(50, cb_timeout, &temp);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);

    g_object_unref(builder);

    return window;
}

int
main(int argc, char *argv[])
{
    GtkWidget *window;

    gtk_init(&argc, &argv);

    window = create_window();
    gtk_widget_show_all(GTK_WIDGET(window));
   
    gtk_main();

    return 0;
}

_________________
E.


Top
 Profile  
 
 Post subject: Re: Cairo drawing problems.
PostPosted: Mon Mar 05, 2012 10:12 am 
Offline

Joined: Fri Mar 02, 2012 6:58 am
Posts: 3
Thanks, it helped me a lot !


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: Exabot [Bot], Google [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group