Re: [gtkmm] Custom types in a Gtk::TreeView



Murray Cumming <murrayc murrayc com> writes:

> On Tue, 2004-04-13 at 14:12, Roger Leigh wrote:
>> >From what I've read in the sources, this should do the trick (from
>> treeviewcolumn.h):
>> 
>> Is adding support for my own types into your namespace OK?
>
> It's a template specialization, so I guess you have no choice. Just
> don't export the symbol in any library that you distribute widely.

The custom types will all be within their own namespace, I don't think
this will be a problem.  There should be no potential for names
clashing.

>> My question here: I need a property_numeric() property, so I can set
>> the number being rendered.  If I derive from CellRendererText, I can
>> then set property_text() as a side effect.  However, I assume that due
>> to being a wrapper, I need to actually set a property ("numeric") in
>> the underlying GObject, with g_object_install_property(), and wrap
>> that with a PropertyProxy.  Since I have a C++ type (numeric), I'm not
>> sure how to do that (GValue?), since I need to somehow create a
>> GParamSpec to install as a property (I didn't see this wrapped).
>> 
>> Is this correct?  Or is there an easier way?
>
> If you just add a PropertyProxy(), it should do that for you. It's
> magic. See for instance, MyCellRendererToggle in the examples.

That really is fantastic!  It now all works, as simply as this this:

  item_list->append_column("Quantity", list_columns.m_col_quantity);

The ability to use a Property<> to add a property to the underlying
GObject is simply amazing!

For anyone interested, the code is as follows:

// custom cellrenderer for the numeric data type                 -*- C++ -*-
// $Id: cellrenderernumeric.h,v 1.1 2004/04/14 14:42:50 rleigh Exp $
//
// Copyright (C) 2003 Epic Technology Limited.
//
// Authors: Roger Leigh <roger whinlatter uklinux net>

#ifndef APP_EPICPOS_CELLRENDERERNUMERIC_H
#define APP_EPICPOS_CELLRENDERERNUMERIC_H

#include <glibmm/property.h>
#include <glibmm/propertyproxy.h>
#include <gtkmm/cellrenderertext.h>
#include <gtkmm/treeviewcolumn.h>

#include <util/numeric.h>

namespace EPICUI
{
  class CellRendererNumeric : public Gtk::CellRendererText
  {
  public:
    /// The constructor.
    CellRendererNumeric();

    /// The destructor.
    virtual ~CellRendererNumeric();

    /// Proxy for the "numeric" property.
    Glib::PropertyProxy<EPIC::numeric> property_numeric();

    /// Provide the default property.
    virtual Glib::PropertyProxy_Base _property_renderable();

  protected:
    /**
     * When the "numeric" property changes, update the "text" property
     * to display the correct value.
     */
    virtual void on_numeric_changed();

  private:
    /// The "numeric" property.
    Glib::Property<EPIC::numeric> property_numeric_;

  }; // class NumericEntry

} // namespace EPICUI

namespace Gtk
{
  namespace TreeViewColumn_CellRendererGeneration
  {
    template<>
    CellRenderer* generate_cellrenderer<EPIC::numeric>(bool editable);
  }
}

#endif // APP_EPICPOS_CELLRENDERERNUMERIC_H
// custom cellrenderer for the numeric data type                 -*- C++ -*-
// $Id: cellrenderernumeric.cc,v 1.1 2004/04/14 14:42:50 rleigh Exp $
//
// Copyright (C) 2003 Epic Technology Limited.
//
// Authors: Roger Leigh <roger whinlatter uklinux net>

#include <sstream>

#include "cellrenderernumeric.h"

namespace EPICUI
{
  CellRendererNumeric::CellRendererNumeric():
    Glib::ObjectBase(typeid(EPICUI::CellRendererNumeric)),
    Gtk::CellRendererText(),
    property_numeric_(*this, "numeric", EPIC::numeric(0L))
  {
    property_numeric_.get_proxy().signal_changed().connect
      ( SigC::slot(*this, &CellRendererNumeric::on_numeric_changed) );
  }

  CellRendererNumeric::~CellRendererNumeric()
  {}

  Glib::PropertyProxy<EPIC::numeric>
  CellRendererNumeric::property_numeric()
  {
    return property_numeric_.get_proxy();
  }

  Glib::PropertyProxy_Base
  CellRendererNumeric::_property_renderable()
  {
    return property_numeric();
  }

  void
  CellRendererNumeric::on_numeric_changed()
  {
    std::ostringstream tmp;
    tmp << property_numeric();
    property_text() = tmp.str();
  }

}; // namespace EPICUI

namespace Gtk
{
  namespace TreeViewColumn_CellRendererGeneration
  {
    template<>
    CellRenderer* generate_cellrenderer<EPIC::numeric>(bool editable)
    {
      EPICUI::CellRendererNumeric* pCellRenderer = new EPICUI::CellRendererNumeric();
      pCellRenderer->property_editable() = editable;
      return pCellRenderer;
    }
  } // namespace TreeViewColumn_CellRendererGeneration
} // namespace Gtk

One issue I found: my "numeric" type stores the number of decimal
places of precision it should hold.  This can be any positive
integer.  It defaults to 0, and can be altered at any time using a
set_dp member function.

When putting a numeric value into a list store model column, the type
is default initialised to have 0 decimal places, and I can't find a
way to change this.  I'm going to alter the type to set this as a
template parameter, but I would be interested if there was a way to
directly access the model column data (this is probably a bad idea,
though).  Is it intended that only types which are Assignable should
be stored in a tree model?  In this case, the operator= intentionally
preserves the precision of the left-hand operand for all operations.


Regards,
Roger

-- 
Roger Leigh

                Printing on GNU/Linux?  http://gimp-print.sourceforge.net/
                GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]