On Wed, 2006-01-11 at 11:22 +0100, Philip Van Hoof wrote:
> On Tue, 2006-01-10 at 12:43 +0100, Philip Van Hoof wrote:

> Somebody cleaned up the page. I added some more documentation and
> explanation. For example about proxy classes and custom models.
> 
> I also created a sample here: http://pastebin.com/500098

I updated the same, it now also actually works and has a IMsgHeader,
MsgHeader and MsgHeaderPrx just like how I explained it in the "Proxy"
solution section.

I attached it.


-- 
Philip Van Hoof, software developer at x-tend 
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
work: vanhoof at x-tend dot be 
http://www.pvanhoof.be - http://www.x-tend.be
#include <gtk/gtk.h>

static int ELEMENT_COUNT = 10000;
static int instantiations = 0;

static GtkWidget *window = NULL;

typedef struct _IMsgHeader IMsgHeader;
typedef struct _MsgHeader MsgHeader;
typedef struct _MsgHeaderPrx MsgHeaderPrx;

struct _IMsgHeader {
   const gchar* (*get_from_func) (IMsgHeader *this);
   const gint   (*get_id_func)   (IMsgHeader *this);

   gint id;
};

struct _MsgHeader {
   IMsgHeader parent;
   gchar *from;
};

struct _MsgHeaderPrx {
   IMsgHeader parent;
   MsgHeader *real;
};


/* IMsgHeader (late binding like) impl */
const gint
imsg_header_get_id (IMsgHeader *this)
{
    return this->get_id_func (this);
}

const gchar* 
imsg_header_get_from (IMsgHeader *this)
{
    return this->get_from_func (this);
}


/* Real subject impl */
MsgHeader* 
msg_header_new (gint id)
{
	MsgHeader *header = g_new0(MsgHeader, 1);

        g_print ("Instantiation for id=%d (%d passed)\n!!",
		 id, instantiations);

	instantiations++;

	header->parent.id = id;
	header->from = g_strdup ("A real IMsgHeader subject!");

	return header;
}


/* Proxy impl */
const gchar*
msg_header_proxy_get_from (IMsgHeader *this_i)
{
   MsgHeaderPrx *this = (MsgHeaderPrx*)this_i;

   if (this->real == NULL)
       this->real = msg_header_new (this->parent.id);

   return this->real->from;
}

const gint
msg_header_proxy_get_id (IMsgHeader *this_i)
{
   MsgHeaderPrx *this = (MsgHeaderPrx*)this_i;

   if (this->real == NULL)
       this->real = msg_header_new (this->parent.id);

   return this->real->parent.id;
}


MsgHeaderPrx*
msg_header_proxy_new (gint id)
{
   MsgHeaderPrx *header = g_new0(MsgHeaderPrx, 1);

   header->parent.id = id;
   header->parent.get_from_func = msg_header_proxy_get_from;
   header->parent.get_id_func = msg_header_proxy_get_id;

   header->real = NULL;

   return header;
}


enum
{
   COLUMN_NUMBER,
   COLUMN_HEADER, 
   NUM_COLUMNS
};


static void
msg_header_treeview_destroy_model_item (gpointer data)
{
        g_print ("Destroy\n");
}

static void
msg_header_treeview_get_model_item (GtkTreeViewColumn *tree_column,
                                   GtkCellRenderer   *cell,
                                   GtkTreeModel      *tree_model,
                                   GtkTreeIter       *iter,
                                   gpointer           data)
{
        gint number;
        IMsgHeader *header;

        /* This function can call the getter on the item in the model.
         * Such an item can be a proxy class (IMsgHeaderPrx), triggering
         * this getter causes an instantiation (or getting it from a
         * factory with a cache) of a real subject (a real MsgHeader).
         *
         * The proxy now reads the value from the real subject and
         * returns it to fullfill the contract of the interface IMsgHeader.
         */

        gtk_tree_model_get (tree_model, iter, COLUMN_HEADER, &header, -1);
        g_print ("from=%s, %d\n", imsg_header_get_from (header), 
			imsg_header_get_id (header));
}

static GtkTreeModel *
create_model (void)
{
  gint i = 0;
  GtkListStore *store;
  GtkTreeIter iter;

  store = gtk_list_store_new (NUM_COLUMNS,
                              G_TYPE_INT,
                              G_TYPE_POINTER);


  for (i = 0; i < ELEMENT_COUNT; i++)
  {

      MsgHeaderPrx *header = msg_header_proxy_new (i);

      gtk_list_store_append (store, &iter);
      gtk_list_store_set (store, &iter,
			  COLUMN_NUMBER, header->parent.id,
                          COLUMN_HEADER, header, -1);
  }

  return GTK_TREE_MODEL (store);
}


static void
add_columns (GtkTreeView *treeview)
{
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;
  GtkTreeModel *model = gtk_tree_view_get_model (treeview);

  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Number",
                                                     renderer,
                                                     "text",
                                                     COLUMN_NUMBER,
                                                     NULL);
  gtk_tree_view_column_set_sort_column_id (column, COLUMN_NUMBER);
  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);

  gtk_tree_view_column_set_fixed_width (column, 200);

  gtk_tree_view_column_set_cell_data_func (column, renderer, 
	msg_header_treeview_get_model_item, NULL,
	msg_header_treeview_destroy_model_item);

  gtk_tree_view_append_column (treeview, column);

}

GtkWidget *
do_list_store (void)
{
  if (!window)
    {
      GtkWidget *vbox;
      GtkWidget *label;
      GtkWidget *sw;
      GtkTreeModel *model;
      GtkWidget *treeview;

      /* create window, etc */
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title (GTK_WINDOW (window), "GtkListStore demo");

      g_signal_connect (window, "destroy",
                        G_CALLBACK (gtk_widget_destroyed), &window);
      gtk_container_set_border_width (GTK_CONTAINER (window), 8);

      vbox = gtk_vbox_new (FALSE, 8);
      gtk_container_add (GTK_CONTAINER (window), vbox);

      label = gtk_label_new ("Bla Bla Bla");
      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);

      sw = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
                                           GTK_SHADOW_ETCHED_IN);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
                                      GTK_POLICY_NEVER,
                                      GTK_POLICY_AUTOMATIC);
      gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);


      g_print ("Create model\n");
      /* create tree model */
      model = create_model ();

      g_print ("Create treeview\n");

      /* create tree view */
      treeview = gtk_tree_view_new_with_model (model);
      gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);

      gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW(treeview), TRUE);

      g_object_unref (model);

      gtk_container_add (GTK_CONTAINER (sw), treeview);

      /* add columns to the tree view */
      add_columns (GTK_TREE_VIEW (treeview));

      /* finish & show */
      gtk_window_set_default_size (GTK_WINDOW (window), 280, 250);
    }

  if (!GTK_WIDGET_VISIBLE (window))
    gtk_widget_show_all (window);
  else
    {
      gtk_widget_destroy (window);
      window = NULL;
    }

  return window;
}

int main (int argc, char **argv)
{
        GtkWindow *win;
        gtk_init (&argc, &argv);

        if (argc > 1)
        {
                ELEMENT_COUNT = atoi (argv[1]);
        }

        win = GTK_WINDOW(do_list_store ());
        gtk_widget_show_all (GTK_WIDGET(win));

        gtk_main();

}
_______________________________________________
maemo-developers mailing list
maemo-developers@maemo.org
https://maemo.org/mailman/listinfo/maemo-developers

Reply via email to