Re: custom TreeModel
- From: danny <danny van elsen skynet be>
- To: gtkmm-list gnome org
- Subject: Re: custom TreeModel
- Date: Thu, 12 Dec 2019 09:09:18 +0100
well, I was trying to come up with a good demo, because I have always felt that people will like to fill a treeview directly from their own data
it has been a while since I have worked woth gtkmm, so I adapted the following from a working program against gtk-2:
the Gtk::Window* do_treeview_memory() locks into the existing demos code (gtkmm-3.22.3/demos/gtk-demo)
the allocation of the treemodel seems to fail, and I only get an empty window
(gtkmm-demo:6194): GLib-GObject-WARNING **: attempting to add an interface (GtkTreeModel) to class (gtkmm__CustomObject_16Memory_TreeModel) after class_init
(gtkmm-demo:6194): Gtk-CRITICAL **: gtk_tree_view_set_model: assertion 'model == NULL || GTK_IS_TREE_MODEL (model)' failed
(and when I will get past that: I obviously haven't tested the callback routines yet...)
regards, Danny.
-------------------------
/* Tree View/Tree Store
*
* The GtkTreeStore is used to store data in tree form, to be
* used later on by a GtkTreeView to display it. This demo builds
* a simple list of nodes in memory and displays it in the GtkTreeStore.
*
*/
#include <gtkmm.h>
#define MEMORY_TREEMODEL_COL_INT 0
#define MEMORY_TREEMODEL_COL_STRING 1
class Memory_Item
{
public:
Memory_Item();
int row_index;
int mi_1;
std::string mi_2;
int mi_A1;
std::string mi_A2;
int mi_B1;
std::string mi_B2;
};
Memory_Item::Memory_Item()
{
row_index = mi_1 = mi_A1 = mi_B1 = 0;
mi_2 = mi_A2 = mi_B2 = "";
}
class Memory
{
public:
Memory();
Memory_Item* Get_Nth_Row(int nth_row);
std::vector <Memory_Item> v_mi;
};
Memory::Memory()
{
v_mi.clear();
}
Memory_Item*
Memory::Get_Nth_Row(int nth_row)
{
return &(v_mi[nth_row]);
};
class Memory_Columns: public Gtk::TreeModel::ColumnRecord
{
public:
Memory_Columns();
virtual ~Memory_Columns();
int Get_Columns_Count() const;
Gtk::TreeModelColumn<int> col_i;
Gtk::TreeModelColumn<Glib::ustring> col_s;
private:
int n_columns;
};
Memory_Columns::Memory_Columns()
{
n_columns = 0;
add(col_i); n_columns++;
add(col_s); n_columns++;
}
Memory_Columns::~Memory_Columns()
{
}
int
Memory_Columns::Get_Columns_Count() const
{
return n_columns;
}
class Memory_TreeModel
: public Glib::Object,
public Gtk::TreeModel
{
public:
Memory_TreeModel();
virtual ~Memory_TreeModel();
static Glib::RefPtr<Memory_TreeModel> create();
void Set_Memory(Memory *m);
Memory *memory;
protected:
// Overrides:
virtual Gtk::TreeModelFlags get_flags_vfunc() const;
virtual int get_n_columns_vfunc() const;
virtual GType get_column_type_vfunc(int index) const;
virtual void get_value_vfunc(const TreeModel::iterator& iter, int column, Glib::ValueBase& value) const;
bool iter_next_vfunc(const iterator& iter, iterator& iter_next) const;
virtual bool iter_children_vfunc(const iterator& parent, iterator& iter) const;
virtual bool iter_has_child_vfunc(const iterator& iter) const;
virtual int iter_n_children_vfunc(const iterator& iter) const;
virtual int iter_n_root_children_vfunc() const;
virtual bool iter_nth_child_vfunc(const iterator& parent, int n, iterator& iter) const;
virtual bool iter_nth_root_child_vfunc(int n, iterator& iter) const;
virtual bool iter_parent_vfunc(const iterator& child, iterator& iter) const;
virtual Path get_path_vfunc(const iterator& iter) const;
virtual bool get_iter_vfunc(const Path& path, iterator& iter) const;
private:
typedef Gtk::TreeModelColumn<Glib::ustring> StringColumn;
typedef Gtk::TreeModelColumn<int> IntColumn;
mutable IntColumn::ValueType ic;
mutable StringColumn::ValueType sc;
mutable StringColumn s_c;
mutable IntColumn i_c;
mutable int result_int;
mutable std::string result_string;
Memory_Columns m_columns;
};
Memory_TreeModel::Memory_TreeModel()
: Glib::ObjectBase( typeid(Memory_TreeModel) ),
Glib::Object()
{
Gtk::TreeModel::add_interface( Glib::Object::get_type() );
memory = 0;
sc.init( StringColumn::ValueType::value_type() );
ic.init( IntColumn::ValueType::value_type() );
}
Memory_TreeModel::~Memory_TreeModel()
{
}
Glib::RefPtr<Memory_TreeModel>
Memory_TreeModel::create()
{
return
Glib::RefPtr<Memory_TreeModel> (new Memory_TreeModel );
}
Gtk::TreeModelFlags
Memory_TreeModel::get_flags_vfunc() const
{
return Gtk::TreeModelFlags(0);
}
int
Memory_TreeModel::get_n_columns_vfunc() const
{
return m_columns.Get_Columns_Count();
}
void
Memory_TreeModel::get_value_vfunc(const TreeModel::iterator& iter, int column, Glib::ValueBase& value) const
{
Memory_Item *mi;
//////////////////////////////////////////////////////////
mi = (Memory_Item *) iter.gobj()->user_data;
if (mi == 0) { return; }
switch (column)
{
case MEMORY_TREEMODEL_COL_INT:
{
result_int = mi->mi_1;
ic.set(result_int);
value.init( Glib::Value< int >::value_type() );
value = ic;
break;
}
case MEMORY_TREEMODEL_COL_STRING:
{
result_string = mi->mi_2;
sc.set(result_string);
value.init( Glib::Value< std::string >::value_type() );
value = sc;
break;
}
}
}
bool
Memory_TreeModel::iter_next_vfunc(const iterator& iter, iterator& iter_next) const
{
Memory_Item *mi;
int new_offset;
//////////////////////////////////////////////////////////
//cout << "iter_next_vfunc" << "\n";
if
((void*) iter.gobj()->user_data == 0)
{ iter_next = iterator(); return false; } //There is no next row.
mi = (Memory_Item *) iter.gobj()->user_data;
new_offset = mi->row_index + 1;
if (new_offset >= memory->v_mi.size())
{ iter_next = iterator(); return false; } //There is no next row.
mi = memory->Get_Nth_Row(new_offset);
iter_next.gobj()->user_data = (void*) &mi;
return true;
}
bool
Memory_TreeModel::iter_children_vfunc(const iterator& parent, iterator& iter) const
{
return iter_nth_child_vfunc(parent, 0, iter);
}
bool
Memory_TreeModel::iter_has_child_vfunc(const iterator& iter) const
{
return (iter_n_children_vfunc(iter) > 0);
}
int
Memory_TreeModel::iter_n_children_vfunc(const iterator& iter) const
{
return 0; //There are no children
}
int
Memory_TreeModel::iter_n_root_children_vfunc() const
{
return
memory->v_mi.size(); // number of rows
}
bool
Memory_TreeModel::iter_nth_child_vfunc(const iterator& parent, int /* n */, iterator& iter) const
{
iter = iterator();
return false; //There are no children.
}
bool
Memory_TreeModel::iter_nth_root_child_vfunc(int n, iterator& iter) const
{
Memory_Item *mi;
//////////////////////////////////////////////////////////
if (!mi) {return false; }
if (n < memory->v_mi.size())
{
mi = memory->Get_Nth_Row(n);
iter.gobj()->user_data = (void*) mi;
return true; // n <= available rows
}
return false; // n > available rows
}
bool
Memory_TreeModel::iter_parent_vfunc(const iterator& child, iterator& iter) const
{
iter = iterator();
return false; //There are no children, so no parents.
}
bool
Memory_TreeModel::get_iter_vfunc(const Path& path, iterator& iter) const
{
unsigned ps; // path_size
int ri; // row_index
Memory_Item *mi;
/////////////////////////////////////////////
if (!memory) {return false; }
ps = path.size();
if ( (!ps)
|| (ps > 1)) //There are no children.
{ iter = iterator(); return false; }
iter = iterator(); //clear the input parameter.
//iter.set_stamp(m_stamp);
ri = path[0];
if (ri >= memory->v_mi.size())
{ iter = iterator(); return false; }
mi = memory->Get_Nth_Row(ri);
iter.gobj()->user_data = (void*) mi;
return true;
}
Gtk::TreeModel::Path
Memory_TreeModel::get_path_vfunc(const iterator& /* iter */) const
{
//TODO:
return Path();
}
GType
Memory_TreeModel::get_column_type_vfunc(int index) const
{
switch (index)
{
case MEMORY_TREEMODEL_COL_INT:
{
return i_c.type();
break;
}
case MEMORY_TREEMODEL_COL_STRING:
{
return s_c.type();
break;
}
default:
{
return 0;
break;
}
}
}
class Example_TreeView_Memory : public Gtk::Window
{
public:
Example_TreeView_Memory();
~Example_TreeView_Memory() override;
protected:
//vfunc overrides:
void on_realize() override;
void fill_memory();
//Member widgets:
Gtk::Box m_VBox;
Gtk::ScrolledWindow m_ScrolledWindow;
Gtk::Label m_Label;
Memory_Columns memcol;
Glib::RefPtr<Memory_TreeModel> treemodel;
Gtk::TreeView treeview;
Memory mem_ory;
};
//Called by DemoWindow;
Gtk::Window* do_treeview_memory()
{
return new Example_TreeView_Memory();
}
Example_TreeView_Memory::Example_TreeView_Memory()
: m_VBox(Gtk::ORIENTATION_VERTICAL, 8),
m_Label("Analysis Sheet")
{
set_title("Memory analysis");
set_border_width(8);
set_default_size(650, 400);
add(m_VBox);
m_VBox.pack_start(m_Label, Gtk::PACK_SHRINK);
m_ScrolledWindow.set_shadow_type(Gtk::SHADOW_ETCHED_IN);
m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
m_VBox.pack_start(m_ScrolledWindow);
/* fill memory */
fill_memory();
/* create model */
treemodel = Memory_TreeModel::create();
treemodel->memory = &mem_ory;
/* treeview */
treeview.append_column("Integer", memcol.col_i);
treeview.append_column("String", memcol.col_s);
treeview.set_model(treemodel);
Glib::RefPtr<Gtk::TreeSelection> refTreeSelection = treeview.get_selection();
refTreeSelection->set_mode(Gtk::SELECTION_MULTIPLE);
m_ScrolledWindow.add(treeview);
show_all();
}
Example_TreeView_Memory::~Example_TreeView_Memory()
{
}
void Example_TreeView_Memory::fill_memory()
{
Memory_Item mi;
mi.row_index = 1;
mi.mi_1 = 1; mi.mi_2 = "item 1"; mi.mi_A1 = 11; mi.mi_A2 = "item A11"; mi.mi_B1 = 111; mi.mi_B2 = "item B111";
mem_ory.v_mi.push_back(mi);
mi.row_index = 2;
mi.mi_1 = 2; mi.mi_2 = "item 2"; mi.mi_A1 = 22; mi.mi_A2 = "item A22"; mi.mi_B1 = 222; mi.mi_B2 = "item B222";
mem_ory.v_mi.push_back(mi);
mi.row_index = 3;
mi.mi_1 = 3; mi.mi_2 = "item 3"; mi.mi_A1 = 33; mi.mi_A2 = "item A33"; mi.mi_B1 = 333; mi.mi_B2 = "item B333";
mem_ory.v_mi.push_back(mi);
mi.row_index = 4;
mi.mi_1 = 4; mi.mi_2 = "item 4"; mi.mi_A1 = 44; mi.mi_A2 = "item A44"; mi.mi_B1 = 444; mi.mi_B2 = "item B444";
mem_ory.v_mi.push_back(mi);
}
void Example_TreeView_Memory::on_realize()
{
treeview.expand_all();
//call base class:
Window::on_realize();
}
-------------------------
demos.h
#ifndef _DEMOS_H
#define _DEMOS_H
#include "demowindow.h"
typedef sigc::slot<Gtk::Window*> type_slotDo;
struct Demo
{
const char* title;
const char* filename;
type_slotDo slot; //The method to call.
Demo* children;
};
Gtk::Window* do_appwindow();
Gtk::Window* do_builder();
Gtk::Window* do_buttonbox();
Gtk::Window* do_change_display();
Gtk::Window* do_colorsel();
Gtk::Window* do_dialog();
Gtk::Window* do_drawingarea();
Gtk::Window* do_flowbox();
Gtk::Window* do_gestures();
Gtk::Window* do_glarea();
Gtk::Window* do_headerbar();
Gtk::Window* do_iconbrowser();
Gtk::Window* do_iconview();
Gtk::Window* do_images();
Gtk::Window* do_menus();
Gtk::Window* do_overlay();
Gtk::Window* do_panes();
Gtk::Window* do_pixbufs();
Gtk::Window* do_shortcuts();
Gtk::Window* do_sizegroup();
Gtk::Window* do_stack();
Gtk::Window* do_stacksidebar();
Gtk::Window* do_textview();
Gtk::Window* do_treeview_editable_cells();
Gtk::Window* do_treeview_liststore();
Gtk::Window* do_treeview_treestore();
Gtk::Window* do_treeview_memory();
Demo child0[] =
{
{ "Editable Cells", "example_treeview_editable_cells.cc", sigc::ptr_fun(&do_treeview_editable_cells), nullptr },
{ "List Store", "example_treeview_liststore.cc", sigc::ptr_fun(&do_treeview_liststore), nullptr },
{ "Tree Store", "example_treeview_treestore.cc", sigc::ptr_fun(&do_treeview_treestore), nullptr },
{ "Memory Tree Store", "example_treeview_memory.cc", sigc::ptr_fun(&do_treeview_memory), nullptr },
{ nullptr, nullptr, type_slotDo(), nullptr }
};
Demo testgtk_demos[] =
{
{ "Application main window", "example_appwindow.cc", sigc::ptr_fun(&do_appwindow), nullptr },
{ "Builder", "example_builder.cc", sigc::ptr_fun(&do_builder), nullptr },
{ "Button Boxes", "example_buttonbox.cc", sigc::ptr_fun(&do_buttonbox), nullptr },
{ "Change Display", "example_change_display.cc", sigc::ptr_fun(&do_change_display), nullptr },
{ "Color Selector", "example_colorsel.cc", sigc::ptr_fun(&do_colorsel), nullptr },
{ "Dialog and Message Boxes", "example_dialog.cc", sigc::ptr_fun(&do_dialog), nullptr },
{ "Drawing Area", "example_drawingarea.cc", sigc::ptr_fun(&do_drawingarea), nullptr },
{ "Flow Box", "example_flowbox.cc", sigc::ptr_fun(&do_flowbox), nullptr },
{ "Gestures", "example_gestures.cc", sigc::ptr_fun(&do_gestures), nullptr },
{ "Header Bar", "example_headerbar.cc", sigc::ptr_fun(&do_headerbar), nullptr },
{ "Icon Browser", "example_iconbrowser.cc", sigc::ptr_fun(&do_iconbrowser), nullptr },
{ "Icon View", "example_iconview.cc", sigc::ptr_fun(&do_iconview), nullptr },
{ "Images", "example_images.cc", sigc::ptr_fun(&do_images), nullptr },
{ "Menus", "example_menus.cc", sigc::ptr_fun(&do_menus), nullptr },
{ "OpenGL Area", "example_glarea.cc", sigc::ptr_fun(&do_glarea), nullptr },
{ "Overlay", "example_overlay.cc", sigc::ptr_fun(&do_overlay), nullptr },
{ "Paned Widgets", "example_panes.cc", sigc::ptr_fun(&do_panes), nullptr },
{ "Pixbufs", "example_pixbufs.cc", sigc::ptr_fun(&do_pixbufs), nullptr },
{ "Shortcuts Window", "example_shortcuts.cc", sigc::ptr_fun(&do_shortcuts), nullptr },
{ "Size Groups", "example_sizegroup.cc", sigc::ptr_fun(&do_sizegroup), nullptr },
{ "Stack", "example_stack.cc", sigc::ptr_fun(&do_stack), nullptr },
{ "Stack Sidebar", "example_stacksidebar.cc", sigc::ptr_fun(&do_stacksidebar), nullptr },
{ "Text Widget", "example_textview.cc", sigc::ptr_fun(&do_textview), nullptr },
{ "Tree View", "", type_slotDo(), child0 },
{ nullptr, nullptr, type_slotDo(), nullptr }
};
#endif //_DEMOS_H
please show the rest of the class declaration, including what/how it inherits, and how you instantiate it.
-------------------------
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]