Re: what's the best way to handle variables and objects?

2006-03-17 Thread Andreas Stricker

John (J5) Palmieri wrote:

Yes.  It depends on your application.  Some people will subclass a
GObject and add the window object plus all of the other widgets as
aggregates.  If you are feeling more daring you can subclass your main
window where your app class would inherit from GtkWindow.  However if
you do not want to get into the intricacies of GObject inheritance
simply creating a struct would be fine:


I agree.

Usually it don't make sense to create a whole GObject descendant just
to pass some data. On the other hand it really make sense if we want
to use OOP/GObject mechanisms like subclassing, (virtual) methods and
reference counting. It depends on the complexity of the application.

Cheers,
Andy


___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


what's the best way to handle variables and objects?

2006-03-15 Thread Andreas Kotowicz
I'm looking for a clean solution on passing variables and objects from
gtk calls to callback functions and back.

I call for instance

g_signal_connect(G_OBJECT(button), clicked,
G_CALLBACK(clear_timer_cb), progressbar);

and pass with it the object I'm working with. (progressbar has been
definded before: GtkWidget *progressbar = gtk_progress_bar_new(); )

now in clear_timer_cb I can modify the object:

void clear_timer_cb(GtkObject *window, void *data)
{
  GtkWidget *progressbar = data;
  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), 0);
}


but what should I do if I want to modify any other variables in this
function as well? let's say that in the part where I created the
g_signal_connect there are also some variables A and B which might be of
interest in clear_timer_cb. 

should I create a struct

struct data {
  gdouble *A;
  gdouble *B;
  GtkWidget *progressbar
};

and then initiate it and pass it always on?

what's the best way in dealing with this?

cheers,
Andreas

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: what's the best way to handle variables and objects?

2006-03-15 Thread Tristan Van Berkom

Andreas Kotowicz wrote:
[...]

but what should I do if I want to modify any other variables in this
function as well? let's say that in the part where I created the
g_signal_connect there are also some variables A and B which might be of
interest in clear_timer_cb. 


should I create a struct

struct data {
  gdouble *A;
  gdouble *B;
  GtkWidget *progressbar
};

and then initiate it and pass it always on?

what's the best way in dealing with this?


This is a typical, popular and clean way to pass mulitple
variables/addresses to a callback, yes.

If you allocate a struct for that a g_signal_connect time...
you might want to consider useing something like
g_object_weak_ref() to free your struct when the button you
connected to is finalized (maybe there is a g_signal_connect_data_full
variation that does this for you ?).


Cheers,
 -Tristan

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: what's the best way to handle variables and objects?

2006-03-15 Thread Andreas Kotowicz
On Wed, 2006-03-15 at 13:44 -0500, John (J5) Palmieri wrote:
 You can create a generic struct but more often than not there is an
 application object or struct that the application developer creates
 which holds all the public variables he or she would care about which is
 passed as userdata to things like g_signal_connect.  

sorry, but I don't exactly understand what you mean. Could you maybe
give me an example of how the application object and the interaction
would look like? would this application object also hold all the labels
and entry fields which might change?

but maybe I do understand you. what I use here is following:

main.c:

#include gtk/gtk.h
#include interface.h
int main (int argc, char *argv[])
{

  GtkWidget *window1;

  gtk_init(argc, argv);

  window1 = create_window1 ();
  gtk_widget_show_all(window1);

  gtk_main();
  return 0;
}


interface.h:
#include gtk/gtk.h

GtkWidget* create_window1 (void);

interface.c:

#include callbacks.h
#include interface.h

GtkWidget*
create_window1 (void)
{
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *progressbar;
  GtkWidget *button_start;
  GtkWidget *spin_sec;
  GtkWidget *spin_min;

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), Window);
  g_signal_connect(G_OBJECT(window), destroy, 
  G_CALLBACK(destroy_window_cb), NULL);
  
  /* vbox for whole window */
  vbox = gtk_vbox_new(FALSE, 6);
  gtk_container_add(GTK_CONTAINER(window), vbox);

  /* put progressbar at the top of the window */
  progressbar = gtk_progress_bar_new();
  gtk_box_pack_start(GTK_BOX(vbox), progressbar, TRUE, TRUE, 12);

  /* entry field for number of seconds */
  spin_sec = gtk_spin_button_new_with_range(0, 59, 1);  
  gtk_box_pack_start(GTK_BOX(vbox), spin_sec, FALSE, FALSE, 0);  

  
  button_start = gtk_button_new_with_mnemonic(_Start);
  gtk_box_pack_start(GTK_BOX(vbox), button_start, FALSE, FALSE, 0);

  g_signal_connect(GTK_BUTTON(button_start), clicked, 
  G_CALLBACK(start_timer_cb), progressbar);
  
  return window;
}

is this what you mean by application object? here comes my problem now:
g_signal_connect on button_start only passes on the progressbar object
to start_timer_cb(). but I also want to have the user input from
spin_sec in this function. so how can I get a grip on both of these (or
even more) variables in start_timer_cb() ?

