/* Copyright (C) 1998-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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <gtkmm/container.h>
#include <gtkmm/orientable.h>
#include <gtkmm/enums.h>

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

namespace Gtk
{

/** A container which arranges its child widgets in rows and columns.
 * It is very similar to Box,
 * but it consistently uses Widget's margin and expand
 * properties instead of custom child properties, and it fully supports
 * height-for-width geometry management.
 *
 * Children are added using attach(). They can span multiple
 * rows or columns. It is also possible to add a child next to an
 * existing child, using attach_next_to(). The behaviour of
 * %Grid when several children occupy the same grid cell is undefined.
 *
 * %Grid can be used like a Box by just using Gtk::Container::add(),
 * which will place children next to each other in the direction determined
 * by the orientation property.
 *
 * @ingroup Widgets
 * @ingroup Containers
 *
 * @newin{3,0}
 */
class Grid
  : public Container,
    public Orientable
{
  _CLASS_GTKOBJECT(Grid, GtkGrid, GTK_GRID, Gtk::Container, GtkContainer)
  _IMPLEMENTS_INTERFACE(Orientable)
public:
  _CTOR_DEFAULT

  //TODO: Add a Grid(Orientation orientation = ORIENTATION_HORIZONTAL) constructor to match the Paned and Box ones?
  //Probably not, because a vertical GtkGrid is not very useful. murrayc.

  _WRAP_METHOD(void attach(Widget& child, int left, int top, int width = 1, int height = 1), gtk_grid_attach)

  /** Adds a widget to the grid.
   *
   * The widget is placed next to @a sibling, on the side determined by
   * @a side. The %attach_next_to() without the @a sibling parameter
   * places the widget in row 0 (for left or right placement) or column 0
   * (for top or bottom placement), at the end indicated by @a side.
   *
   * Attaching widgets labeled [1], [2], [3] without the @a sibling parameter and
   * @a side == Gtk::POS_LEFT yields a layout of [3][2][1].
   *
   * @param child The widget to add.
   * @param sibling The child of @a grid that @a child will be placed
   *        next to, or omitted to place @a child at the beginning or end.
   * @param side The side of @a sibling that @a child is positioned next to.
   * @param width The number of columns that @a child will span.
   * @param height The number of rows that @a child will span.
   */
  _WRAP_METHOD(void attach_next_to(Widget& child, Widget& sibling{?}, PositionType side, int width = 1, int height = 1), gtk_grid_attach_next_to)

  _WRAP_METHOD(Widget* get_child_at(int left, int top), gtk_grid_get_child_at)
  _WRAP_METHOD(const Widget* get_child_at(int left, int top) const, gtk_grid_get_child_at)
  _WRAP_METHOD(void insert_row(int position), gtk_grid_insert_row)
  _WRAP_METHOD(void insert_column(int position), gtk_grid_insert_column)
  _WRAP_METHOD(void remove_row(int position), gtk_grid_remove_row)
  _WRAP_METHOD(void remove_column(int position), gtk_grid_remove_column)
  _WRAP_METHOD(void insert_next_to(Widget& sibling, PositionType side), gtk_grid_insert_next_to)

  _WRAP_METHOD(void set_row_homogeneous(bool homogeneous = true), gtk_grid_set_row_homogeneous)
  _WRAP_METHOD(bool get_row_homogeneous() const, gtk_grid_get_row_homogeneous)
  _WRAP_METHOD(void set_row_spacing(guint spacing), gtk_grid_set_row_spacing)
  _WRAP_METHOD(guint get_row_spacing() const, gtk_grid_get_row_spacing)
  _WRAP_METHOD(void set_column_homogeneous(bool homogeneous), gtk_grid_set_column_homogeneous)
  _WRAP_METHOD(bool get_column_homogeneous() const, gtk_grid_get_column_homogeneous)
  _WRAP_METHOD(void set_column_spacing(guint spacing), gtk_grid_set_column_spacing)
  _WRAP_METHOD(guint get_column_spacing() const, gtk_grid_get_column_spacing)
  _WRAP_METHOD(void set_row_baseline_position(int row, BaselinePosition pos), gtk_grid_set_row_baseline_position)
  _WRAP_METHOD(BaselinePosition get_row_baseline_position(int row) const, gtk_grid_get_row_baseline_position)
  _WRAP_METHOD(void set_baseline_row(int row), gtk_grid_set_baseline_row)
  _WRAP_METHOD(int get_baseline_row() const, gtk_grid_get_baseline_row)

  _WRAP_PROPERTY("row-spacing", guint)
  _WRAP_PROPERTY("column-spacing", guint)
  _WRAP_PROPERTY("row-homogeneous", bool)
  _WRAP_PROPERTY("column-homogeneous", bool)
  _WRAP_PROPERTY("baseline-row", int)

  _WRAP_CHILD_PROPERTY("left-attach", int)
  _WRAP_CHILD_PROPERTY("top-attach", int)
  _WRAP_CHILD_PROPERTY("width", int)
  _WRAP_CHILD_PROPERTY("height", int)
};

} // namespace Gtk
