RE: How to get Position of GtkTreeIter?



On Tue, 2003-08-19 at 13:27, martyn 2 russell bt com wrote:
 I'm searchig for a function like "gtk_list_view_get_position()"
 in cooperation with gtk tree selection mode (value that we'll
 get by calling gtk_tree_view_get_selection(); ). Is anybody
 here who knows about such possibility?

If you want to know the index only to lookup your object in an
array,
then i suggest to simply add an additional data field of to your
ListStore (just increase the first argument of 
gtk_list_store_new() and
add a G_TYPE_POINTER).
When adding new rows you also need to pass the pointer to your
object:
gtk_list_store_set(model, &iter, [<some_fields>],
                   x, &your_array[position]);


The problem with using this, is that if the item position changes (say
the
one above is removed) then all below it would need updating in the
store/model.  This is HIGHLY inefficient and if there is a lot of data
in
the store/model, then you descrease the speed at which you can do
operations
unnecessarily (note: you need a LOT of data for this to be the case).

Actually you should store array[position] (which is a pointer to your
object) instead of a pointer to array, my fault. In this case my
solution is very efficient. More detailed:

Basically there are two problems:
1) you have an object and want to find it in your ListStore (to
remove/modify it)
2) you have a ListStore entry (GtkTreeIter) and want to access the
according object

Usually you have both...so here are my solutions:

1) Add a GtkTreeIter to your object (which usually is a struct).
Whenever you create a new object, call the gui function that adds this
object to your ListStore by using the GtkTreeIter in your object (that
simply means: you store the ListStore position directly in your object).
The good thing about a ListStore/TreeStore is, that this GtkTreeIter
always represents the correct entry (unless you remove it) even if you
visually reorder the items. [Info: ListStore and TreeStore both
implement GtkTreeModel. There could be other implementations of
GtkTreeModel that have GtkTreeIter's that become invalid if you resort
the items. (gtk_tree_model_get_flags() & GTK_TREE_MODEL_ITERS_PERSIST)
tells you what's the case].

2) Add a G_TYPE_POINTER to your ListStore that points to your object
(not the array position that also holds this pointer). Whenever you
remove an object, call a gui function that removes your item from your
ListStore.

Code example (using GList* instead of array):

typedef struct {
  GtkTreeIter* iter;
  int counter;
  /*..more object data..*/
} object_t;

static GtkListStore* ListStore = NULL;
static GList* AllObjects = NULL;

void create_gui() {
  /* ... */
  ListStore = gtk_list_store_new(2,
                                 0, G_TYPE_POINTER,
                                 1, G_TYPE_INT);
  /* ... */
}

void create_new_object() {
  object_t* object = g_malloc(sizeof(*object));
  
  object->counter = 0;
  object->iter = NULL;
  AllObjects = g_list_append(AllObjects, object);
  show_object(object);
}

void show_object(object_t* object) {
  GtkTreeIter* iter;

  if (!object->iter) {
    /* this object is not show yet, append it to your list */
    object->iter = iter = g_malloc(sizeof(*iter));
    gtk_list_store_append(ListStore, iter);
  } else {
    /* this object is alreay show, simply update it */
    iter = object->iter;
  }
  gtk_list_store_set(ListStore, iter,
                     0, object,
                     1, object->counter,
                     -1);
}

void remove_object(object_t* object) {
  AllObjects = g_list_remove(AllObjects, object);
  hide_object(object);
  g_free(object);
}

void hide_object(object_t* object) {
  if (object->iter) {
    gtk_list_store_remove(ListStore, object->iter);
    g_free(object->iter);
    object->iter = NULL;
  } else {
    /* object is not shown, do nothing */
  }
}

If you catch events like "changed", simply iterate through the
selection, get the object pointer (gtk_tree_model_get()) and call any
function, maybe:

void object_increase_counter(object_t* object) {
  object->counter++;
  show_object(object);  /* update the view */
}

Note: this all is of complexity O(1), so it is very fast.....no need to
iterate in your array, no need to iterate in your ListStore.


Markus.






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