callbacks.c:

void start_timer_cb(GtkObject *window, void *data)
{
  GtkWidget *progressbar = data;
  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), 
  gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(progressbar))+0.1);
}


 BTW GtkObject is usually not used directly anymore.  Usually objects are
 passed to callbacks as GObject, GtkWidget or their actual class (in your
 case GtkButton) as they are the most useful casts. 

thanks, good to know. 


andreas

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: what's the best way to handle variables and objects?

2006-03-15 Thread Wallace Owen
My reply's in the body (I ain't no top-poster!):

On Wed, 2006-03-15 at 22:57 +0100, Andreas Kotowicz wrote:
 On Wed, 2006-03-15 at 13:44 -0500, John (J5) Palmieri wrote:
  You can create a generic struct but more often than not there is an
  application object or struct that the application developer creates
  which holds all the public variables he or she would care about which is
  passed as userdata to things like g_signal_connect.  
 
 sorry, but I don't exactly understand what you mean. Could you maybe
 give me an example of how the application object and the interaction
 would look like? would this application object also hold all the labels
 and entry fields which might change?
 
 but maybe I do understand you. what I use here is following:
 
 main.c:
 
 #include gtk/gtk.h
 #include interface.h
 int main (int argc, char *argv[])
 {
 
   GtkWidget *window1;
 
   gtk_init(argc, argv);
 
   window1 = create_window1 ();
   gtk_widget_show_all(window1);
 
   gtk_main();
   return 0;
 }
 
 
 interface.h:
 #include gtk/gtk.h
 
 GtkWidget* create_window1 (void);
 
 interface.c:
 
 #include callbacks.h
 #include interface.h
 
 GtkWidget*
 create_window1 (void)
 {
   GtkWidget *window;
   GtkWidget *vbox;
   GtkWidget *progressbar;
   GtkWidget *button_start;
   GtkWidget *spin_sec;
   GtkWidget *spin_min;
 
   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(window), Window);
   g_signal_connect(G_OBJECT(window), destroy, 
   G_CALLBACK(destroy_window_cb), NULL);
   
   /* vbox for whole window */
   vbox = gtk_vbox_new(FALSE, 6);
   gtk_container_add(GTK_CONTAINER(window), vbox);
 
   /* put progressbar at the top of the window */
   progressbar = gtk_progress_bar_new();
   gtk_box_pack_start(GTK_BOX(vbox), progressbar, TRUE, TRUE, 12);
 
   /* entry field for number of seconds */
   spin_sec = gtk_spin_button_new_with_range(0, 59, 1);  
   gtk_box_pack_start(GTK_BOX(vbox), spin_sec, FALSE, FALSE, 0);  
 
   
   button_start = gtk_button_new_with_mnemonic(_Start);
   gtk_box_pack_start(GTK_BOX(vbox), button_start, FALSE, FALSE, 0);
 
   g_signal_connect(GTK_BUTTON(button_start), clicked, 
   G_CALLBACK(start_timer_cb), progressbar);
   
   return window;
 }
 
 is this what you mean by application object? here comes my problem now:
 g_signal_connect on button_start only passes on the progressbar object
 to start_timer_cb(). but I also want to have the user input from
 spin_sec in this function. so how can I get a grip on both of these (or
 even more) variables in start_timer_cb() ?

Define a struct that has as it's member fields all the values you want
accessible to the callback, including the progressbar, spin_sec, etc:

struct MyUserData
{
GtkWidget *progress_bar;
GtkWidget *spin_sec;
};

Allocate one of these on the heap (note: I'm using C++, so new's what I
use for this):

MyUserData *myData = new MyUserData;

myData-progress_bar = progressbar;
myData-spin_sec = spin_sec;

Pass the allocated storage as the last parm to g_signal_connect.

g_signal_connect(GTK_BUTTON(button_start), clicked, G_CALLBACK
(start_timer_cb), myData);

In the callback, cast the pointer to the user-supplied parm to the type
of your struct and access it's members as needed:

void start_timer_cb(GtkObject *window, void *data)
{
MyUserData *myData = (MyUserData*)data;

// the progressbar is myData-progress_bar, etc.
// ...
}

Remember to return the storage to the heap when you're done using it.


  // Wally

-- 
Your eyes are weary from staring at the CRT.  You feel sleepy.  Notice
how restful it is to watch the cursor blink.  Close your eyes.  The   
opinions stated above are yours.  You cannot imagine why you ever felt
otherwise.

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: what's the best way to handle variables and objects?

2006-03-15 Thread John (J5) Palmieri
On Wed, 2006-03-15 at 22:57 +0100, Andreas Kotowicz wrote:
 On Wed, 2006-03-15 at 13:44 -0500, John (J5) Palmieri wrote:
  You can create a generic struct but more often than not there is an
  application object or struct that the application developer creates
  which holds all the public variables he or she would care about which is
  passed as userdata to things like g_signal_connect.  
 
 sorry, but I don't exactly understand what you mean. Could you maybe
 give me an example of how the application object and the interaction
 would look like? would this application object also hold all the labels
 and entry fields which might change?

