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


#include <glibmm.h>

/* $Id: container.hg,v 1.11 2006/04/12 11:11:25 murrayc 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.
 */
 
#include <glibmm/listhandle.h>
#include <gtkmm/widget.h>


/** @defgroup Containers Container Widgets
 * These widgets can be used to group other widgets together.
 */

/* we'll include gtkfeatures because we dont want to include the whole
   gtk/gtk.h - this file is used by almost ALL our widgets, so dependencies
   in minimum - adding things here will increase compile times ALOT */


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _GtkContainer GtkContainer;
typedef struct _GtkContainerClass GtkContainerClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Gtk
{ class Container_Class; } // namespace Gtk
namespace Gtk
{

class Adjustment;
class Label;

/** Abstract container class
 *
 * This is the abstract container from which all gtk+ widgets which hold
 * other items derive from.  It mainly houses virtual functions
 * used for inserting and removing children.  Containers in gtk+
 * may hold one item or many items depending on the implementation.
 *
 * This interface is used for all single item holding containers.
 * Multi-item containers provide their own unique interface as their
 * items are generally more complex.  The methods of the derived
 * classes should be prefered over these.
 *
 * @ingroup Widgets
 */

class Container : public Widget
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  typedef Container CppObjectType;
  typedef Container_Class CppClassType;
  typedef GtkContainer BaseObjectType;
  typedef GtkContainerClass BaseClassType;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

