gtkmm: |
The C++ Interface to Gtk+ |
TreeView |
The Gtk::TreeView widget
stores the data that you want to display in a
Gtk::TreeModel
or Gtk::ListModel
.
examplewindow.h:
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H
#include <glibmm.h>
#include <gdkmm.h>
#include <gtkmm.h>
class ExampleWindow : public Gtk::Window
{
public:
ExampleWindow();
virtual ~ExampleWindow();
private:
void add_entry( const int id, const int dice_id, const char* filename, const char* name );
// Signal handlers
virtual void on_button_quit();
virtual void on_button_delete();
virtual void on_selection_changed();
// Types and classes
typedef Glib::RefPtr<Gdk::Pixbuf> PixbufPtr;
class ModelColumns : public Gtk::TreeModel::ColumnRecord
{
public:
ModelColumns()
{ add(m_col_id); add(m_dice_id); add(m_pixbuf); add(m_col_name); }
Gtk::TreeModelColumn<int> m_col_id;
Gtk::TreeModelColumn<int> m_dice_id;
Gtk::TreeModelColumn<PixbufPtr> m_pixbuf;
Gtk::TreeModelColumn<Glib::ustring> m_col_name;
};
// Private members
ModelColumns m_Columns;
Gtk::VBox m_VBox;
Gtk::ScrolledWindow m_ScrolledWindow;
Gtk::TreeView m_TreeView;
Glib::RefPtr<Gtk::ListStore> m_refTreeModel;
Glib::RefPtr<Gtk::TreeSelection> m_refTreeSelection;
Gtk::HButtonBox m_ButtonBox;
Gtk::Button m_Button_Quit;
Gtk::Button m_Button_Delete;
};
#endif //GTKMM_EXAMPLEWINDOW_H
examplewindow.cc:
#include <iostream>
#include "examplewindow.h"
namespace
{
struct TreeEntry
{
int m_id;
int m_dice_id;
const char* m_filename;
const char* m_name;
TreeEntry() : m_id(-1), m_dice_id(-1), m_filename(0), m_name(0) {}
TreeEntry( const int id, const int dice_id, const char* fn, const char* name )
: m_id(id), m_dice_id(dice_id), m_filename(fn), m_name(name) {}
};
TreeEntry g_entries[] =
{
TreeEntry( 1, 1, "gnome-dice-1.svg", "Billy Bob" ),
TreeEntry( 11, 2, "gnome-dice-2.svg", "Billy Bob Junior" ),
TreeEntry( 12, 3, "gnome-dice-3.svg", "Sue Bob" ),
TreeEntry( 2, 4, "gnome-dice-4.svg", "Joey Jojo" ),
TreeEntry( 3, 5, "gnome-dice-5.svg", "Rob McRoberts" ),
TreeEntry( 31, 6, "gnome-dice-6.svg", "Xavier McRoberts" ),
TreeEntry( 53, 1, "gnome-dice-1.svg", "Ian McClintock" ),
TreeEntry( 27, 2, "gnome-dice-2.svg", "John Roberts" )
};
}
ExampleWindow::ExampleWindow() :
m_Button_Quit("Quit"),
m_Button_Delete("Delete")
{
set_title("Gtk::TreeView (TreeStore) example");
set_border_width(5);
set_default_size(800, 600);
add(m_VBox);
//Add the TreeView, inside a ScrolledWindow, with the button underneath:
m_ScrolledWindow.add(m_TreeView);
//Only show the scrollbars when they are necessary:
m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
m_VBox.pack_start(m_ScrolledWindow);
m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_Button_Delete, Gtk::PACK_SHRINK);
m_ButtonBox.set_border_width(5);
m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_quit) );
m_Button_Delete.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_delete) );
m_Button_Delete.set_sensitive( false ); // Only activate if row selected
//Create the Tree model:
m_refTreeModel = Gtk::ListStore::create(m_Columns);
m_TreeView.set_model(m_refTreeModel);
//All the items to be reordered with drag-and-drop:
m_TreeView.set_reorderable();
m_TreeView.set_rules_hint();
m_TreeView.set_headers_clickable(true);
m_TreeView.set_headers_visible(true);
// Handle tree selections
//
m_refTreeSelection = m_TreeView.get_selection();
m_refTreeSelection->signal_changed().connect( sigc::mem_fun(*this, &ExampleWindow::on_selection_changed) );
//Add the TreeView's view columns:
m_TreeView.append_column("ID", m_Columns.m_col_id);
m_TreeView.append_column("Image", m_Columns.m_pixbuf);
m_TreeView.append_column("Name", m_Columns.m_col_name);
m_refTreeModel->set_sort_column( m_Columns.m_col_name, Gtk::SORT_ASCENDING ); // Initial sorting column
// Set sorting for each column added
Gtk::TreeView::Column* pColumn = m_TreeView.get_column(0);
pColumn->set_sort_column( m_Columns.m_col_id );
pColumn = m_TreeView.get_column(1);
pColumn->set_sort_column( m_Columns.m_dice_id );
pColumn = m_TreeView.get_column(2);
pColumn->set_sort_column( m_Columns.m_col_name );
// Fill the TreeView's model
//
const int count = sizeof( g_entries ) / sizeof( TreeEntry );
for( int idx = 0; idx < count; ++idx )
{
add_entry( g_entries[idx].m_id, g_entries[idx].m_dice_id, g_entries[idx].m_filename, g_entries[idx].m_name );
}
show_all_children();
}
ExampleWindow::~ExampleWindow()
{
}
void ExampleWindow::add_entry( const int id, const int dice_id, const char* filename, const char* name )
{
Gtk::TreeModel::Row row = *(m_refTreeModel->append());
row[m_Columns.m_col_id] = id;
row[m_Columns.m_dice_id] = dice_id;
row[m_Columns.m_pixbuf] = Gdk::Pixbuf::create_from_file( filename );
row[m_Columns.m_col_name] = name;
}
void ExampleWindow::on_button_quit()
{
hide();
}
void ExampleWindow::on_button_delete()
{
Gtk::TreeModel::iterator store_iter = m_refTreeSelection->get_selected();
m_refTreeModel->erase( store_iter );
}
void ExampleWindow::on_selection_changed()
{
m_Button_Delete.set_sensitive(
m_refTreeSelection->count_selected_rows() > 0 );
}