Re: custom TreeModel

danny via gtkmm-list <[email protected]>
Newsgroups gmane.comp.gnome.gtkmm
Message-ID <[email protected]>
hi
well, actually, I did not find the example you are referring to. I
probably did when I was working with the original gtk2 program, though.
so I have come up with this:(gtkmm-3.22.3/demos)
--------------------------------------------------------------/* 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>
//debug#include <iostream>
#define MEMORY_TREEMODEL_COL_INT        0#define
MEMORY_TREEMODEL_COL_STRING     1
class Memory_Item{// one Memory Item will represent one chunk of
information to// be shown in the Treeview, i.e. one row with
subnodespublic:	Memory_Item();
	// data for top level nodes	int			m
i_1;	std::string mi_2;
	// for first level of sub nodes	int			
mi_A1;	std::string	mi_A2;
	// for second level of sub nodes	int			
mi_B1;	std::string	mi_B2;};
Memory_Item::Memory_Item(){	mi_1 = mi_A1 = mi_B1 = 0;	mi_
2 = mi_A2 = mi_B2 = "";}

class Memory{public:	Memory();
	// these we will show in the treeview	std::vector
<Memory_Item>      v_mi;};
Memory::Memory(){	v_mi.clear();}
class Memory_Columns: public Gtk::TreeModel::ColumnRecord{public:
	Memory_Columns();
    virtual ~Memory_Columns();
    int Get_Columns_Count() const;
    // a column for the ints    Gtk::TreeModelColumn<int> col_i;
    // and a column for the
strings    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(){}
intMemory_Columns::Get_Columns_Count() const{  return n_columns;}
class  Memory_TreeModel  : public Gtk::TreeModel , public
Glib::Object{public:
	Memory_TreeModel();  virtual ~Memory_TreeModel();
  static    Glib::RefPtr<Memory_TreeModel> create();
  void      Set_Memory(Memory *m);
  // the gate for the model to the information to be shown  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::TreeModelFlagsMemory_TreeModel::get_flags_vfunc() const{   return
Gtk::TreeModelFlags(0);}
intMemory_TreeModel::get_n_columns_vfunc() const{   return
m_columns.Get_Columns_Count();}
voidMemory_TreeModel::get_value_vfunc(const TreeModel::iterator& iter,
int column, Glib::ValueBase& value) const{	// what information
does one row contain?  Memory_Item   mi;
  unsigned long	l;  unsigned long	p;		//
path  //////////////////////////////////////////////////////////
  // user_data contains the row number  l = (unsigned long)
iter.gobj()->user_data;
  if (l >= memory->v_mi.size())  { return; }
  // user_data2 contains the depth of the node  p = (unsigned long)
iter.gobj()->user_data2;
  mi = memory->v_mi.at(l);
  switch (column)  {  case MEMORY_TREEMODEL_COL_INT:    {     if (p <=
1) 		// top level node     	 	 	 	
 	{result_int = mi.mi_1;}
     else if (p == 2) 	// first sub node level     	 	
 	 	 	{result_int = mi.mi_A1;}
     else    			// second sub node level     	
 	 	 	 	{result_int = mi.mi_B1;}
     ic.set(result_int);     value.init( Glib::Value< int
>::value_type() );     value = ic;     break;    }
  case MEMORY_TREEMODEL_COL_STRING:    {    	// same
partitioning as for the ints     if (p <= 1) 		{result_st
ring = mi.mi_2;}     else if (p == 2) 	{result_string =
mi.mi_A2;}     else    			{result_string =
mi.mi_B2;}
     sc.set(result_string);     value.init( Glib::Value< std::string
>::value_type() );     value = sc;
     break;    }  }}
boolMemory_TreeModel::iter_next_vfunc(const iterator& iter, iterator&
iter_next) const{	// what is the next node from this one? 
unsigned long l, p;
  //////////////////////////////////////////////////////////
  l = (unsigned long) iter.gobj()->user_data;  p = (unsigned long)
iter.gobj()->user_data2;
  if (   (l + 1 >= memory->v_mi.size())		// beyond the
last row	  || (p > 1))						
	// the sublevels have just one child, no next node
  { iter_next = iterator(); return false; } //There is no next row.
  l++;									
	// next row
  // set markers for next node  iter_next.gobj()->user_data = (void *)
l;  iter_next.gobj()->user_data2 = (void *) p;
  return true;}
boolMemory_TreeModel::iter_children_vfunc(const iterator& parent,
iterator& iter) const{	// get the first child of this parent
node  return iter_nth_child_vfunc(parent, 0, iter);}
boolMemory_TreeModel::iter_has_child_vfunc(const iterator& iter)
const{  return (iter_n_children_vfunc(iter) > 0);}
intMemory_TreeModel::iter_n_children_vfunc(const iterator& iter)
const{  unsigned long	l;
  int	n;
  ////////////////////////////////////////
  l = (unsigned long) iter.gobj()->user_data2;
  if (l == 0)			// uninitiated node  { n = 0;}
  else if (l <= 2)		// only two sublevels of nodes  { n =
1;}
  else  { n = 0;}				// no nodes
  return n;}
intMemory_TreeModel::iter_n_root_children_vfunc() const{  return
memory->v_mi.size();  // number of rows}
boolMemory_TreeModel::iter_nth_child_vfunc(const iterator& parent,
int  n , iterator& iter) const{	// get the nth child of this
parent node  unsigned long	l, p;
  ////////////////////////////////////////
  p = (unsigned long) parent.gobj()->user_data;  l = (unsigned long)
parent.gobj()->user_data2;
  if (   (l > 2)		// only two sublevels of nodes	 
 || (n > 0))		// and one child node only  {   iter =
iterator();   return false; //There are no children.  }
  iter.gobj()->user_data = (void*) p;			// row
index  iter.gobj()->user_data2 = (void*) (l + 1);	// sublevel
  return true;}
boolMemory_TreeModel::iter_nth_root_child_vfunc(int n, iterator& iter)
const{	// get the nth row  unsigned long l;
  ///////////////////////////////////////
  l = n;
  if (l >= memory->v_mi.size()) {return false; }
  iter.gobj()->user_data = (void*) l;		// row index 
iter.gobj()->user_data2 = (void*) 1;		// top level node
  return true;    // n <= available rows}
boolMemory_TreeModel::iter_parent_vfunc(const iterator& child,
iterator& iter) const{	// set a parent for this child  unsigned
long	l, p;
  ////////////////////////////////////////
  l = (unsigned long) child.gobj()->user_data2;  p = (unsigned long)
child.gobj()->user_data;
  if (l <= 1)			// top level  {   iter =
iterator();
   return false; //There are no children.  }
  iter.gobj()->user_data = (void*) p;			// row
index  iter.gobj()->user_data2 = (void*) (l - 1);	// one level
up
  return true;}
boolMemory_TreeModel::get_iter_vfunc(const Path& path, iterator& iter)
const{	// define a node
   unsigned long          ps;     // path_size   unsigned long 		
  ri;     // row_index
   /////////////////////////////////////////////
   ps = path.size();   if (   (!ps)       || (ps > 3))			
	// only two levels of subnodes
   { iter = iterator(); return false; }
   iter = iterator(); //clear the input parameter.
   ri = path[0];
   if (ri >= memory->v_mi.size())   { iter = iterator(); return false;
}
   iter.gobj()->user_data = (void*) ri;		// row
index   iter.gobj()->user_data2 = (void*) ps;	//
sublevel   iter.gobj()->user_data3 = (void*) -1;	// just to show
its presence, really
   return true;}
Gtk::TreeModel::PathMemory_TreeModel::get_path_vfunc(const iterator& /*
iter */) const{   //TODO:   return Path();}
GTypeMemory_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.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.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.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.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();}---------------------------
-----------------------------------
adapt  demo.h
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 }};
--------------------------------------------------------------
I'm not sure, though, if I really understand the purpose of virtual
bool Gtk::TreeModel::iter_parent_vfunc 
          (
          
this function finds a parent for the given child, right? but why would
that be needed, if a child can only be arrived at from a parent node in
the first place?
regards, Danny.
--------------------------------------------------------------
-----Original Message-----
Date: Sat, 14 Dec 2019 11:23:37 +0100Subject: Re: custom TreeModelCc: g
[email protected]: danny <[email protected]>From: Kjell
Ahlstedt <[email protected]>
  
    
  
  
    Your custom TreeModel can perhaps be added either to the gtkmm
      demo programs or to the gtkmm tutorial at
      https://gitlab.gnome.org/GNOME/gtkmm-documentation. Let's decide
      when you have a working program.

    
    Have you noticed that there is a custom TreeModel example at
https://gitlab.gnome.org/GNOME/gtkmm-documentation/tree/gtkmm-3-24/exam
ples/others/treemodelcustom
      ? I don't know if it's a good example. Most programs under the
      examples/others directory are not maintained.
    Kjell

    
    On 2019-12-12 09:37, danny via
      gtkmm-list wrote:

    
    
>       
>       
>       
>       indeed! that seems to get me on my way! thanks!
>       
> 
>       
>       if/when I get this working: would you be interested in adding
>         this to the gtkmm demo programs?
>       
> 
>       
>       regards, D.
>       
>         
>           
>       
>       
> 
>

_______________________________________________
gtkmm-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.