/*  Inti: Integrated Foundation Classes
 *  Copyright (C) 2002 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/toolbar.h
//! @brief A GtkToolbar C++ wrapper interface.
//!
//! Provides Toolbar, a container widget that Buttons, ToggleButtons, RadioButtons
//! and arbitrary widgets can be added to.

#ifndef INTI_GTK_TOOLBAR_H
#define INTI_GTK_TOOLBAR_H

#ifndef INTI_GTK_CONTAINER_H
#include <inti/gtk/container.h>
#endif

#ifndef __GTK_TOOLBAR_H__
#include <gtk/gtktoolbar.h>
#endif

namespace Inti {

namespace Gtk {

class Button;
class Label;
class RadioButton;
class ToggleButton;
class ToolbarClass;

//! @enum ToolbarChildType
//! ToolbarChildType is used to set the type of new elements that are added to a Toolbar. 

enum ToolbarChildType
{
	TOOLBAR_CHILD_SPACE = GTK_TOOLBAR_CHILD_SPACE, //!< A space; one of the styles in ToolbarSpaceStyle.
	TOOLBAR_CHILD_BUTTON = GTK_TOOLBAR_CHILD_BUTTON, //!< A Button.
	TOOLBAR_CHILD_TOGGLEBUTTON = GTK_TOOLBAR_CHILD_TOGGLEBUTTON, //!< A ToggleButton.
	TOOLBAR_CHILD_RADIOBUTTON = GTK_TOOLBAR_CHILD_RADIOBUTTON, //!< A RadioButton. 
	TOOLBAR_CHILD_WIDGET = GTK_TOOLBAR_CHILD_WIDGET //!< A standard Widget.
};
	
//! @enum ToolbarSpaceStyle
//! The toolbar space style, either a line or an empty space.

enum ToolbarSpaceStyle
{
	TOOLBAR_SPACE_EMPTY = GTK_TOOLBAR_SPACE_EMPTY, //!< A empty space.
	TOOLBAR_SPACE_LINE = GTK_TOOLBAR_SPACE_LINE //!< A line space.
};

//! @enum ToolbarStyle
//! ToolbarStyle is used to customize the appearance of a Toolbar. Note that setting the 
//! toolbar style overrides the user's preferences for the default toolbar style. 

enum ToolbarStyle
{
	TOOLBAR_ICONS = GTK_TOOLBAR_ICONS, 
	//!< Buttons display only icons in the toolbar.
	
	TOOLBAR_TEXT = GTK_TOOLBAR_TEXT,
	//!< Buttons display only text labels in the toolbar. 
	
	TOOLBAR_BOTH = GTK_TOOLBAR_BOTH,
	//!< Buttons display text and icons in the toolbar. 
	
	TOOLBAR_BOTH_HORIZ = GTK_TOOLBAR_BOTH_HORIZ
	//!< Buttons display icons and text alongside each other, rather than vertically stacked.
};

//! @class ToolbarChild toolbar.h inti/gtk/toolbar.h
//! @brief A GtkToolbarChild C++ wrapper class.
//!
//! ToolbarChild represents a child widget in a toolbar. It has four read-only data members:
//! the toolbar child type, the widget, the icon image and the text label.

class ToolbarChild
{
	friend class none;

	ToolbarChild(const ToolbarChild&);
	ToolbarChild& operator=(const ToolbarChild&);
	
	GtkToolbarChild child_;

public:
//! @name Accessors
//! @{

	GtkToolbarChild* gtk_toolbar_child() const { return const_cast<GtkToolbarChild*>(&child_); }
	//!< Get a pointer to the GtkToolbarChild structure.
	
	ToolbarChildType type() const;
	//!< Returns the type of toolbar child.

	Widget* widget() const;
	//!< Returns a pointer to the child widget, or null if no widget was added. 

	Widget* icon() const;
	//!< Returns a pointer to the image widget, or null if the child doesn't have an icon. 

	Label* label() const;
	//!< Returns a pointer to the label widget, or null if there is no text label. 
	
//! @}
};

//! @class Toolbar toolbar.h inti/gtk/toolbar.h
//! @brief A GtkToolbar C++ wrapper class.
//!
//! After constructing an empty toolbar, buttons with text and/or images are added with
//! append_button(), prepend_button(), and insert_button(). There are similar methods
//! for adding ToggleButtons and RadioButtons. An arbitrary widget can be added to the
//! toolbar with append_widget(), prepend_widget(), and insert_widget(). Widgets can be
//! visibly grouped by adding gaps between widgets using append_space(), prepend_space(),
//! and insert_space(). 

class Toolbar : public Container
{
	friend class G::Object;
	friend class ToolbarClass;

	Toolbar(const Toolbar&);
	Toolbar& operator=(const Toolbar&);
	
protected:
//! @name Constructors
//! @{

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

	virtual void on_orientation_changed(Orientation orientation);
	//!< Called when the orientation of a toolbar is changed. 
	//!< @param orientation  The new Orientation of the toolbar. 

	virtual void on_style_changed(ToolbarStyle style);
	//!< Called when ever the style of a toolbar is adjusted. 
	//!< @param style The new ToolbarStyle of toolbar.
	//!<
	//!< <BR>For example, this would be a useful signal to connect to if you want to
	//!< display more items on the toolbar when it is in icon-only mode; each item 
	//!< takes less space on the bar. 

//! @}
//  Properties

	typedef G::Property<Orientation, int> OrientationPropertyType;
	typedef G::PropertyProxy<G::Object, OrientationPropertyType> OrientationPropertyProxy;
	static const OrientationPropertyType orientation_property;

	typedef G::Property<ToolbarStyle, int> ToolbarStylePropertyType;
	typedef G::PropertyProxy<G::Object, ToolbarStylePropertyType> ToolbarStylePropertyProxy;
	static const ToolbarStylePropertyType toolbar_style_property;

//  Signals

	typedef G::Signal1<void, GtkOrientation> OrientationChangedSignalType;
	typedef G::SignalProxy<TypeInstance, OrientationChangedSignalType> OrientationChangedSignalProxy;
	static const OrientationChangedSignalType orientation_changed_signal;

	typedef G::Signal1<void, GtkToolbarStyle> StyleChangedSignalType;
	typedef G::SignalProxy<TypeInstance, StyleChangedSignalType> StyleChangedSignalProxy;
	static const StyleChangedSignalType style_changed_signal;

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

	explicit Toolbar(Orientation orientation = ORIENTATION_HORIZONTAL, ToolbarStyle style = TOOLBAR_ICONS);
	//!< Constrcut a new toolbar.
	//!< @param orientation The Orientation, either horizontal or vertical.
	//!< @param style The style for the toolbar.

	virtual ~Toolbar();
	//!< Destructor.

//! @}
//! @name Accessors
//! @{

	GtkToolbar* gtk_toolbar() const { return (GtkToolbar*)instance; }
	//!< Get a pointer to the GtkToolbar structure.

	GtkToolbarClass* gtk_toolbar_class() const;
	//!< Get a pointer to the GtkToolbarClass structure.

	operator GtkToolbar* () const;
	//!< Conversion operator; safely converts a Toolbar to a GtkToolbar pointer.

	bool children(std::vector<ToolbarChild*>& child_list) const;
	//!< Retrieves the list of the toolbar's children.
	//!< @param child_list A reference to a vector of ToolbarChild* to hold the child list.
	//!< @return <EM>true</EM> if <EM>child_list</EM> is not empty.

	Orientation get_orientation() const;
	//!< Returns the current orientation of the toolbar (see set_orientation()).
	
	ToolbarStyle get_style() const;
	//!< Retrieves whether the toolbar has text, icons, or both (see set_style()).
	//!< @return The current style of the toolbar. 
	
	IconSize get_icon_size() const;
	//!< Returns the current icon size for the icons on the toolbar (see set_icon_size()).
	
	bool get_tooltips() const;
	//!< Returns true if tooltips are enabled (see set_tooltips()).

//! @}
//! @name Methods
//! @{

	Button* append_button
	(
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Adds a new button to the end (right or bottom edges) of the toolbar. 
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon. 
	//!< @param callback The slot to call when the button is pressed.
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new button added to the toolbar; you can ignore this value if you want. 
		
	Button* prepend_button
	(
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Adds a new button to the beginning (left or top edges) of the toolbar. 
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new button added to the toolbar; you can ignore this value if you want. 

	Button* insert_button
	(
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		int position,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Inserts a new button into the toolbar at the specified position.
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param position The number of widgets to insert this item after. 	
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new button added to the toolbar; you can ignore this value if you want. 

	ToggleButton* append_toggle_button
	(
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Adds a new toggle button to the end (right or bottom edges) of the toolbar. 
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new toggle button added to the toolbar; you can ignore this value if you want. 

	ToggleButton* prepend_toggle_button
	(
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		const String& tooltip_text = 0,
		const String& tooltip_private_text  = 0
	);
	//!< Adds a new toggle button to the beginning (left or top edges) of the toolbar. 
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new toggle button added to the toolbar; you can ignore this value if you want. 

	ToggleButton* insert_toggle_button
	(
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		int position,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Inserts a new toggle button into the toolbar at the specified position.
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param position The number of widgets to insert this item after. 	
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new toggle button added to the toolbar; you can ignore this value if you want. 

	RadioButton* append_radio_button
	(
		const RadioButton *group,
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Adds a new radio button to the end (right or bottom edges) of the toolbar. 
	//!< @param group The radio button whose group this radio button should be added to, or null.	
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new radio button added to the toolbar. 
	//!< 
	//!< <BR>The <EM>group</EM> argument should be null for the first radio button in a group.
	//!< Then for subsequent radio buttons in the same group, the return value from the first
	//!< or previous call to this method is passed as the group argument for the next call.

	RadioButton* prepend_radio_button
	(
		const RadioButton *group,
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		const String& tooltip_text = 0,
		const String& tooltip_private_text   = 0
	);
	//!< Adds a new radio button to the beginning (left or top edges) of the toolbar.
	//!< @param group The radio button whose group this radio button should be added to, or null.	
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon.
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new radio button added to the toolbar. 
	//!< 
	//!< <BR>The <EM>group</EM> argument should be null for the first radio button in a group.
	//!< Then for subsequent radio buttons in the same group, the return value from the first
	//!< or previous call to this method is passed as the group argument for the next call.

	RadioButton* insert_radio_button
	(
		const RadioButton *group,
		const String& text,
		Widget *icon,
		const Slot0<void> *callback,
		int position,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Inserts a new radio button into the toolbar at the specified position.
	//!< @param group The radio button whose group this radio button should be added to, or null.	
	//!< @param text The toolbar button label. 
	//!< @param icon A Widget that should be used as the button's icon. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param position The number of widgets to insert this item after. 	
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new radio button added to the toolbar. 
	//!< 
	//!< <BR>The <EM>group</EM> argument should be null for the first radio button in a group.
	//!< Then for subsequent radio buttons in the same group, the return value from the first
	//!< or previous call to this method is passed as the group argument for the next call.

	Button* append_stock
	(
		const char *stock_id,
		const Slot0<void> *callback,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Adds a stock button to the end (right or bottom edges) of the toolbar. 
	//!< @param stock_id The GTK+ stock identifier, such as GTK_STOCK_OPEN or GTK_STOCK_EXIT. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new button added to the toolbar; you can ignore this value if you want. 

	Button* prepend_stock
	(
		const char *stock_id,
		const Slot0<void> *callback,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Adds a stock button to the beginning (left or top edges) of the toolbar. 
	//!< @param stock_id The GTK+ stock identifier, such as GTK_STOCK_OPEN or GTK_STOCK_EXIT. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new button added to the toolbar; you can ignore this value if you want. 

	Button* insert_stock
	(
		const char *stock_id,
		const Slot0<void> *callback,
		int position,
		const String& tooltip_text = 0,
		const String& tooltip_private_text = 0
	);
	//!< Inserts a new stock button into the toolbar at the specified position.
	//!< @param stock_id The GTK+ stock identifier, such as GTK_STOCK_OPEN or GTK_STOCK_EXIT. 
	//!< @param callback The slot to call when the button is pressed. 
	//!< @param position The number of widgets to insert this item after. 	
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 
	//!< @return The new button added to the toolbar; you can ignore this value if you want. 

	void append_space();
	//!< Adds a new space to the end of the toolbar. 

	void prepend_space();
	//!< Adds a new space to the beginning of the toolbar. 

	void insert_space(int position);
	//!< Inserts a new space into the toolbar at the specified position.
	//!< @param position The number of widgets to insert the space after. 	

	void remove_space(int position);
	//!< Removes the space at the specified position.

	void append_widget(Widget& widget, const String& tooltip_text = 0, const String& tooltip_private_text = 0);
	//!< Adds a widget to the end (right or bottom edges) of the toolbar. 
	//!< @param widget The Widget to add.
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 

	void prepend_widget(Widget& widget, const String& tooltip_text = 0, const String& tooltip_private_text = 0);
	//!< Adds a widget to the beginning (left or top edges) of the toolbar. 
	//!< @param widget The Widget to add.
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 

	void insert_widget(Widget& widget, int position, const String& tooltip_text = 0, const String& tooltip_private_text =  0);
	//!< Inserts a widget into the toolbar at the specified position.
	//!< @param widget The Widget to add.
	//!< @param position The number of widgets to insert the Widget after. 	
	//!< @param tooltip_text A string that appears when the user holds the mouse over this item. 
	//!< @param tooltip_private_text The private text of the tooltip. 

	void set_orientation(Orientation orientation);
	//!< Sets whether a toolbar should appear horizontally or vertically. 
	//!< @param orientation The new Orientation.
	
	void set_style(ToolbarStyle style);
	//!< Alters the view of toolbar to display either icons only, text only, or both. 
	//!< @param style The new style for the toolbar.
	
	void set_icon_size(IconSize icon_size);
	//!< Sets the size of stock icons in the toolbar. 
	//!< @param icon_size The IconSize that stock icons in the toolbar shall have.
	//!<	
	//!< <BR>You can call this method either before you add the icons or after they've been
	//!< added. The size you set will override user preferences for the default icon size.
	
	void set_tooltips(bool enable);
	//!< Sets if the tooltips of a toolbar should be active or not. 
	//!< @param enable Set to false to disable the tooltips, or true to enable them.
	 
	void unset_style();
	//!< Unsets the toolbar style set with set_style(), so that user preferences will be
	//!<  used to determine the toolbar style.
	
	void unset_icon_size();
	//!< Unsets the toolbar icon size set with set_icon_size(), so that user preferences
	//!< will be used to determine the icon size.
		
//! @}
//! @name Property Proxies
//! @{

	const OrientationPropertyProxy prop_orientation()
	{
		return OrientationPropertyProxy(this, &orientation_property);
	}
	//!< The orientation of the toolbar (Orientation : Read / Write).

	const ToolbarStylePropertyProxy prop_toolbar_style()
	{
		return ToolbarStylePropertyProxy(this, &toolbar_style_property);
	}
	//!< How to draw the toolbar (ToolbarStyle : Read / Write).	

//! @}
//! @name Signal Proxies
//! @{

	const OrientationChangedSignalProxy sig_orientation_changed()
	{
		return OrientationChangedSignalProxy(this, &orientation_changed_signal);
	}
	//!< Connect to the orientation_changed_signal; emitted when the orientation of a toolbar is changed. 

	const StyleChangedSignalProxy sig_style_changed()
	{
		return StyleChangedSignalProxy(this, &style_changed_signal);
	}
	//!< Connect to the style_changed_signal; emitted when ever the style of a toolbar is adjusted. 
	
//! @}
};

} // namespace Gtk

} // namespace Inti

#endif // INTI_GTK_TOOLBAR_H

