OSDN Git Service

Board treeview is sortable.
[fukui-no-namari/dialektos.git] / src / board_view_column.hxx
index 26cf9a4..615ed4b 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <gtkmm/treeviewcolumn.h>
 #include <glibmm/ustring.h>
-#include <gtkmm/treemodel.h>
 #include <gtkmm/cellrenderer.h>
 #include <boost/mpl/find.hpp>
 #include "thread_list_model.hxx"
@@ -36,99 +35,161 @@ namespace view_column {
 
 class Base : public Gtk::TreeViewColumn {
 public:
-  Base(const Glib::ustring& title);
-  virtual ~Base();
-protected:
-  template <typename ModelColumnType>
-  void on_cell_data_int(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
-  template <typename ModelColumnType>
-  void on_cell_data_string(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
-private:
-  virtual void do_cell_data(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter) = 0;
-  void on_cell_data(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
+  Base(const Glib::ustring& title) : Gtk::TreeViewColumn(title) {
+    set_min_width(15);
+    set_reorderable(true);
+    set_resizable(true);
+    set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED);
+    set_clickable(true);
+//    set_fixed_width(30); // specify in a derived class.
+  }
+  virtual ~Base() {}
+  virtual std::string get_id() const = 0;
 };
 
-template <typename ModelColumnType>
-void Base::on_cell_data_int(Gtk::CellRenderer* cell,
-    const Gtk::TreeModel::iterator& iter) {
-  typename ModelColumnType::type value;
-  iter->get_value(boost::mpl::find<model_column::List,
-      ModelColumnType>::type::pos::value, value);
-  if (value > 0) cell->set_property("text", value);
-  else cell->set_property("text", Glib::ustring(""));
-}
-template <typename ModelColumnType>
-void Base::on_cell_data_string(Gtk::CellRenderer* cell,
-    const Gtk::TreeModel::iterator& iter) {
+template <typename DerivedT>
+class ViewColumnBase : public Base {
+public:
+  ViewColumnBase(const Glib::ustring& title) : Base(title) {
+    Gtk::CellRendererText* cell = Gtk::manage(new Gtk::CellRendererText);
+    pack_start(*cell, true);
+
+    typedef typename DerivedT::render_cell_functor FunctorType;
+    set_cell_data_func(*cell, FunctorType());
+  }
+  virtual ~ViewColumnBase() {}
+};
 
-  typename ModelColumnType::type value;
-  iter->get_value(boost::mpl::find<model_column::List,
-      ModelColumnType>::type::pos::value, value);
 
-  cell->set_property("text", value);
-}
+namespace {
+template <typename TypeHolderT, typename ValueType> struct DoRenderCell;
 
+template <typename TypeHolderT>
+struct DoRenderCell<TypeHolderT, std::string> :
+  public std::binary_function<Gtk::CellRenderer*,
+    Gtk::TreeModel::iterator, void> {
+  void operator()(
+      Gtk::CellRenderer* cell,
+      const Gtk::TreeModel::iterator& iter) const {
+    typename TypeHolderT::type value;
+    iter->get_value(boost::mpl::find<model_column::List,
+        TypeHolderT>::type::pos::value, value);
 
-class StartTime: public Base {
-public:
-  StartTime();
-  virtual ~StartTime();
-private:
-  virtual void do_cell_data(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
+    cell->set_property("text", value);
+  }
+};
+template <typename TypeHolderT>
+struct DoRenderCell<TypeHolderT, int> :
+  public std::binary_function<Gtk::CellRenderer*,
+    Gtk::TreeModel::iterator, void> {
+  void operator()(
+      Gtk::CellRenderer* cell,
+      const Gtk::TreeModel::iterator& iter) const {
+    typename TypeHolderT::type value;
+    iter->get_value(boost::mpl::find<model_column::List,
+        TypeHolderT>::type::pos::value, value);
+    if (value > 0) cell->set_property("text", value);
+    else cell->set_property("text", Glib::ustring(""));
+  }
 };
+template <typename TypeHolderT>
+struct DoRenderCell<TypeHolderT, double> :
+  public std::binary_function<Gtk::CellRenderer*,
+    Gtk::TreeModel::iterator, void> {
+  void operator()(
+      Gtk::CellRenderer* cell,
+      const Gtk::TreeModel::iterator& iter) const {
+    typename TypeHolderT::type value;
+    iter->get_value(boost::mpl::find<model_column::List,
+        TypeHolderT>::type::pos::value, value);
+    if (value > 0) cell->set_property("text", value);
+    else cell->set_property("text", Glib::ustring(""));
+  }
+};
+
+template <typename TypeHolderT>
+struct RenderCell :
+  public DoRenderCell<TypeHolderT, typename TypeHolderT::type> {};
+
+} // anonymous namespace
 
-class Average: public Base {
+
+struct RenderCellStartTime :
+  public std::binary_function<Gtk::CellRenderer*,
+    Gtk::TreeModel::iterator, void> {
+  void operator()(
+      Gtk::CellRenderer* cell,
+      const Gtk::TreeModel::iterator& iter) const;
+};
+
+
+class StartTime: public ViewColumnBase<StartTime> {
 public:
-  Average();
-  virtual ~Average();
+  typedef RenderCellStartTime render_cell_functor;
+  typedef model_column::ID sort_model_column_type;
+  StartTime() : ViewColumnBase<StartTime>("Since") {
+    set_fixed_width(50);
+  }
+  virtual ~StartTime() {}
+  virtual std::string get_id() const { return "start_time"; };
+};
 
-private:
-  virtual void do_cell_data(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
+class Average: public ViewColumnBase<Average> {
+public:
+  typedef RenderCell<model_column::Average> render_cell_functor;
+  typedef model_column::Average sort_model_column_type;
+  Average() : ViewColumnBase<Average>("Average") {
+    set_fixed_width(50);
+  }
+  virtual ~Average() {}
+  virtual std::string get_id() const { return "average"; };
 };
 
 
-class Title: public Base {
+class Title: public ViewColumnBase<Title> {
 public:
-  Title();
-  virtual ~Title();
-private:
-  virtual void do_cell_data(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
+  typedef RenderCell<model_column::Title> render_cell_functor;
+  typedef model_column::Title sort_model_column_type;
+  Title() : ViewColumnBase<Title>("Title") {
+    set_fixed_width(200);
+  }
+  virtual ~Title() {}
+  virtual std::string get_id() const { return "title"; };
 };
 
 
-class ResNum: public Base {
+class ResNum: public ViewColumnBase<ResNum> {
 public:
-  ResNum();
-  virtual ~ResNum();
-private:
-  virtual void do_cell_data(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
+  typedef RenderCell<model_column::ResNum> render_cell_functor;
+  typedef model_column::ResNum sort_model_column_type;
+  ResNum() : ViewColumnBase<ResNum>("Res") {
+    set_fixed_width(30);
+  }
+  virtual ~ResNum() {}
+  virtual std::string get_id() const { return "res_num"; };
 };
 
 
-class Number: public Base {
+class Number: public ViewColumnBase<Number> {
 public:
-  Number();
-  virtual ~Number();
-private:
-  virtual void do_cell_data(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
+  typedef RenderCell<model_column::Number> render_cell_functor;
+  typedef model_column::Number sort_model_column_type;
+  Number() : ViewColumnBase<Number>("No.") {
+    set_fixed_width(30);
+  }
+  virtual ~Number() {}
+  virtual std::string get_id() const { return "number"; };
 };
 
-class LineCount: public Base {
+class LineCount: public ViewColumnBase<LineCount> {
 public:
-  LineCount();
-  virtual ~LineCount();
-private:
-  virtual void do_cell_data(Gtk::CellRenderer* cell,
-      const Gtk::TreeModel::iterator& iter);
+  typedef RenderCell<model_column::LineCount> render_cell_functor;
+  typedef model_column::LineCount sort_model_column_type;
+  LineCount() : ViewColumnBase<LineCount>("Read") {
+    set_fixed_width(30);
+  }
+  virtual ~LineCount() {}
+  virtual std::string get_id() const { return "line_count"; };
 };