gtk - How Automatically Update Two or Several GtkDrawAreas in C -
i'm trying develop little supervision system 2 gtkdrawarea widgets , update them simultaneously whenever toogle buttons regarded each drawarea. little example made ploting 2 sinoides.
however first gtkdrawarea widget updated in did, other remains freezed until rezise gtkwindow. tried use g_timeout_add_full seens work 1 gtkdrawarea.
i'm sending image of test aplication.
if me thankful.
ps: sorry english :-)
here code:
#include <stdlib.h> #include <gtk/gtk.h> #include <glib.h> #include <cairo.h> #include <math.h> #include <unistd.h> #include <stdlib.h> gtkwidget *window; gtkwidget *darea1; gtkwidget *darea2; double w_larg = 1600; double w_alt = 1200; bool toggle_stat1 = false; bool toggle_stat2 = false; int width, height; double fase1 = 2; double amp1 = 1.25; double fase2 = 4; double amp2 = 1.25; gboolean flag_amp1 = true; gboolean flag_amp2 = true; static gboolean invalidate_drawing1(gpointer data); static gboolean invalidate_drawing2(gpointer data); //******************************************************************************* static gboolean on_toggled1(gtkwidget *widget, gpointer data) { if(gtk_toggle_button_get_active(gtk_toggle_button(widget))) {toggle_stat1 = true; printf("togglebutton01 --> acionado / toggle_stat1 = %d\n",toggle_stat1); g_timeout_add_full(g_priority_default_idle,250,invalidate_drawing1,darea1,null); // variação atualizada da linha acima :-) } else {toggle_stat1 = false; printf("togglebutton01 --> liberado / toggle_stat1 = %d\n",toggle_stat1); } return false; } //******************************************************************************* static gboolean on_toggled2(gtkwidget *widget, gpointer data) { if(gtk_toggle_button_get_active(gtk_toggle_button(widget))) {toggle_stat2 = true; printf("togglebutton02 --> acionado / toggle_stat2 = %d\n",toggle_stat2); g_timeout_add_full(g_priority_default_idle,250,invalidate_drawing2,darea2,null); // variação atualizada da linha acima :-) } else {toggle_stat2 = false; printf("togglebutton02 --> liberado / toggle_stat2 = %d\n",toggle_stat2); } return false; } //******************************************************************************* //******************************************************************************* //******************************************************************************* //******************************************************************************* static gboolean draw_darea1(gtkwidget *widget, cairo_t *cr, gpointer data) { int valor1; double valor2; static const double dashed1[] = {4.0, 21.0, 2.0}; static const double dashed3[] = {2.0}; cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_rgba(cr, 0.45, 0.45, 0.45, 1); cairo_rectangle(cr,0 , 0, widget->allocation.width, widget->allocation.height); cairo_fill(cr); double = widget->allocation.width; double j = widget->allocation.height; double sc = fase1*m_pi/i; double y; double h = 0; if (amp1 != 0) h = h + j/amp1; //--------------------------------------------------------------------------- cairo_set_source_rgba(cr, 0, 0, 1, 1); cairo_set_line_width(cr, 1.5); cairo_move_to(cr, 0, (j/2)+(sin( (-i/2)*sc )*(h/2)) ); for(double x=(-i/2);x<=(i/2);x=x+2) { valor1 = rand()%5; valor2 = rand()%50; y=x*sc; if (valor1 < 3 ) cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) + valor2 ); if (valor1 == 3) cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) ); if (valor1 > 3 ) cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) - valor2 ); } cairo_stroke(cr); //--------------------------------------------------------------------------- cairo_set_source_rgba(cr, 1, 1, 0, 1); cairo_set_dash(cr,dashed1, 1, 0 ); cairo_set_line_width(cr, 1.5); cairo_move_to(cr, 0, (j/2)+(sin( (-i/2)*sc )*(h/2)) ); for(double x=(-i/2);x<=(i/2);x=x+10) { y=x*sc; cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) ); } cairo_stroke(cr); //--------------------------------------------------------------------------- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1); cairo_set_dash(cr,dashed3, 1, 0 ); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,0,(j/2)); cairo_line_to(cr,i,(j/2)); cairo_move_to(cr,(i/2),0); cairo_line_to(cr,(i/2),j); cairo_stroke(cr); cairo_destroy(cr); return true; } //******************************************************************************* //******************************************************************************* //******************************************************************************* //******************************************************************************* static gboolean draw_darea2(gtkwidget *widget, cairo_t *cr, gpointer data) { int valor1; double valor2; static const double dashed1[] = {4.0, 21.0, 2.0}; static const double dashed3[] = {2.0}; cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_rgba(cr, 0.45, 0.45, 0.45, 1); cairo_rectangle(cr,0 , 0, widget->allocation.width, widget->allocation.height); cairo_fill(cr); double = widget->allocation.width; double j = widget->allocation.height; double sc = fase2*m_pi/i; double y; double h = 0; if (amp2 != 0) h = h + j/amp2; //--------------------- cairo_set_source_rgba(cr, 0, 0, 1, 1); cairo_set_line_width(cr, 1.5); cairo_move_to(cr, 0, (j/2)+(sin( (-i/2)*sc )*(h/2)) ); for(double x=(-i/2);x<=(i/2);x=x+2) { valor1 = rand()%5; valor2 = rand()%50; y=x*sc; if (valor1 < 3 ) cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) + valor2 ); if (valor1 == 3) cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) ); if (valor1 > 3 ) cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) - valor2 ); } cairo_stroke(cr); //--------------------- cairo_set_source_rgba(cr, 0, 1, 0, 1); cairo_set_dash(cr,dashed1, 1, 0 ); cairo_set_line_width(cr, 1.5); cairo_move_to(cr, 0, (j/2)+(sin( (-i/2)*sc )*(h/2)) ); for(double x=(-i/2);x<=(i/2);x=x+10) { y=x*sc; cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) ); } cairo_stroke(cr); //--------------------- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1); cairo_set_dash(cr,dashed3, 1, 0 ); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,0,(j/2)); cairo_line_to(cr,i,(j/2)); cairo_move_to(cr,(i/2),0); cairo_line_to(cr,(i/2),j); cairo_stroke(cr); cairo_destroy(cr); return true; } //******************************************************************************* //******************************************************************************* //******************************************************************************* //******************************************************************************* static gboolean invalidate_drawing1(gpointer data) { gdkwindow *win; g_print("t_signal-1 | amp1 = %2.3f | ",amp1); if (toggle_stat1==true) { if ((flag_amp1==true)&&(amp1 <= 3)) amp1=amp1+0.25; else flag_amp1=false; if ((flag_amp1==false)&&(amp1 >= 1.25)) amp1=amp1-0.25; else flag_amp1=true; } //--------------------- win = gtk_widget_get_window(gtk_widget(data)); if (win) { gtkallocation allocation; gtk_widget_get_allocation(gtk_widget(data), &allocation); gdk_window_invalidate_rect(win, &allocation, false); } if (flag_amp1 == true) return true; else return false; } //********************** //********************** //********************** static gboolean invalidate_drawing2(gpointer data) { gdkwindow *win; //--------------------- g_print("t_signal-2 | amp2 = %2.3f\n",amp2); if (toggle_stat2==true) { if ((flag_amp2==true)&&(amp2 <= 3)) amp2=amp2+0.25; else flag_amp2=false; if ((flag_amp2==false)&&(amp2 >= 1.25)) amp2=amp2-0.25; else flag_amp2=true; } //--------------------- win = gtk_widget_get_window(gtk_widget(data)); if (win) { gtkallocation allocation; gtk_widget_get_allocation(gtk_widget(data), &allocation); gdk_window_invalidate_rect(win, &allocation, false); } if (flag_amp2 == true) return true; else return false; } //********************** //********************** //********************** int main (int argc, char *argv[]) { gtkbuilder *builder; gtkwidget *togglebutton1; gtkwidget *togglebutton2; gtkwidget *togglebutton3; gtkwidget *button1; // amp+ gtkwidget *button2; // amp- gtk_init (&argc, &argv); builder = gtk_builder_new (); gtk_builder_add_from_file (builder, "gtk_glade_2drawarea01-r00.glade", null); //carrega informações projeto glade para o gtkbuilder window = gtk_widget(gtk_builder_get_object (builder, "window1")); //retorna o objeto window, para mostrá-lo mais tarde darea1 = gtk_widget(gtk_builder_get_object (builder, "drawingarea1")); //retorna o objeto drawingarea, para mostrá-lo mais tarde darea2 = gtk_widget(gtk_builder_get_object (builder, "drawingarea2")); //retorna o objeto drawingarea, para mostrá-lo mais tarde togglebutton1 = gtk_widget(gtk_builder_get_object (builder, "togglebutton1")); //retorna o objeto togglebutton1, para mostrá-lo mais tarde togglebutton2 = gtk_widget(gtk_builder_get_object (builder, "togglebutton2")); //retorna o objeto togglebutton1, para mostrá-lo mais tarde togglebutton3 = gtk_widget(gtk_builder_get_object (builder, "togglebutton3")); //retorna o objeto togglebutton1, para mostrá-lo mais tarde button1 = gtk_widget(gtk_builder_get_object (builder, "button1")); //retorna o objeto button1, para mostrá-lo mais tarde button2 = gtk_widget(gtk_builder_get_object (builder, "button2")); //retorna o objeto button2, para mostrá-lo mais tarde gtk_window_set_title(gtk_window(window), "gtk 2 viewports drawarea 01"); gtk_builder_connect_signals (builder, null); //conecta todos os eventos dentro projeto glade. g_object_unref (g_object (builder)); //exclui o gtkbuilder, pois não iremos mais usá-lo nesse exemplo. g_signal_connect(g_object(togglebutton1) , "toggled" , g_callback(on_toggled1) , null); g_signal_connect(g_object(togglebutton2) , "toggled" , g_callback(on_toggled2) , null); g_signal_connect(g_object(darea1), "expose-event", g_callback(draw_darea1), null); g_signal_connect(g_object(darea2), "expose-event", g_callback(draw_darea2), null); g_signal_connect_swapped(g_object(window) , "destroy", g_callback(gtk_main_quit) , g_object(window)); gtk_widget_show_all(window); //mostra janela com seus objetos gtk_main (); return 0; }
here's code fixed (below) after suggestion andlabs , wogsland. thank you.
#include <stdlib.h> #include <gtk/gtk.h> #include <glib.h> #include <cairo.h> #include <math.h> #include <unistd.h> #include <stdlib.h> gtkwidget *window; gtkwidget *darea1; gtkwidget *darea2; bool toggle_stat1 = false; bool toggle_stat2 = false; double fase1 = 2; double amp1 = 1.25; double fase2 = 4; double amp2 = 1.25; gboolean flag_amp1 = true; gboolean flag_amp2 = true; //******************************************************************************* static gboolean on_toggled1(gtkwidget *widget, gpointer data) { if(gtk_toggle_button_get_active(gtk_toggle_button(widget))) {toggle_stat1 = true; printf("togglebutton01 --> acionado / toggle_stat1 = %d\n",toggle_stat1); } else {toggle_stat1 = false; printf("togglebutton01 --> liberado / toggle_stat1 = %d\n",toggle_stat1); } return false; } //******************************************************************************* static gboolean on_toggled2(gtkwidget *widget, gpointer data) { if(gtk_toggle_button_get_active(gtk_toggle_button(widget))) {toggle_stat2 = true; printf("togglebutton02 --> acionado / toggle_stat2 = %d\n",toggle_stat2); } else {toggle_stat2 = false; printf("togglebutton02 --> liberado / toggle_stat2 = %d\n",toggle_stat2); } return false; } //******************************************************************************* //******************************************************************************* static gboolean draw_darea1(gtkwidget *widget, cairo_t *cr, gpointer data) { static const double dashed1[] = {4.0, 21.0, 2.0}; cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_rgba(cr, 0.45, 0.45, 0.45, 1); cairo_rectangle(cr,0 , 0, widget->allocation.width, widget->allocation.height); cairo_fill(cr); double = widget->allocation.width; double j = widget->allocation.height; double sc = fase1*m_pi/i; double y; double h = 0; if (amp1 != 0) h = h + j/amp1; //--------------------------------------------------------------------------- cairo_set_source_rgba(cr, 1, 1, 0, 1); cairo_set_dash(cr,dashed1, 1, 0 ); cairo_set_line_width(cr, 1.5); cairo_move_to(cr, 0, (j/2)+(sin( (-i/2)*sc )*(h/2)) ); for(double x=(-i/2);x<=(i/2);x=x+10) { y=x*sc; cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) ); } cairo_stroke(cr); return true; } //******************************************************************************* //******************************************************************************* static gboolean draw_darea2(gtkwidget *widget, cairo_t *cr, gpointer data) { static const double dashed1[] = {4.0, 21.0, 2.0}; cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_rgba(cr, 0.45, 0.45, 0.45, 1); cairo_rectangle(cr,0 , 0, widget->allocation.width, widget->allocation.height); cairo_fill(cr); double = widget->allocation.width; double j = widget->allocation.height; double sc = fase2*m_pi/i; double y; double h = 0; if (amp2 != 0) h = h + j/amp2; //--------------------- cairo_set_source_rgba(cr, 0, 1, 0, 1); cairo_set_dash(cr,dashed1, 1, 0 ); cairo_set_line_width(cr, 1.5); cairo_move_to(cr, 0, (j/2)+(sin( (-i/2)*sc )*(h/2)) ); for(double x=(-i/2);x<=(i/2);x=x+10) { y=x*sc; cairo_line_to(cr,x+(i/2),(j/2)+(sin(y)*(h/2)) ); } cairo_stroke(cr); return true; } //******************************************************************************* //******************************************************************************* static gboolean invalidate_drawing1(gtkwidget *widget) { g_print("t_signal-1 | amp1 = %2.3f | ",amp1); if (toggle_stat1==true) { if ((flag_amp1==true)&&(amp1 <= 3)) amp1=amp1+0.25; else flag_amp1=false; if ((flag_amp1==false)&&(amp1 >= 1.25)) amp1=amp1-0.25; else flag_amp1=true; } //--------------------- gtk_widget_queue_draw(widget); return true; } //********************** //********************** static gboolean invalidate_drawing2(gtkwidget *widget) { g_print("t_signal-2 | amp2 = %2.3f\n",amp2); if (toggle_stat2==true) { if ((flag_amp2==true)&&(amp2 <= 3)) amp2=amp2+0.25; else flag_amp2=false; if ((flag_amp2==false)&&(amp2 >= 1.25)) amp2=amp2-0.25; else flag_amp2=true; } //--------------------- gtk_widget_queue_draw(widget); return true; } //********************** int main (int argc, char *argv[]) { gtkbuilder *builder; gtkwidget *togglebutton1; gtkwidget *togglebutton2; gtk_init (&argc, &argv); builder = gtk_builder_new (); gtk_builder_add_from_file (builder, "gtk_glade_2drawarea01-r00.glade", null); //carrega informações projeto glade para o gtkbuilder window = gtk_widget(gtk_builder_get_object (builder, "window1")); //retorna o objeto window, para mostrá-lo mais tarde darea1 = gtk_widget(gtk_builder_get_object (builder, "drawingarea1")); //retorna o objeto drawingarea, para mostrá-lo mais tarde darea2 = gtk_widget(gtk_builder_get_object (builder, "drawingarea2")); //retorna o objeto drawingarea, para mostrá-lo mais tarde togglebutton1 = gtk_widget(gtk_builder_get_object (builder, "togglebutton1")); //retorna o objeto togglebutton1, para mostrá-lo mais tarde togglebutton2 = gtk_widget(gtk_builder_get_object (builder, "togglebutton2")); //retorna o objeto togglebutton1, para mostrá-lo mais tarde gtk_window_set_title(gtk_window(window), "gtk 2 viewports drawarea 01"); gtk_builder_connect_signals (builder, null); //conecta todos os eventos dentro projeto glade. g_object_unref (g_object (builder)); //exclui o gtkbuilder, pois não iremos mais usá-lo nesse exemplo. g_signal_connect(g_object(togglebutton1) , "toggled" , g_callback(on_toggled1) , null); g_signal_connect(g_object(togglebutton2) , "toggled" , g_callback(on_toggled2) , null); g_signal_connect(g_object(darea1), "expose-event", g_callback(draw_darea1), null); g_signal_connect(g_object(darea2), "expose-event", g_callback(draw_darea2), null); g_signal_connect_swapped(g_object(window) , "destroy", g_callback(gtk_main_quit) , g_object(window)); g_timeout_add_full(g_priority_default_idle,250,(gsourcefunc)invalidate_drawing1,(gpointer)darea1,null); // variação atualizada da linha acima :-) g_timeout_add_full(g_priority_default_idle,250,(gsourcefunc)invalidate_drawing2,(gpointer)darea2,null); // variação atualizada da linha acima :-) gtk_widget_show_all(window); //mostra janela com seus objetos gtk_main (); return 0; }
and final image.
don't use gdk_window_invalidate_rect()
. use gtk_widget_queue_draw()
or gtk_widget_queue_draw_area()
.
Comments
Post a Comment