/*  Inti: Integrated Foundation Classes
 *  Copyright (C) 2002-2003 The Inti Development Team.
 *  Copyright (C) 2000 Red Hat, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
//! @file inti/gtk/scrolledwindow.h
//! @brief A GtkScrolledWindow C++ wrapper interface.
//!
//! Provides ScrolledWindow, a container that holds a single child widget. ScrolledWindow adds
//! scrollbars to the child widget and optionally draws a beveled frame around the child widget.

#ifndef INTI_GTK_SCROLLED_WINDOW_H
#define INTI_GTK_SCROLLED_WINDOW_H

#ifndef INTI_GTK_BIN_H
#include <inti/gtk/bin.h>
#endif

#ifndef __GTK_SCROLLED_WINDOW_H__
#include <gtk/gtkscrolledwindow.h>
#endif

#ifndef INTI_GTK_ADJUSTMENT_H
#include <inti/gtk/adjustment.h>
#endif

namespace Inti {

namespace Gtk {
	
class HScrollbar;
class VScrollbar;
class ScrolledWindowClass;

//! @class ScrolledWindow scrolledwindow.h inti/gtk/scrolledwindow.h
//! @brief A GtkScrolledWindow C++ wrapper class.
//!
//! ScrolledWindow is a Bin subclass: it's a container that holds a single child widget. 
//! ScrolledWindow adds scrollbars to the child widget and optionally draws a beveled frame
//! around the child widget.
//!
//! The scrolled window can work in two ways. Some widgets have native scrolling support;
//! these widgets have "slots" for Adjustment objects. The scrolled window installs 
//! Adjustment objects in the child window's slots using the set_scroll_adjustments_signal. 
//! Widgets with native scroll support include TreeView, TextView, and Layout. 
//!
//! For widgets that lack native scrolling support, the Viewport widget acts as an adaptor
//! class, implementing scrollability for child widgets that lack their own scrolling 
//! capabilities. Use Viewport to scroll child widgets such as Table, Box, and so on. 
//!
//! If a widget has native scrolling abilities, it can be added to the ScrolledWindow with
//! Gtk::Container::add(). If a widget does not, you must first add the widget to a Viewport,
//! then add the Viewport to the scrolled window. The convenience function add_with_viewport()
//! does exactly this, so you can ignore the presence of the viewport. 
//!
//! The position of the scrollbars is controlled by the scroll adjustments. See Adjustment for
//! the fields in an adjustment - for Scrollbar, used by ScrolledWindow, the "value" field 
//! represents the position of the scrollbar, which must be between the <EM>lower</EM> field and
//! <EM>upper - page_size</EM>. The <EM>page_size</EM> field represents the size of the visible
//! scrollable area. The <EM>step_increment</EM> and "page_increment" fields are used when the user
//! asks to step down (using the small stepper arrows) or page down (using for example the Page Down key). 
//!
//! If a ScrolledWindow doesn't behave quite as you would like, or doesn't have exactly the right 
//! layout, it's very possible to set up your own scrolling with Scrollbar and for example a Table.

class ScrolledWindow : public Bin
{
	friend class G::Object;
	friend class ScrolledWindowClass;

	ScrolledWindow(const ScrolledWindow&);
	ScrolledWindow& operator=(const ScrolledWindow&);

protected:
//! @name Constructors
//! @{

	explicit ScrolledWindow(GtkScrolledWindow *scrolled_window, bool reference = false);
	//!< Construct a new ScrolledWindow from an existing GtkScrolledWindow.
	//!< @param scrolled_window A pointer to a GtkScrolledWindow.
	//!< @param reference Set false if the initial reference count is floating, set true if it's not.
	//!<
	//!< <BR>The <EM>scrolled_window</EM> can be a newly created GtkScrolledWindow or an existing
	//!< GtkScrolledWindow (see G::Object::Object).
	
//! @}	
//  Properties

	typedef G::Property<Adjustment*, G::Object*> HAdjustmentPropertyType;
	typedef G::PropertyProxy<G::Object, HAdjustmentPropertyType> HAdjustmentPropertyProxy;
	static const HAdjustmentPropertyType hadjustment_property;

	typedef G::Property<Adjustment*, G::Object*> VAdjustmentPropertyType;
	typedef G::PropertyProxy<G::Object, VAdjustmentPropertyType> VAdjustmentPropertyProxy;
	static const VAdjustmentPropertyType vadjustment_property;

	typedef G::Property<PolicyType, int> HScrollbarPolicyPropertyType;
	typedef G::PropertyProxy<G::Object, HScrollbarPolicyPropertyType> HScrollbarPolicyPropertyProxy;
	static const HScrollbarPolicyPropertyType hscrollbar_policy_property;

	typedef G::Property<PolicyType, int> VScrollbarPolicyPropertyType;
	typedef G::PropertyProxy<G::Object, VScrollbarPolicyPropertyType> VScrollbarPolicyPropertyProxy;
	static const VScrollbarPolicyPropertyType vscrollbar_policy_property;

	typedef G::Property<CornerType, int> WindowPlacementPropertyType;
	typedef G::PropertyProxy<G::Object, WindowPlacementPropertyType> WindowPlacementPropertyProxy;
	static const WindowPlacementPropertyType window_placement_property;

	typedef G::Property<ShadowType, int> ShadowTypePropertyType;
	typedef G::PropertyProxy<G::Object, ShadowTypePropertyType> ShadowTypePropertyProxy;
	static const ShadowTypePropertyType shadow_type_property;

public:
//! @name Constructors
//! @{

	ScrolledWindow();
	//!< Construct a new scrolled window. The scrolled window will create both adjustments for you.
	//!< The adjustments can be retrieved by calling get_hadjustment() and get_vadjustment().

	ScrolledWindow(Adjustment *hadjustment, Adjustment *vadjustment);
	//!< Construct a new scrolled window with the specified adjustments. 
	//!< @param hadjustment The Horizontal adjustment. 
	//!< @param vadjustment The Vertical adjustment. 
	//!<	
	//!< <BR>The two adjustments will be shared with the scrollbars and the child widget to keep
	//!< the bars in sync with the child. If you pass null for an adjustment the scrolled window
	//!< will create that adjustment for you. 

	virtual ~ScrolledWindow();
	//!< Destructor.
	
//! @}
//! @name Accessors
//! @{

	GtkScrolledWindow* gtk_scrolled_window() const { return (GtkScrolledWindow*)instance; }
	//!< Get a pointer to the GtkScrolledWindow structure.
	
	GtkScrolledWindowClass* gtk_scrolled_window_class() const;
	//!< Get a pointer to the GtkScrolledWindowclass structure.
	
	operator GtkScrolledWindow* () const;
	//!< Conversion operator; safely converts a ScrolledWindow to a GtkScrolledWindow pointer.
	
	HScrollbar* hscrollbar() const;
	//!< Get a pointer to the horizontal scrollbar.

	VScrollbar* vscrollbar() const;
	//!< Get a pointer to the vertical scrollbar.

	Adjustment* get_hadjustment() const;
	//!< Returns the horizontal scrollbar's adjustment, used to connect the horizontal
	//!< scrollbar to the child widget's horizontal scroll functionality. 
	//!< @return The horizontal Adjustment.

 	Adjustment* get_vadjustment() const;
	//!< Returns the vertical scrollbar's adjustment, used to connect the vertical
	//!< scrollbar to the child widget's vertical scroll functionality. 
	//!< @return The vertical Adjustment.

	void get_policy(PolicyType *hscrollbar_policy, PolicyType *vscrollbar_policy) const;
	//!< Retrieves the current policy values for the horizontal and vertical scrollbars (see set_policy()).
	//!< @param hscrollbar_policy The location to store the policy for the horizontal scrollbar, or null. 
	//!< @param vscrollbar_policy The location to store the policy for the horizontal scrollbar, or null. 
 
	CornerType get_placement() const;
	//!< Gets the placement of the scrollbars for the scrolled window (see set_placement()).
	//!< @return The current placement value. 
 
 	ShadowType get_shadow_type() const;
	//!< Gets the shadow type of the scrolled window (see set_shadow_type()).
	//!< @return The current shadow type. 
 
//! @}
//! @name Methods
//! @{

	void set_hadjustment(Adjustment *hadjustment);
	//!< Sets the Adjustment for the horizontal scrollbar. 
	//!< @param hadjustment The horizontal scroll adjustment. 
 
	void set_vadjustment(Adjustment *vadjustment);
	//!< Sets the Adjustment for the vertical scrollbar. 
	//!< @param vadjustment The vertical scroll adjustment. 

	void set_policy(PolicyType hscrollbar_policy, PolicyType vscrollbar_policy);
	//!< Sets the scrollbar policy for the horizontal and vertical scrollbars. 
	//!< @param hscrollbar_policy The policy for horizontal bar. 
	//!< @param vscrollbar_policy The policy for vertical bar.
	//!< 
	//!< <BR>The policy determines when the scrollbar should appear; it is a value from the 
	//!< Gtk::PolicyType enumeration. If POLICY_ALWAYS, the scrollbar is always present; if
	//!< POLICY_NEVER, the scrollbar is never present; if POLICY_AUTOMATIC, the scrollbar is
	//!< present only if needed (that is, if the slider part of the bar would be smaller than
	//!< the trough - the display is larger than the page size). 

	void set_policy_automatic();
	//!< Sets the scrollbar policy for the horizontal and vertical scrollbars to POLICY_AUTOMATIC, 
	//!< which means the scrollbars are present only if needed.
	
	void set_placement(CornerType window_placement);
	//!< Determines the location of the child widget with respect to the scrollbars. 
	//!< @param window_placement The position of the child window. 
	//!<	
	//!< <BR>The default is CORNER_TOP_LEFT, meaning the child is in the top left, with the
	//!< scrollbars underneath and to the right. Other values in CornerType are CORNER_TOP_RIGHT,
	//!< CORNER_BOTTOM_LEFT, and CORNER_BOTTOM_RIGHT. 
 
	void set_shadow_type(ShadowType type);
	//!< Changes the type of shadow drawn around the contents of scrolled_window.
	//!< @param type The kind of shadow to draw around scrolled window contents. 

	void add_with_viewport(Widget& child);
	//!< Used to add children without native scrolling capabilities. 
	//!< @param child The wdget you want to scroll.
	//!<
	//!< <BR>This is simply a convenience function; it is equivalent to adding the unscrollable
	//!< child to a viewport, then adding the viewport to the scrolled window. If a child has
	//!< native scrolling, use Gtk::Container::add() instead of this function. The viewport 
	//!< scrolls the child by moving its Gdk::Window, and takes the size of the child to be the
	//!< size of its toplevel Gdk::Window. This will be very wrong for most widgets that support
	//!< native scrolling; for example, if you add a widget such as TreeView with a viewport, 
	//!< the whole widget will scroll, including the column headings. Thus, widgets with native
	//!< scrolling support should not be used with the Viewport proxy.
	//!<
	//!< A widget supports scrolling natively if the set_scroll_adjustments_signal is declared
	//!< in its class declaration. 

//! @}
//! @name Property Proxies
//! @{

	const HAdjustmentPropertyProxy prop_hadjustment()
	{
		return HAdjustmentPropertyProxy(this, &hadjustment_property);
	}
	//!< The Adjustment for the horizontal position (Adjustment* : Read / Write / Construct).

	const VAdjustmentPropertyProxy prop_vadjustment()
	{
		return VAdjustmentPropertyProxy(this, &vadjustment_property);
	}
	//!< The Adjustment for the vertical position (Adjustment* : Read / Write / Construct).

	const HScrollbarPolicyPropertyProxy prop_hscrollbar_policy()
	{
		return HScrollbarPolicyPropertyProxy(this, &hscrollbar_policy_property);
	}
	//!< When the horizontal scrollbar is displayed (PolicyType : Read / Write).

	const VScrollbarPolicyPropertyProxy prop_vscrollbar_policy()
	{
		return VScrollbarPolicyPropertyProxy(this, &vscrollbar_policy_property);
	}
	//!< When the vertical scrollbar is displayed (PolicyType : Read / Write).

	const WindowPlacementPropertyProxy prop_window_placement()
	{
		return WindowPlacementPropertyProxy(this, &window_placement_property);
	}
	//!< Where the contents are located with respect to the scrollbars (CornerType : Read / Write).

	const ShadowTypePropertyProxy prop_shadow_type()
	{
		return ShadowTypePropertyProxy(this, &shadow_type_property);
	}
	//!< Style of bevel around the contents (ShadowType : Read / Write).

//! @}
};

} // namespace Gtk

} // namespace Inti

#endif // INTI_GTK_SCROLLED_WINDOW_H

