[gnome-love] Graphic extension of GtkTreeView, need help



Hello everyone, this is my first post on gnome-love, I hope you can help me.

My idea is to create a class that extends GtkTreeView.
This class must have a toolbar (preferably implemented with GtkToolbar, but if it is too difficult even with a simple GtkBox) that will provide some additional functionality.

I would also like this toolbar, similar to the way as the labels GtkNotebook, is adjustable by means of a method "_set_toolbar_position ([new Widget] widget, GtkPositionType pos);"

Preferably I would like the result to be like this (see image link first attachment) or as you can see, the graphics area of the parent class is inscribed in a rounded edge like the cards GtkNotebook .

For anyone who can help me I will be happy to share the full merits of the implementation of this class. Below place the code in the first draft that I got.

Thank you all in advance! :)

main.c
--------------------------------------------------------------------------------------------- 
#include <gtk/gtk.h>
#include "gtkextendtreeview.h"

static GtkWidget* BuildExtendTreeView(){
  /* Creates an instance of the new widget */
  GtkExtendTreeView* const extend_tree = GTK_EXTEND_TREE_VIEW(gtk_extend_tree_view_new());
  /* Create a sample tree model */
  GtkListStore* const store = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_STRING);

  /* Set in the template two columns of example */
  GtkTreeView* const table = GTK_TREE_VIEW(extend_tree);
  gtk_tree_view_set_model(table,GTK_TREE_MODEL(store));
  /* Create a new GtkCellRendererText, add it to the tree view column */
  GtkCellRenderer* const renderer = gtk_cell_renderer_text_new();
  /* Create all the tree view columns needed to build the tree view model, and append them to the tree view */
  GtkTreeViewColumn *column = NULL;
  column = gtk_tree_view_column_new_with_attributes("First Column",renderer,"text",0,NULL);
  gtk_tree_view_append_column(table,column);
  column = gtk_tree_view_column_new_with_attributes("Second Column",renderer,"text",1,NULL);
  gtk_tree_view_append_column(table,column);

  /* Return the new widget */
  return GTK_WIDGET(extend_tree);
}

int main (int argc, char *argv[])
{
  GtkWidget *win = NULL;

  /* Initialize GTK+ */
  g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
  gtk_init (&argc, &argv);
  g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);

  /* Create the main window */
  win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_set_border_width (GTK_CONTAINER (win), 8);
  gtk_window_set_title (GTK_WINDOW (win), "Example to Extend Tree View");
  gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
  g_signal_connect (win, "destroy", gtk_main_quit, NULL);
  gtk_widget_set_size_request(GTK_WIDGET(win), 600,300);
  gtk_widget_realize (win);

  /* Creates an instance of the new widget and attach it to the window */
  gtk_container_add (GTK_CONTAINER (win), BuildExtendTreeView());

  /* Enter the main loop */
  gtk_widget_show_all (win);
  gtk_main ();
  return 0;
}
 
gtkextendtreeview.h 
------------------------------------------------------------------------------------- 
/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#ifndef __GTK_EXTEND_TREE_VIEW_H__
#define __GTK_EXTEND_TREE_VIEW_H__

#include <glib.h>
#include <glib-object.h>
#include <gtk/gtktreeview.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkstock.h>
#include <gtk/gtkbutton.h>

G_BEGIN_DECLS

#define GTK_TYPE_EXTEND_TREE_VIEW             (gtk_extend_tree_view_get_type())
#define GTK_EXTEND_TREE_VIEW(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_EXTEND_TREE_VIEW, GtkExtendTreeView))
#define GTK_EXTEND_TREE_VIEW_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_EXTEND_TREE_VIEW, GtkExtendTreeViewClass))
#define GTK_IS_EXTEND_TREE_VIEW(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_EXTEND_TREE_VIEW))
#define GTK_IS_EXTEND_TREE_VIEW_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_EXTEND_TREE_VIEW))

typedef struct _GtkExtendTreeView       GtkExtendTreeView;
typedef struct _GtkExtendTreeViewClass  GtkExtendTreeViewClass;

struct _GtkExtendTreeView
{
  GtkTreeView parent;
  GtkWidget* toolbar;
};

struct _GtkExtendTreeViewClass
{
  GtkTreeViewClass parent_class;
};

