/* Copyright (C) 2002 The gtkmm Development Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or(at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
*/

// This is for including the config header before any code (such as
// the #ifndef GTKMM_DISABLE_DEPRECATED in deprecated classes) is generated:
_CONFIGINCLUDE(gtkmmconfig.h)

#include <gtkmm/treeiter.h>
#include <gtkmm/button.h>
#include <gtkmm/treemodel.h>
#include <gtkmm/celllayout.h>
#include <gtkmm/buildable.h>
#include <gtkmm/cellrenderer_generation.h>

_DEFS(gtkmm,gtk)
_PINCLUDE(gtkmm/private/object_p.h)

#m4 _PUSH(SECTION_CC_PRE_INCLUDES)
#undef GTK_DISABLE_DEPRECATED
#define GDK_DISABLE_DEPRECATION_WARNINGS 1
#m4 _POP()

_IS_DEPRECATED // The entire file is deprecated.

namespace Gtk
{

_CC_INCLUDE(gtk/gtk.h)

// We use GTKMM_API here because gcc needs the extra help on win32 , even
// when using --export-all and auto-import.
// See http://bugzilla.gnome.org/show_bug.cgi?id=309030.

class CellArea;
class TreeView;

/** Typedefed as Gtk::TreeView::Column.
 * This is a visible column in a Gtk::TreeView widget. It determines the geometry, type.
 *
 * @ingroup TreeView
 * @deprecated 4.10: Use Gtk::ColumnView and Gtk::ColumnViewColumn
 *   instead of Gtk::TreeView to show a tabular list.
 */
class GTKMM_API TreeViewColumn
: public Object,
  public CellLayout,
  public Buildable
{
  _CLASS_GTKOBJECT(TreeViewColumn, GtkTreeViewColumn, GTK_TREE_VIEW_COLUMN, Object, GObject, , , GTKMM_API)
  _IMPLEMENTS_INTERFACE(CellLayout)
  _IMPLEMENTS_INTERFACE(Buildable)
  _IGNORE(gtk_tree_view_column_set_cell_data_func)

public:
_WRAP_ENUM(Sizing, GtkTreeViewColumnSizing, decl_prefix GTKMM_API)

typedef TreeViewColumn Column;

_CTOR_DEFAULT()

explicit TreeViewColumn(const Glib::ustring& title);
TreeViewColumn(const Glib::ustring& title, CellRenderer& cell);

/** Create a default view column for the given model column type.
 */
template<class T_ModelColumnType>
TreeViewColumn(const Glib::ustring& title, const TreeModelColumn<T_ModelColumnType>& column);

_WRAP_METHOD(void pack_start(CellRenderer& cell, bool expand = true), gtk_tree_view_column_pack_start)
_WRAP_METHOD(void pack_end(CellRenderer& cell, bool expand = true), gtk_tree_view_column_pack_end)

/** Creates an appropriate CellRenderer for the @a column, and packs that cell into the beginning of the column.
 * If @a expand  is <tt>false</tt>, then
 * the cell is allocated no more space than it needs. Any unused space is divided
 * evenly between cells for which @a expand is <tt>true</tt>.
 *
 * You can use get_first_cell() or get_cells() to access the generated CellRenderer.
 *
 * @param column The model column that will be rendered by the view cell.
 * @param expand <tt>true</tt> if the cell is to be given extra space allocated to the view column.
 */
template<class T_ModelColumnType>
void pack_start(const TreeModelColumn<T_ModelColumnType>& column, bool expand = true);

/** Creates an appropriate CellRenderer for the @a column, and packs that cell at the end of the column.
 * If @a expand  is <tt>false</tt>, then
 * the cell is allocated no more space than it needs. Any unused space is divided
 * evenly between cells for which @a expand is <tt>true</tt>.
 *
 * You can use get_first_cell() or get_cells() to access the generated CellRenderer.
 *
 * @param column The model column that will be rendered by the view cell.
 * @param expand <tt>true</tt> if the cell is to be given extra space allocated to the view column.
 */
template<class T_ModelColumnType>
void pack_end(const TreeModelColumn<T_ModelColumnType>& column, bool expand = true);

_WRAP_METHOD(void clear(), gtk_tree_view_column_clear)

_WRAP_METHOD(void add_attribute(CellRenderer& cell_renderer, const Glib::ustring& attribute, int column),
             gtk_tree_view_column_add_attribute)

void add_attribute(const Glib::PropertyProxy_Base& property, const TreeModelColumnBase& column);

void add_attribute(Gtk::CellRenderer& cell, const Glib::ustring& property_name, const TreeModelColumnBase& column);
_IGNORE(gtk_tree_view_column_set_attributes)

/** Associate a view CellRenderer with a model column, so that the CellRenderer renders the data in the model column.
 *
 * @param renderer The view cell renderer which will render the model column.
 * @param column The model column to be renderered by this view.
 */
void set_renderer(Gtk::CellRenderer& renderer, const TreeModelColumnBase& column);

// _WRAP_METHOD(void set_attributes(CellRenderer& cell_renderer, ...), )

  /** For instance,
   * void on_cell_data(Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
   *
   * This function is used instead of the standard attributes mapping for setting the column value, and should set the
   * value of the column's cell renderer as appropriate.
   */
  typedef sigc::slot<void(CellRenderer*, const Gtk::TreeModel::const_iterator&)> SlotTreeCellData;

  /** Sets the slot callback to use for the column.
   * This callback function is used instead of the standard attributes mapping for setting the column value, and should set the
   * value of the column's cell renderer as appropriate.
   *
   * See also unset_cell_data_func().
   *
   * @param cell_renderer A Gtk::CellRenderer
   * @param slot The callback slot to use. Create this with sigc::mem_fun(), or sigc::ptr_fun().
   */
  void set_cell_data_func(CellRenderer& cell_renderer, const SlotTreeCellData& slot);

  /** Removes a previously set callback slot. See set_cell_data_func().
   */
  void unset_cell_data_func(CellRenderer& cell_renderer);

  _WRAP_METHOD(void clear_attributes(CellRenderer& cell_renderer), gtk_tree_view_column_clear_attributes)
  _WRAP_METHOD(void set_spacing(int spacing), gtk_tree_view_column_set_spacing)
  _WRAP_METHOD(int get_spacing() const, gtk_tree_view_column_get_spacing)
  _WRAP_METHOD(void set_visible(bool visible = true), gtk_tree_view_column_set_visible)
  _WRAP_METHOD(bool get_visible() const, gtk_tree_view_column_get_visible)
  _WRAP_METHOD(void set_resizable(bool resizable = true), gtk_tree_view_column_set_resizable)
  _WRAP_METHOD(bool get_resizable() const, gtk_tree_view_column_get_resizable)
  _WRAP_METHOD(void set_sizing(Sizing type), gtk_tree_view_column_set_sizing)
  _WRAP_METHOD(Sizing get_sizing(), gtk_tree_view_column_get_sizing)
  _WRAP_METHOD(int get_x_offset() const, gtk_tree_view_column_get_x_offset)
  _WRAP_METHOD(int get_width() const, gtk_tree_view_column_get_width)
  _WRAP_METHOD(int get_fixed_width() const, gtk_tree_view_column_get_fixed_width)
  _WRAP_METHOD(void set_fixed_width(int fixed_width), gtk_tree_view_column_set_fixed_width)
  _WRAP_METHOD(void set_min_width(int min_width), gtk_tree_view_column_set_min_width)
  _WRAP_METHOD(int get_min_width() const, gtk_tree_view_column_get_min_width)
  _WRAP_METHOD(void set_max_width(int max_width), gtk_tree_view_column_set_max_width)
  _WRAP_METHOD(int get_max_width() const, gtk_tree_view_column_get_max_width)
  _WRAP_METHOD(void clicked(), gtk_tree_view_column_clicked)

  _WRAP_METHOD(void set_title(const Glib::ustring& title), gtk_tree_view_column_set_title)
  _WRAP_METHOD(Glib::ustring get_title() const, gtk_tree_view_column_get_title)

  _WRAP_METHOD(void set_expand(bool expand = true), gtk_tree_view_column_set_expand)
  _WRAP_METHOD(bool get_expand() const, gtk_tree_view_column_get_expand)

  _WRAP_METHOD(void set_clickable(bool clickable = true), gtk_tree_view_column_set_clickable)
  _WRAP_METHOD(bool get_clickable() const, gtk_tree_view_column_get_clickable)
  _WRAP_METHOD(void set_widget(Gtk::Widget& widget), gtk_tree_view_column_set_widget)
  _WRAP_METHOD(Widget* get_widget(), gtk_tree_view_column_get_widget)
  _WRAP_METHOD(const Widget* get_widget() const, gtk_tree_view_column_get_widget)

  _WRAP_METHOD(void set_alignment(float xalign), gtk_tree_view_column_set_alignment)
  _WRAP_METHOD(void set_alignment(Align xalign), gtk_tree_view_column_set_alignment)

  _WRAP_METHOD(float get_alignment() const, gtk_tree_view_column_get_alignment)
  _WRAP_METHOD(void set_reorderable(bool reorderable = true), gtk_tree_view_column_set_reorderable)
  _WRAP_METHOD(bool get_reorderable() const, gtk_tree_view_column_get_reorderable)

  _WRAP_METHOD(void set_sort_column(const TreeModelColumnBase& sort_column_id), gtk_tree_view_column_set_sort_column_id)
  _WRAP_METHOD(void set_sort_column(int sort_column_id), gtk_tree_view_column_set_sort_column_id)

  _WRAP_METHOD(int get_sort_column_id() const, gtk_tree_view_column_get_sort_column_id)
  _WRAP_METHOD(void set_sort_indicator(bool setting), gtk_tree_view_column_set_sort_indicator)
  _WRAP_METHOD(bool get_sort_indicator() const, gtk_tree_view_column_get_sort_indicator)
  _WRAP_METHOD(void set_sort_order(SortType order), gtk_tree_view_column_set_sort_order)
  _WRAP_METHOD(SortType get_sort_order() const, gtk_tree_view_column_get_sort_order)

  _WRAP_METHOD(void cell_set_cell_data(const Glib::RefPtr<TreeModel>& tree_model, const TreeModel::iterator& iter, bool is_expander, bool is_expanded), gtk_tree_view_column_cell_set_cell_data)

  _WRAP_METHOD(void cell_get_size(int& x_offset, int& y_offset, int& width, int& height) const, gtk_tree_view_column_cell_get_size)

  _WRAP_METHOD(bool cell_is_visible() const, gtk_tree_view_column_cell_is_visible)
  _WRAP_METHOD(void focus_cell(CellRenderer& cell), gtk_tree_view_column_focus_cell)

  _WRAP_METHOD(bool get_cell_position(const CellRenderer& cell_renderer, int& start_pos, int& width) const, gtk_tree_view_column_cell_get_position)
  _WRAP_METHOD(void queue_resize(), gtk_tree_view_column_queue_resize)

  _WRAP_METHOD(TreeView* get_tree_view(), gtk_tree_view_column_get_tree_view, refreturn)
  _WRAP_METHOD(const TreeView* get_tree_view() const, gtk_tree_view_column_get_tree_view, refreturn, constversion)

  _WRAP_METHOD(Button* get_button(), gtk_tree_view_column_get_button, refreturn)
  _WRAP_METHOD(const Button* get_button() const, gtk_tree_view_column_get_button, refreturn, constversion)

  // no_default_handler because GtkTreeViewColumnClass is private.
  _WRAP_SIGNAL(void clicked(), "clicked", no_default_handler)

  _WRAP_PROPERTY("visible", bool)
  _WRAP_PROPERTY("resizable", bool)
  _WRAP_PROPERTY("x-offset", int)
  _WRAP_PROPERTY("width", int)
  _WRAP_PROPERTY("spacing", int)
  _WRAP_PROPERTY("sizing", Sizing)
  _WRAP_PROPERTY("fixed-width", int)
  _WRAP_PROPERTY("min-width", int)
  _WRAP_PROPERTY("max-width", int)
  _WRAP_PROPERTY("title", Glib::ustring)
  _WRAP_PROPERTY("expand", bool)
  _WRAP_PROPERTY("clickable", bool)
  _WRAP_PROPERTY("widget", Widget*)
  _WRAP_PROPERTY("alignment", float)
  _WRAP_PROPERTY("reorderable", bool)
  _WRAP_PROPERTY("sort-indicator", bool)
  _WRAP_PROPERTY("sort-order", SortType)
  _WRAP_PROPERTY("sort-column-id", int)
  _WRAP_PROPERTY("cell-area", Glib::RefPtr<CellArea>)

#ifndef DOXYGEN_SHOULD_SKIP_THIS
private:
  // Only necessary because of the templated ctor, see below.
  static const Glib::Class& class_init_();
#endif //DOXYGEN_SHOULD_SKIP_THIS
};

#ifndef DOXYGEN_SHOULD_SKIP_THIS

template<class T_ModelColumnType> inline
void TreeViewColumn::pack_start(const TreeModelColumn<T_ModelColumnType>& column, bool expand)
{
  //Generate appropriate Renderer for the column:
  CellRenderer* pCellRenderer = manage( CellRenderer_Generation::generate_cellrenderer<T_ModelColumnType>() );

  //Use the renderer:
  pack_start(*pCellRenderer, expand);
  set_renderer(*pCellRenderer, column);
}

template<class T_ModelColumnType> inline
void TreeViewColumn::pack_end(const TreeModelColumn<T_ModelColumnType>& column, bool expand)
{
  //Generate appropriate Renderer for the column:
  CellRenderer* pCellRenderer= manage( CellRenderer_Generation::generate_cellrenderer<T_ModelColumnType>() );

  //Use the renderer:
  pack_end(*pCellRenderer, expand);
  set_renderer(*pCellRenderer, column);
}

template <class T_ModelColumnType> inline
TreeViewColumn::TreeViewColumn(const Glib::ustring& title,
                               const TreeModelColumn<T_ModelColumnType>& column)
:
  Glib::ObjectBase(nullptr), // not (yet) a custom class
  Gtk::Object(Glib::ConstructParams(class_init_(), "title", title.c_str(), nullptr))
{
  pack_start(column, true /* expand */);
}

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

} // namespace Gtk