  virtual ~Container();

#ifndef DOXYGEN_SHOULD_SKIP_THIS

private:
  friend class Container_Class;
  static CppClassType container_class_;

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

protected:
  explicit Container(const Glib::ConstructParams& construct_params);
  explicit Container(GtkContainer* 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.
  GtkContainer*       gobj()       { return reinterpret_cast<GtkContainer*>(gobject_); }

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


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

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

  //Default Signal Handlers::
  virtual void on_add(Widget* widget);
  virtual void on_remove(Widget* widget);
  virtual void on_check_resize();
  virtual void on_set_focus_child(Widget* widget);


private:

  
public:

/* Application-level methods */

  
  /** Sets the border width of the container.
   * 
   * The border width of a container is the amount of space to leave
   * around the outside of the container. The only exception to this is
   * Gtk::Window; because toplevel windows can't leave space outside,
   * they leave the space inside. The border is added on all sides of
   * the container. To add space to only one side, one approach is to
   * create a Gtk::Alignment widget, call Gtk::Widget::set_size_request()
   * to give it a size, and place it on the side of the container as
   * a spacer.
   * @param border_width Amount of blank space to leave <em>outside</em> 
   * the container. Valid values are in the range 0-65535 pixels.
   */
  void set_border_width(guint border_width);

  
  /** Retrieves the border width of the container. See
   * set_border_width().
   * @return The current border width.
   */
  guint get_border_width() const;

  //This is virtual so that we can override it in Gtk::ScrolledWindow:
 virtual void add(Widget& widget);
  

  /** Removes @a widget from @a container. @a widget must be inside @a container.
   * If @a widget is managed with Gtk::manage(), and you don't want to use @a widget
   * again then you should delete @a widget, because there will no longer be any parent 
   * container to delete it automatically.
   * @param widget A current child of @a container.
   */

  void remove(Widget& widget);
  

  /** Sets the resize mode for the container.
   * 
   * The resize mode of a container determines whether a resize request 
   * will be passed to the container's parent, queued for later execution
   * or executed immediately.
   * @param resize_mode The new resize mode.
   */
  void set_resize_mode(ResizeMode resize_mode);

  
  /** Returns the resize mode for the container. See
   * set_resize_mode().
   * @return The current resize mode.
   */
  ResizeMode get_resize_mode() const;


  /** Request that contained widgets check their size
   */
  void check_resize();

  /** For instance, 
   * void on_foreach(Gtk::Widget* widget);
   */
  typedef sigc::slot<void, Widget&> ForeachSlot;

  /** Operate on contained items
   * This is largely an internal used mainly for things like
   * creating duplicates of internal lists and other such
   * operations.  The result is lossy as it only gets the
   * the main child and not its external pieces.
   *
   * For example notebook pages contain a page, a label, and
   * a menu item.  But this only operates on the pages.
   */
  void foreach(const ForeachSlot& slot);

  /// (internal) Operate on contained items (see foreach())
  //_WRAP_METHOD(void foreach_(GtkCallback callback,gpointer data),gtk_container_foreach)

  /// (internal) Operate on contained items (see foreach())
  //_WRAP_METHOD(void foreach_full_(GtkCallback callback,GtkCallbackMarshal marshal, gpointer data,GDestroyNotify notify),gtk_container_foreach_full)

  
  /** Returns the container's non-internal children. See
   * forall() for details on what constitutes an "internal" child.
   * @return A newly-allocated list of the container's non-internal children.
   */
  Glib::ListHandle<Widget*> get_children();
  
  /** Returns the container's non-internal children. See
   * forall() for details on what constitutes an "internal" child.
   * @return A newly-allocated list of the container's non-internal children.
   */
  Glib::ListHandle<const Widget*> get_children() const;

  
  /** When a container receives an expose event, it must send synthetic
   * expose events to all children that don't have their own Gdk::Windows.
   * This function provides a convenient way of doing this. A container,
   * when it receives an expose event, calls propagate_expose() 
   * once for each child, passing in the event the container received.
   * 
   * propagate_expose() takes care of deciding whether
   * an expose event needs to be sent to the child, intersecting
   * the event's area with the child area, and sending the event.
   * 
   * In most cases, a container can simply either simply inherit the
   * Gtk::Widget::expose implementation from Gtk::Container, or, do some drawing 
   * and then chain to the ::expose implementation from Gtk::Container.
   * @param child A child of @a container.
   * @param event A expose event sent to container.
   */
  void propagate_expose(Widget& child, GdkEventExpose* event);

  
  /** Sets a focus chain, overriding the one computed automatically by GTK+.
   * 
   * In principle each widget in the chain should be a descendant of the 
   * container, but this is not enforced by this method, since it's allowed 
   * to set the focus chain before you pack the widgets, or have a widget 
   * in the chain that isn't always packed. The necessary checks are done 
   * when the focus chain is actually traversed.
   * @param focusable_widgets The new focus chain.
   */
  void set_focus_chain(const Glib::ListHandle<Widget*>& focusable_widgets);

  // gtk_container_get_focus_chain() has been split up into two
  // functions in order to make implicit container conversion possible.
  bool has_focus_chain() const;
  Glib::ListHandle<Widget*> get_focus_chain();
  Glib::ListHandle<const Widget*> get_focus_chain() const;

  
  /** Removes a focus chain explicitly set with set_focus_chain().
   */
  void unset_focus_chain();


/* Widget-level methods */

  
  /** Sets the @a reallocate_redraws flag of the container to the given value.
   * 
   * Containers requesting reallocation redraws get automatically
   * redrawn if any of their children changed allocation.
   * @param needs_redraws The new value for the container's @a reallocate_redraws flag.
   */
  void set_reallocate_redraws(bool needs_redraws =  true);


  /** Sets the focus on a child
   */
  void set_focus_child(Widget& widget);

  
  /** Hooks up an adjustment to focus handling in a container, so when a 
   * child of the container is focused, the adjustment is scrolled to 
   * show that widget. This function sets the vertical alignment. See 
   * Gtk::ScrolledWindow::get_vadjustment() for a typical way of obtaining 
   * the adjustment and set_focus_hadjustment() for setting
   * the horizontal adjustment.
   * 
   * The adjustments have to be in pixel units and in the same coordinate 
   * system as the allocation for immediate children of the container.
   * @param adjustment An adjustment which should be adjusted when the focus 
   * is moved among the descendents of @a container.
   */
  void set_focus_vadjustment(Adjustment& adjustment);

  
  /** Retrieves the vertical focus adjustment for the container. See
   * set_focus_vadjustment().
   * @return The vertical focus adjustment, or <tt>0</tt> if
   * none has been set.
   */
  Adjustment* get_focus_vadjustment();
  
  /** Retrieves the vertical focus adjustment for the container. See
   * set_focus_vadjustment().
   * @return The vertical focus adjustment, or <tt>0</tt> if
   * none has been set.
   */
  const Adjustment* get_focus_vadjustment() const;

  
  /** Hooks up an adjustment to focus handling in a container, so when a child 
   * of the container is focused, the adjustment is scrolled to show that 
   * widget. This function sets the horizontal alignment. 
   * See Gtk::ScrolledWindow::get_hadjustment() for a typical way of obtaining 
   * the adjustment and set_focus_vadjustment() for setting
   * the vertical adjustment.
   * 
   * The adjustments have to be in pixel units and in the same coordinate 
   * system as the allocation for immediate children of the container.
   * @param adjustment An adjustment which should be adjusted when the focus is 
   * moved among the descendents of @a container.
   */
  void set_focus_hadjustment(Adjustment& adjustment);

  
  /** Retrieves the horizontal focus adjustment for the container. See
   * set_focus_hadjustment().
   * @return The horizontal focus adjustment, or <tt>0</tt> if
   * none has been set.
   */
  Adjustment* get_focus_hadjustment();
  
  /** Retrieves the horizontal focus adjustment for the container. See
   * set_focus_hadjustment().
   * @return The horizontal focus adjustment, or <tt>0</tt> if
   * none has been set.
   */
  const Adjustment* get_focus_hadjustment() const;


  void resize_children();
  
  
  /** Returns the type of the children supported by the container.
   * 
   * Note that this may return TYPE_NONE to indicate that no more
   * children can be added, e.g. for a Gtk::Paned which already has two 
   * children.
   * @return A Type.
   */
  GType child_type() const;

  // Ignore functions such as gtk_container_class_install_child_property(),  which I think are for themes, like the GtkWidget style properties.
  

  /**
   * @par Prototype:
   * <tt>void on_my_%add(Widget* widget)</tt>
   */

  Glib::SignalProxy1< void,Widget* > signal_add();


  //We use the optional custom_c_callback parameter with _WRAP_SIGNAL() here,
  //so that we can write special code to check for deleted child widget parameters:
  
  /**
   * @par Prototype:
   * <tt>void on_my_%remove(Widget* widget)</tt>
   */

  Glib::SignalProxy1< void,Widget* > signal_remove();


  /**
   * @par Prototype:
   * <tt>void on_my_%check_resize()</tt>
   */

  Glib::SignalProxy0< void > signal_check_resize();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%set_focus_child(Widget* widget)</tt>
   */

  Glib::SignalProxy1< void,Widget* > signal_set_focus_child();


  void show_all_children(bool recursive = true); 

protected:
  Container();

    virtual GType child_type_vfunc() const;

    virtual void forall_vfunc(gboolean include_internals, GtkCallback callback, gpointer callback_data);

  //TODO: What is this?
    virtual char* composite_name_vfunc(GtkWidget* child);

    virtual void set_child_property_vfunc(GtkWidget* child, guint property_id, const GValue* value, GParamSpec* pspec);

    virtual void get_child_property_vfunc(GtkWidget* child, guint property_id, GValue* value, GParamSpec* pspec) const;


  #ifdef GLIBMM_PROPERTIES_ENABLED
/** The width of the empty border outside the containers 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<guint> property_border_width() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** The width of the empty border outside the containers 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<guint> property_border_width() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Specify how resize events are handled.
   *
   * 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<ResizeMode> property_resize_mode() ;
#endif //#GLIBMM_PROPERTIES_ENABLED

#ifdef GLIBMM_PROPERTIES_ENABLED
/** Specify how resize events are handled.
   *
   * 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<ResizeMode> property_resize_mode() const;
#endif //#GLIBMM_PROPERTIES_ENABLED

  #ifdef GLIBMM_PROPERTIES_ENABLED
/** Can be used to add a new child to the container.
   *
   * 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_WriteOnly<Widget*> property_child() ;
#endif //#GLIBMM_PROPERTIES_ENABLED


};

} // 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::Container
   */
  Gtk::Container* wrap(GtkContainer* object, bool take_copy = false);
} //namespace Glib


#endif /* _GTKMM_CONTAINER_H */

