Re: custom TreeModel

danny via gtkmm-list <[email protected]>
Newsgroups gmane.comp.gnome.gtkmm
Message-ID <[email protected]>
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.
-------------------------

_______________________________________________
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.