GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Jul 25, 2014 6:15 pm

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Graphic extension of GtkTreeView, need help
PostPosted: Tue Sep 04, 2012 12:41 pm 
Offline
Familiar Face

Joined: Thu Apr 12, 2012 10:34 am
Posts: 8
Hello everyone, this is the first time I've worked directly with the graphical GTK, 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 container) 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 attachment) or as you can see, the graphics area of the parent class is inscribed in a rounded edge like the cards GtkNotebook.
Attachment:
File comment: Final release how I would like the widget to appear graphically (ps: even the buttons are only a stub)
GtkExtendTreeView.png
GtkExtendTreeView.png [ 26.52 KiB | Viewed 2017 times ]

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! :)

PS: Both the name of the widget that the buttons on the toolbar are currently stubs.

gtkextendtreeview.h
Code:
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* [...]
*/

#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
Code:
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* [...]
*/

#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);
}


main.c
Code:
#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;
}


Attachments:
File comment: This package contains the code that you can download to make your own implementation.
gtkextendtreeview.zip [4.41 KiB]
Downloaded 177 times
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group