// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _GTKMM_BOX_H
#define _GTKMM_BOX_H


#include <glibmm.h>

/* $Id: box.hg,v 1.10 2006/01/28 18:49:13 jjongsma Exp $ */

/* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


// Temporarily undef GTK_DISABLE_DEPRECATED, redefining it later if appropriate.
// We need this to use _GtkBoxChild, which we use in our (deprecated) API.
#if defined(GTK_DISABLE_DEPRECATED) && !defined(GTKMM_GTK_DISABLE_DEPRECATED_UNDEFED)
#undef GTK_DISABLE_DEPRECATED
#define GTKMM_GTK_DISABLE_DEPRECATED_UNDEFED 1
#endif

// This is needed for gdkregion.h, for GdkSpanFunc, which we indirectly include.
// Otherwise application code must be very careful of the include order.
#if defined(GDK_DISABLE_DEPRECATED) && !defined(GTKMM_GDK_DISABLE_DEPRECATED_UNDEFED)
#undef GDK_DISABLE_DEPRECATED
#define GTKMM_GDK_DISABLE_DEPRECATED_UNDEFED 1
#endif

#include <gtk/gtk.h>  /* For _GtkBoxChild */

// Redefine GTK_DISABLE_DEPRECATED if it was defined before we temporarily undefed it:
#if defined(GTKMM_GTK_DISABLE_DEPRECATED_UNDEFED)
#define GTK_DISABLE_DEPRECATED 1
#undef GTKMM_GTK_DISABLE_DEPRECATED_UNDEFED
#endif

// Redefine GDK_DISABLE_DEPRECATED if it was defined before we temporarily undefed it:
#if defined(GTKMM_GDK_DISABLE_DEPRECATED_UNDEFED)
#define GDK_DISABLE_DEPRECATED 1
#undef GTKMM_GDK_DISABLE_DEPRECATED_UNDEFED
#endif


#include <gtkmm/container.h>
#include <glibmm/helperlist.h>

#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GtkBox GtkBox;
typedef struct _GtkBoxClass GtkBoxClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gtk
{ class Box_Class; } // namespace Gtk
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GtkVBox GtkVBox;
typedef struct _GtkVBoxClass GtkVBoxClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gtk
{ class VBox_Class; } // namespace Gtk
#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GtkHBox GtkHBox;
typedef struct _GtkHBoxClass GtkHBoxClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gtk
{ class HBox_Class; } // namespace Gtk
namespace Gtk
{

/** Packing options for adding child widgets to a Box with pack_start() and pack_end().
 * @ingroup gtkmmEnums
 */
enum PackOptions
{
  PACK_SHRINK, /**< Space is contracted to the child widget size. */
  PACK_EXPAND_PADDING, /**< Space is expanded, with extra space filled with padding. */
  PACK_EXPAND_WIDGET /**< Space is expanded, with extra space filled by increasing the child widget size. */
};

class Box;

namespace Box_Helpers
{

//This may not have any data or virtual functions. See below.
class Child : protected _GtkBoxChild
{
private:
  Child& operator=(const Child&); //Not implemented.
  Child(const Child&); //Not implemented.

public:
  /// Provides access to the underlying C GObject.
  inline _GtkBoxChild* gobj() { return this; }
  /// Provides access to the underlying C GObject.
  inline const _GtkBoxChild* gobj() const { return this; }

  Widget* get_widget() const;

  inline guint16 get_padding() const   { return (gobj()->padding); }
  inline bool get_expand() const       { return (gobj()->expand); }
  inline bool get_fill() const         { return (gobj()->fill); }
  inline bool get_pack() const         { return (gobj()->pack); }

  void set_options(PackOptions options, guint padding = 0);
  void set_options(bool expand, bool fill, guint padding = 0);

  void set_pack(PackType pack);

protected:
  inline GtkBox* parent()
    { return (GtkBox*) (gtk_widget_get_parent(gobj()->widget)); }

  void redraw();

#ifndef DOXYGEN_SHOULD_SKIP_THIS
  friend class Dummy_; // silence the compiler (Child has only private ctors)
#endif
};

class Element
{
public:
 Element(Widget& widget,
          PackOptions options = PACK_EXPAND_WIDGET,
          guint padding = 0,
          PackType pack = PACK_START)
      : widget_(&widget), options_(options),
        padding_(padding), pack_(pack)
    {}

  Widget* widget_;
  PackOptions options_;
  guint padding_;
  PackType pack_;
};

typedef Element StartElem;

struct EndElem : public Element
{
  EndElem(Widget& widget,
          PackOptions options = PACK_EXPAND_WIDGET,
          guint padding = 0)
      : Element (widget, options, padding, PACK_END)
    {}
};

 
class BoxList : public Glib::HelperList< Child, const Element, Glib::List_Iterator< Child > >
{
public:
  BoxList();
  explicit BoxList(GtkBox* gparent);
  BoxList(const BoxList& src);
  virtual ~BoxList() {}