Yes.  It depends on your application.  Some people will subclass a
GObject and add the window object plus all of the other widgets as
aggregates.  If you are feeling more daring you can subclass your main
window where your app class would inherit from GtkWindow.  However if
you do not want to get into the intricacies of GObject inheritance
simply creating a struct would be fine:

typedef struct _FooApp
{
  gchar *app_name;

  GtkWidget *main_window;
  GtkWidget *progress_bar;
  GtkWidget *button_start;
 
} FooApp;

FooApp *
create_app (void)
{
  FooApp *app;

  app = g_new0 (FooApp, 1);

  app_name = g_strdup (My Foo App);

  app-main_window = ...
  app-progress_bar = ...

  gtk_container_add (GTK_CONTAINER (app-main_window),
app-progress_bar);

  .
  .
  .

  g_signal_connect(app-button_start, clicked,
G_CALLBACK(start_timer_cb), app);

  gtk_widget_show_all (app-main_window);

  return app;
}

 but maybe I do understand you. what I use here is following:
 
 main.c:
 
 #include gtk/gtk.h
 #include interface.h
 int main (int argc, char *argv[])
 {
 
   GtkWidget *window1;
 
   gtk_init(argc, argv);
 
   window1 = create_window1 ();
   gtk_widget_show_all(window1);
 
   gtk_main();
   return 0;
 }
 
 
 interface.h:
 #include gtk/gtk.h
 
 GtkWidget* create_window1 (void);
 
 interface.c:
 
 #include callbacks.h
 #include interface.h
 
 GtkWidget*
 create_window1 (void)
 {
   GtkWidget *window;
   GtkWidget *vbox;
   GtkWidget *progressbar;
   GtkWidget *button_start;
   GtkWidget *spin_sec;
   GtkWidget *spin_min;
 
   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(window), Window);
   g_signal_connect(G_OBJECT(window), destroy, 
   G_CALLBACK(destroy_window_cb), NULL);
   
   /* vbox for whole window */
   vbox = gtk_vbox_new(FALSE, 6);
   gtk_container_add(GTK_CONTAINER(window), vbox);
 
   /* put progressbar at the top of the window */
   progressbar = gtk_progress_bar_new();
   gtk_box_pack_start(GTK_BOX(vbox), progressbar, TRUE, TRUE, 12);
 
   /* entry field for number of seconds */
   spin_sec = gtk_spin_button_new_with_range(0, 59, 1);  
   gtk_box_pack_start(GTK_BOX(vbox), spin_sec, FALSE, FALSE, 0);  
 
   
   button_start = gtk_button_new_with_mnemonic(_Start);
   gtk_box_pack_start(GTK_BOX(vbox), button_start, FALSE, FALSE, 0);
 
   g_signal_connect(GTK_BUTTON(button_start), clicked, 
   G_CALLBACK(start_timer_cb), progressbar);
   
   return window;
 }
 
 is this what you mean by application object? here comes my problem now:
 g_signal_connect on button_start only passes on the progressbar object
 to start_timer_cb(). but I also want to have the user input from
 spin_sec in this function. so how can I get a grip on both of these (or
 even more) variables in start_timer_cb() ?
 
 callbacks.c:
 
 void start_timer_cb(GtkObject *window, void *data)
 {
   GtkWidget *progressbar = data;
   gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), 
   gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(progressbar))+0.1);
 }
 
 
  BTW GtkObject is usually not used directly anymore.  Usually objects are
  passed to callbacks as GObject, GtkWidget or their actual class (in your
  case GtkButton) as they are the most useful casts. 
 
 thanks, good to know. 
 
 
 andreas

-- 
John (J5) Palmieri [EMAIL PROTECTED]

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list


Re: what's the best way to handle variables and objects?

2006-03-15 Thread Tristan Van Berkom

Andreas Kotowicz wrote:


Hi Tristan,


[...]


do you know maybe a relatively simple gnome app which uses this concept,
so I could have a look at the source code and see how all the
interaction works?



Well, how about I just type away from memory... after writing that
I notice that its probably not something one would do... but it should
give you some good ideas ;-)

Cheers,
   -Tristan


typedef struct {
   GtkWidget *prog;
   gint a;
   gchar *str;
} MyStruct;

/*
.
.
.
*/
static void
my_destroy (MyStruct *my)
{
   if (my-str) g_free (my-str);
   g_free (my);
}

/*
.
.
.
*/
MyStruct  * my = g_new0 (MyStruct, 1);

http://developer.gnome.org/doc/API/2.0/glib/glib-Datasets.html#GDestroyNotifyg_signal_connect_data 
(G_OBJECT(adj), value-changed,

   G_CALLBACK (progress_callback), my,
   (GDestroyNotify)my_destroy, 0);


/*
.
.
.
*/
static void
progress_callback (GtkWidget *button, MyStruct *my)
{
   /* do something rediculous like set the progress bar percentage
* to match the adjustment.
*/
}

___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list