/* Used to implement object-GTK, provides the type of the created widget */
GType           gtk_extend_tree_view_get_type(void) G_GNUC_CONST;
/* Creates a new GtkTableGrid widget */
GtkWidget*      gtk_extend_tree_view_new(void);

G_END_DECLS

#endif /* __GTK_EXTEND_TREE_VIEW_H__ */
 
gtkextendtreeview.c 
---------------------------------------------------------------------------------------
/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#include "gtkextendtreeview.h"
/* Static pointer to parent class of GtkExtendTreeView */
static GtkTreeViewClass* parent_class;
static void gtk_extend_tree_view_set_property(GObject* object, guint prop_id, const GValue *value, GParamSpec* pspec){
  switch(prop_id){
    //TODO: Implements setting properties
    break;
    default:    /* invalid property */
      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
  }
}
static void gtk_extend_tree_view_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec){
  switch(prop_id){
    //TODO: Implements getting properties
    default:    /* invalid property */
      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
  }
}
static void gtk_extend_tree_view_realize(GtkWidget* const widget){
  /* Invokes the method realize the parent class */
  GTK_WIDGET_CLASS(parent_class)->realize(widget);
  /* Retrieve a reference to the toolbar */
  GtkWidget* const toolbar = GTK_EXTEND_TREE_VIEW(widget)->toolbar;
  if(gtk_widget_get_parent(toolbar) != widget){
    gtk_widget_freeze_child_notify (toolbar);
    gtk_widget_set_parent (toolbar, widget);
    gtk_widget_thaw_child_notify (toolbar);
  }
}
static void gtk_extend_tree_view_show(GtkWidget* const widget){
  GTK_WIDGET_CLASS(parent_class)->show(widget);
  gtk_widget_show(GTK_EXTEND_TREE_VIEW(widget)->toolbar);
}
static void gtk_extend_tree_view_map(GtkWidget* const widget){
  GTK_WIDGET_CLASS(parent_class)->map(widget);
  gtk_widget_map(GTK_EXTEND_TREE_VIEW(widget)->toolbar);
}
static void gtk_extend_tree_view_size_request(GtkWidget* const widget, GtkRequisition* const requisition){
  /* Invokes the method size request the parent class */
  GTK_WIDGET_CLASS(parent_class)->size_request(widget,requisition);
  /* Retrieve a reference to the toolbar */
  GtkWidget* const toolbar = GTK_EXTEND_TREE_VIEW(widget)->toolbar;
  /* Check that the toolbar is visible */
  if(gtk_widget_get_visible(toolbar)){
    /* Declare a structure to retrieve the required size from the toolbar */
    GtkRequisition toolbar_requisition;
    /* Recovery required size of the toolbar */
    gtk_widget_size_request(toolbar,&toolbar_requisition);
    /* Add the required height from the tree view, the request from the toolbar */
    requisition->height += toolbar_requisition.height;
    /* If the toolbar requires a width greater than that of the tree view, the value of required width is reimposed */
    if(toolbar_requisition.width>requisition->width)
      requisition->width = toolbar_requisition.width;
  }
  /* Are added to the size to be requested also those relating to the thickness of the border */
  requisition->width += GTK_CONTAINER(widget)->border_width * 2;
  requisition->height += GTK_CONTAINER(widget)->border_width * 2;
}
static void gtk_extend_tree_view_size_allocate(GtkWidget* const widget, GtkAllocation* const allocation){
  /* Retrieve a reference to the toolbar */
  GtkWidget* const toolbar = GTK_EXTEND_TREE_VIEW(widget)->toolbar;
  /* Invokes the method size allocation the parent class */
  GTK_WIDGET_CLASS(parent_class)->size_allocate(widget,allocation);
  /* Check that the toolbar is visible */
  if(gtk_widget_get_visible(toolbar)){
    /* Declares two structures to represent the size and location of the toolbar */
    GtkRequisition toolbar_requisition;
    GtkAllocation toolbar_allocation;
    /* Retrieve the size of the tree view border */
    const guint16 border = GTK_CONTAINER(widget)->border_width;
    /* Sets the toolbar width, if it's greater than zero and equal to the difference between the tree view width and twice of the tree view border */
    toolbar_allocation.width = (gint) allocation->width - (gint) border * 2;
    if(toolbar_allocation.width<1)toolbar_allocation.width=1;
    /* Set the horizontal distance of the toolbar */
    toolbar_allocation.x = allocation->x + border;
    /* Recovery required size of the toolbar */
    gtk_widget_get_child_requisition(toolbar, &toolbar_requisition);
    /* Imposed on the value of the height of the toolbar, equal to the height required if this is greater than zero */
    toolbar_allocation.height = toolbar_requisition.height<1?1:toolbar_requisition.height;
    /* Set the vertical distance of the toolbar */
    toolbar_allocation.y = allocation->y + allocation->height - border + toolbar_requisition.height;
    /* Allocate the new size of the toolbar */
    gtk_widget_size_allocate (toolbar, &toolbar_allocation);
  }
}
static void gtk_extend_tree_view_forall(GtkContainer* const container, const gboolean include_internals, GtkCallback callback, gpointer const callback_data){
  /* Invokes the method forall of the parent class */
  GTK_CONTAINER_CLASS(parent_class)->forall(container,include_internals,callback,callback_data);
  /* Check if the callback should be applied also to the internal child */
  if(include_internals){
    /* Invokes the callback for the toolbar of the tree view */
    (*callback) (GTK_EXTEND_TREE_VIEW(container)->toolbar, callback_data);
  }
}
/* Internal Widget Implementation ::: Initializes the widget class */
static void gtk_extend_tree_view_class_init(GtkExtendTreeViewClass* const klass){
  /* GObject signals */
  GObjectClass* const o_klass = G_OBJECT_CLASS(klass);
  o_klass->set_property = gtk_extend_tree_view_set_property;
  o_klass->get_property = gtk_extend_tree_view_get_property;
  GtkContainerClass* const c_klass = GTK_CONTAINER_CLASS(klass);
  c_klass->forall = gtk_extend_tree_view_forall;
  /* GtkWidget signals */
  GtkWidgetClass* const w_klass = GTK_WIDGET_CLASS(klass);
  w_klass->realize = gtk_extend_tree_view_realize;
  w_klass->show = gtk_extend_tree_view_show;
  w_klass->map = gtk_extend_tree_view_map;
  w_klass->size_request = gtk_extend_tree_view_size_request;
  w_klass->size_allocate = gtk_extend_tree_view_size_allocate;
  /* Store in global variable the reference to object class of the widget */
  parent_class = g_type_class_peek_parent(klass);
  /* GtkExtendTreeView Signals */
  //TODO: Install signals
  /* GtkExtendTreeView Properties */
  //TODO: Install properties
}
static void gtk_extend_tree_view_init(GtkExtendTreeView* const widget){
  //FIXME: This button is only an example widget that will later be replaced by a
  //       toolbar with various buttons for various functions of the class.
  widget->toolbar = gtk_button_new_from_stock(GTK_STOCK_ABOUT);
}
/* Internal Widget Implementation ::: Return the GtkExtendTreeView type */
GType gtk_extend_tree_view_get_type(void){
  static GType gtk_extend_tree_view_type = 0;
  if(!gtk_extend_tree_view_type){
    const GTypeInfo gtk_extend_tree_view_info = {
      sizeof (GtkExtendTreeViewClass),
      NULL, /* base_init */
      NULL, /* base_finalize */
      (GClassInitFunc) gtk_extend_tree_view_class_init,
      NULL, /* class_finalize */
      NULL, /* class_data */
      sizeof (GtkExtendTreeView),
      0,
      (GInstanceInitFunc) gtk_extend_tree_view_init,
    };
    gtk_extend_tree_view_type = g_type_register_static (GTK_TYPE_TREE_VIEW, "GtkExtendTreeView", &gtk_extend_tree_view_info, 0);
  }
  return gtk_extend_tree_view_type;
}
/* Creates a new GtkExtendTreeView widget */
GtkWidget* gtk_extend_tree_view_new(){
  return g_object_new(GTK_TYPE_EXTEND_TREE_VIEW,NULL);
}
 

Attachment: GtkExtendTreeView.png
Description: PNG image

Attachment: gtkextendtreeview.zip
Description: Zip archive



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