  BoxList& operator=(const BoxList& src);

  typedef Glib::HelperList< Child, const Element,  Glib::List_Iterator< Child > > type_base;

  GtkBox* gparent();
  const GtkBox* gparent() const;

  virtual GList*& glist() const;      // front of list

  virtual void erase(iterator start, iterator stop);
  virtual iterator erase(iterator);  //Implented as custom or by LIST_CONTAINER_REMOVE
  virtual void remove(const_reference); //Implented as custom or by LIST_CONTAINER_REMOVE

  /// This is order n. (use at own risk)
  reference operator[](size_type l) const;

public:
  iterator insert(iterator position, element_type& e); //custom-implemented.

  template <class InputIterator>
  inline void insert(iterator position, InputIterator first, InputIterator last)
  {
    for(;first != last; ++first)
      position = insert(position, *first);
  }

 inline void push_front(element_type& e)
    { insert(begin(), e); }
  inline void push_back(element_type& e)
    { insert(end(), e); }


  //The standard iterator, instead of List_Cpp_Iterator,
  //only works because Child is derived from _GtkBoxChild.

  
  iterator find(const_reference c);
  iterator find(Widget&);

  
virtual void remove(Widget& w); //Implented as custom or by LIST_CONTAINER_REMOVE

        // Non-standard
        void reorder(iterator loc,iterator pos);
  };


} /* namespace Box_Helpers */


//TODO: Inherit/Implement Orientation when we can break ABI.

/** A base class for box containers.
 *
 * Abstract base class for horizontal and vertical boxes, which organize a
 * variable number of widgets into a rectangular area.  This is an abstract
 * class and it defers choice of which way the widgets are packed to the screen
 * to the derived classes.  It provides a common interface for inserting
 * widgets to a box indepenently of how it is shown in the screen.
 *
 * Gtk::Box uses a notion of packing. Packing refers to adding widgets with
 * reference to a particular position in a Gtk::Container. There are two
 * reference positions: the start and the end of the box. For a VBox, the start
 * is defined as the top of the box and the end is defined as the bottom.  For
 * a HBox the start is defined as the left side and the end is defined as the
 * right side.  Use repeated calls to pack_start() to pack widgets into a
 * Gtk::Box from start to end. Use pack_end() to add widgets from end to start.
 * You may intersperse these calls and add widgets from both ends of the same
 * Gtk::Box. The last widget added with pack_start() will be placed just before
 * the last widget added with pack_end()
 *
 * Because Gtk::Box is a Gtk::Container, you may also use Gtk::Container::add()
 * to insert widgets, and they will be packed as if with pack_start(). Use
 * Gtk::Container::remove() to remove widgets.
 *
 * Use set_homogeneous() to specify whether or not all children of the Gtk::Box
 * occupy the same amount of space.  Use set_spacing() to determine the minimum
 * space placed between all children in the Gtk::Box.  Use reorder_child() to
 * move a child widget to a different place in the box.  Use
 * set_child_packing() to reset the pack options and padding attributes of any
 * Gtk::Box child. Use query_child_packing() to query these fields.
 */

class Box : public Container
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef Box CppObjectType;
  typedef Box_Class CppClassType;
  typedef GtkBox BaseObjectType;
  typedef GtkBoxClass BaseClassType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  virtual ~Box();

#ifndef DOXYGEN_SHOULD_SKIP_THIS

private:
  friend class Box_Class;
  static CppClassType box_class_;

