Re: Simple boxing



On Wed, 2004-11-03 at 13:26, Sven Neumann wrote:
> Hi,
> 
> Gabriel de Perthuis <Gabriel de-Perthuis laPoste net> writes:
> 
> > Le mercredi 03 novembre 2004 à 08:22 +0100, David Necas (Yeti) a écrit :
> >> You can use a pointer -- with G_TYPE_POINTER column type.
> >> In fact I often use G_TYPE_POINTER even for objects because
> >> I don't like unreferencing them every time I fetch them from
> >> model.
> > Thanks, it is more simple than I thought!
> >
> > It is certainly worth mentioning this in the gobject tutorial, in
> > chapter 2 or maybe in chapter 4.
> 
> It isn't really recommended to treat objects like this. Of course if
> you know what you are doing, it will work. But I wouldn't suggest to
> do it this way as it may very well fall onto your feet one day.

I personally don't like the idea if having all my data only in the
List/TreeStore because the my program then isnt separated from the GUI
anymore.
My approach is to have an object (struct) with all the internal data,
and the TreeModel holds a pointer to it in column 0.
Whenever my program likes to show the object, ui_object_new() is called:

  static void ui_object_update(object) {
    [set all columns of model using object as data source]
  }
  static void ui_object_hide(object) {
    ui_object_unobserve(object, ui_object_update, NULL);
    [remove from tree model]
  }
  static void ui_object_show(object) {
    [add to tree model]
    ui_object_update(object);
  }
  void ui_object_new(object) {
    object_at_destruction(object, ui_object_hide, NULL);
    object_observe(object, ui_object_update, NULL);
    ui_object_show(object);
  }

All my objects are derived from a self-made class object_t.

Whenever a users accesses a line in the model, the object pointer is
retrieved (column 0) and a function object_do_something(object) is
called. So i use the column>0 of the model for display only.

This way i can easily run my program as a deamon (by making
ui_object_new() an empty function, since its the only GUI function
called by the core program), or i can switch to another GUI toolkit.

Here is a small example:

static GtkListStore* ui_buddy_get_store(int which) {
  static GtkListStore* BuddyStore = NULL;

  if (!BuddyStore)
    BuddyStore = gtk_list_store_new(2, G_TYPE_POINTER, G_TYPE_STRING);
  return BuddyStore;
}

static void ui_buddy_hide(buddy_t* buddy) {
  GtkTreeIter* iter = OBJ(buddy)->gui_data;
  if (!iter) return;

  gtk_list_store_remove(ui_buddy_get_store(), iter);
  OBJ(buddy)->gui_data = NULL;
  g_free(iter);
}

static void ui_buddy_update(buddy_t* buddy) {
  GtkTreeIter* iter = OBJ(buddy)->gui_data;

  if (!iter) return;
  gtk_list_store_set(ui_buddy_get_store(), iter,
                     0, buddy,
                     1, buddy->nick,
                     -1);
}

static void ui_buddy_show(buddy_t* buddy) {
  GtkTreeIter* iter;

  if (OBJ(buddy)->gui_data) return;
  OBJ(buddy)->gui_data = iter = g_malloc(sizeof(*iter));
  gtk_list_store_append(ui_buddy_get_store(), iter);
  
  ui_buddy_update(buddy);
}

void ui_buddy_new(buddy_t* buddy) {
  object_at_destruction(OBJ(buddy), (ObjectFunc)ui_buddy_hide, NULL);
  object_observe(OBJ(buddy), (ObjectFunc)ui_buddy_update, NULL);
  ui_buddy_show(buddy);
}

Markus.




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