  // noncopyable
  Box(const Box&);
  Box& operator=(const Box&);

protected:
  explicit Box(const Glib::ConstructParams& construct_params);
  explicit Box(GtkBox* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;


  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GtkObject.
  GtkBox*       gobj()       { return reinterpret_cast<GtkBox*>(gobject_); }

  ///Provides access to the underlying C GtkObject.
  const GtkBox* gobj() const { return reinterpret_cast<GtkBox*>(gobject_); }


public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::


private:

  
public:
  typedef Box_Helpers::BoxList BoxList;

protected:
  Box();
public:

  
  /** Left side insert a widget to a box.
   * The expand argument to pack_start() or pack_end()
   * controls whether the widgets are laid out in the box to fill in all
   * the extra space in the box so the box is expanded to fill the area
   * allocated to it (<tt>true</tt>). Or the box is shrunk to just fit the widgets
   * (<tt>false</tt>).  Setting @a expand to <tt>false</tt> will allow you to do right and left
   * justifying of your widgets.  Otherwise, they will all expand to fit in
   * the box, and the same effect could be achieved by using only one of
   * pack_start() or pack_end() functions.
   * 
   * The @a fill argument to the pack_start()/pack_end() functions control whether the
   * extra space is allocated to the objects themselves (<tt>true</tt>), or as extra
   * padding in the box around these objects (<tt>false</tt>). It only has an effect
   * if the @a expand argument is also <tt>true</tt>.
   * 
   * The difference between spacing (set when the box is created)
   * and padding (set when elements are packed) is, that spacing is added between
   * objects, and padding is added on either side of an object.
   * @param child The Gtk::Widget to be added to @a box.
   * @param expand <tt>true</tt> if the new child is to be given extra space allocated to
   *  @a box.  The extra space will be divided evenly between all children of
   *  @a box that use this option.
   * @param fill <tt>true</tt> if space given to @a child by the @a expand option is
   * actually allocated to @a child, rather than just padding it.  This
   * parameter has no effect if @a expand is set to <tt>false</tt>.  A child is
   * always allocated the full height of a Gtk::HBox and the full width 
   * of a Gtk::VBox. This option affects the other dimension.
   * @param padding Extra space in pixels to put between this child and its
   * neighbors, over and above the global amount specified by
   * Gtk::Box:spacing property.  If @a child is a widget at one of the 
   * reference ends of @a box, then @a padding pixels are also put between 
   *  @a child and the reference edge of @a box.
   */
  void pack_start(Widget& child, bool expand, bool fill, guint padding =  0);

  /** Left side insert a widget to a box.
   * @param child A Widget to be added to box.
   * @param options Controls how the widget expands to fill space, and how the space around them is used.
   * @param padding Padding that is added on either side of the widget. This is different to spacing set when the box is created (or with set_spacing()) - spacing is added between objects, and padding is added on either side of an object.
   */
  void pack_start(Widget& child, PackOptions options = PACK_EXPAND_WIDGET, guint padding = 0);

  
  /** Adds @a child to @a box, packed with reference to the end of @a box.  
   * The @a child is packed after (away from end of) any other child 
   * packed with reference to the end of @a box.
   * @param child The Gtk::Widget to be added to @a box.
   * @param expand <tt>true</tt> if the new child is to be given extra space allocated 
   * to @a box. The extra space will be divided evenly between all children 
   * of @a box that use this option.
   * @param fill <tt>true</tt> if space given to @a child by the @a expand option is
   * actually allocated to @a child, rather than just padding it.  This
   * parameter has no effect if @a expand is set to <tt>false</tt>.  A child is
   * always allocated the full height of a Gtk::HBox and the full width 
   * of a Gtk::VBox.  This option affects the other dimension.
   * @param padding Extra space in pixels to put between this child and its
   * neighbors, over and above the global amount specified by
   * Gtk::Box:spacing property.  If @a child is a widget at one of the 
   * reference ends of @a box, then @a padding pixels are also put between 
   *  @a child and the reference edge of @a box.
   */
  void pack_end(Widget& child, bool expand, bool fill, guint padding =  0);

  /** Right side insert a widget to a box.
   * @param child A Widget to be added to box.
   * @param options Controls how the widget expands to fill space, and how the space around them is used.
   * @param padding Padding that is added on either side of the widget. This is different to spacing set when the box is created (or with set_spacing()) - spacing is added between objects, and padding is added on either side of an object.
   */
  void pack_end(Widget& child, PackOptions options = PACK_EXPAND_WIDGET, guint padding = 0);

  
  /** Sets the Gtk::Box:homogeneous property of @a box, controlling 
   * whether or not all children of @a box are given equal space 
   * in the box.
   * @param homogeneous A boolean value, <tt>true</tt> to create equal allotments,
   * <tt>false</tt> for variable allotments.
   */
  void set_homogeneous(bool homogeneous =  true);
  
  /** Returns whether the box is homogeneous (all children are the
   * same size). See set_homogeneous().
   * @return <tt>true</tt> if the box is homogeneous.
   */
  bool get_homogeneous() const;

  
  /** Sets the Gtk::Box:spacing property of @a box, which is the 
   * number of pixels to place between children of @a box.
   * @param spacing The number of pixels to put between children.
   */
  void set_spacing(int spacing);
  
  /** Gets the value set by set_spacing().
   * @return Spacing between children.
   */
  int get_spacing() const;

  
  /** Moves @a child to a new @a position in the list of @a box children.  
   * The list is the <structfield>children</structfield> field of
   * Gtk::Box-struct, and contains both widgets packed Gtk::PACK_START 
   * as well as widgets packed Gtk::PACK_END, in the order that these 
   * widgets were added to @a box.
   * 
   * A widget's position in the @a box children list determines where 
   * the widget is packed into @a box.  A child widget at some position 
   * in the list will be packed just after all other widgets of the 
   * same packing type that appear earlier in the list.
   * @param child The Gtk::Widget to move.
   * @param position The new position for @a child in the list of children 
   * of @a box, starting from 0. If negative, indicates the end of 
   * the list.
   */
  void reorder_child(Widget& child, int pos);

  /* Get the child widgets.
   * @result An STL-style container of pointers to the box's child widgets.
   */
  BoxList& children();

  /* Get the child widgets.
   * @result An STL-style container of pointers to the box's child widgets.
   */
  const BoxList& children() const;

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The amount of space between children.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy<int> property_spacing() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** The amount of space between children.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<int> property_spacing() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Whether the children should all be the same size.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy<bool> property_homogeneous() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Whether the children should all be the same size.
   *
   * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
   * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
   * the value of the property changes.
   */
  Glib::PropertyProxy_ReadOnly<bool> property_homogeneous() const;
#endif //#GLIBMM_PROPERTIES_ENABLED


protected:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  mutable BoxList children_proxy_;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


};


/** Vertical Box for laying widgets in a vertical row.
 *
 * You should create these objects, but it is more confortable to pass
 * around pointers of Gtk::Box. All the methods that do anything are in
 * class Gtk::Box and this allows you to later change the direction of the
 * box, when there's no dependencies to HBox and VBox classes.
 *
 * @ingroup Widgets
 * @ingroup Containers
 */

class VBox : public Box
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef VBox CppObjectType;
  typedef VBox_Class CppClassType;
  typedef GtkVBox BaseObjectType;
  typedef GtkVBoxClass BaseClassType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  virtual ~VBox();

#ifndef DOXYGEN_SHOULD_SKIP_THIS

private:
  friend class VBox_Class;
  static CppClassType vbox_class_;

  // noncopyable
  VBox(const VBox&);
  VBox& operator=(const VBox&);

protected:
  explicit VBox(const Glib::ConstructParams& construct_params);
  explicit VBox(GtkVBox* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;


  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GtkObject.
  GtkVBox*       gobj()       { return reinterpret_cast<GtkVBox*>(gobject_); }

  ///Provides access to the underlying C GtkObject.
  const GtkVBox* gobj() const { return reinterpret_cast<GtkVBox*>(gobject_); }


public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::


private:

public:

  /** Creates a new vertical box.
   * @param homogeneous Whether each widget in the VBox should have the same
   * height.  If set, a PACK_SHRINK argument to pack_start() or pack_end() is
   * ignored.
   * @param spacing Determines the space in pixels between child widgets.
   */
    explicit VBox(bool homogeneous =  false, int spacing =  0);


};

/** Horizontal Box for laying widgets in a horizontal row.
 *
 * You should create these objects, but it is more confortable to pass
 * around pointers of Gtk::Box. All the methods that do anything are in
 * class Gtk::Box and this allows you to later change the direction of the
 * box, when there's no dependencies to HBox and VBox classes.
 *
 * Use the Gtk::Box packing interface to determine the arrangement, spacing,
 * width, and alignment of Gtk::HBox children.
 *
 * All children are allocated the same height.
 *
 * @ingroup Widgets
 * @ingroup Containers
 */

class HBox : public Box
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef HBox CppObjectType;
  typedef HBox_Class CppClassType;
  typedef GtkHBox BaseObjectType;
  typedef GtkHBoxClass BaseClassType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  virtual ~HBox();

#ifndef DOXYGEN_SHOULD_SKIP_THIS

private:
  friend class HBox_Class;
  static CppClassType hbox_class_;

  // noncopyable
  HBox(const HBox&);
  HBox& operator=(const HBox&);

protected:
  explicit HBox(const Glib::ConstructParams& construct_params);
  explicit HBox(GtkHBox* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;


  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GtkObject.
  GtkHBox*       gobj()       { return reinterpret_cast<GtkHBox*>(gobject_); }

  ///Provides access to the underlying C GtkObject.
  const GtkHBox* gobj() const { return reinterpret_cast<GtkHBox*>(gobject_); }


public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::


private:

public:

  /** Creates a new horizontal box.
   * @param homogeneous Whether each widget in the HBox should have the same
   * width.  If set, a PACK_SHRINK argument to pack_start() or pack_end() is
   * ignored.
   * @param spacing Determines the space in pixels between child widgets.
   */
    explicit HBox(bool homogeneous =  false, int spacing =  0);


};

} // namespace Gtk


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gtk::Box
   */
  Gtk::Box* wrap(GtkBox* object, bool take_copy = false);
} //namespace Glib


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gtk::VBox
   */
  Gtk::VBox* wrap(GtkVBox* object, bool take_copy = false);
} //namespace Glib


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gtk::HBox
   */
  Gtk::HBox* wrap(GtkHBox* object, bool take_copy = false);
} //namespace Glib


#endif /* _GTKMM_BOX_H */

