/*  Inti: Integrated Foundation Classes
 *  Copyright (C) 2002 The Inti Development Team.
 *
 *  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/frame.h
//! @brief A GtkFrame C++ wrapper interface.
//!
//! Provides Frame, a Bin widget that surrounds its child with a decorative frame
//! and an optional label.

#ifndef INTI_GTK_FRAME_H
#define INTI_GTK_FRAME_H

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

#ifndef __GTK_FRAME_H__
#include <gtk/gtkframe.h>
#endif

namespace Inti {

namespace Gtk {

class FrameClass;

//! @class Frame frame.h inti/gtk/frame.h
//! @brief A GtkFrame C++ wrapper class.
//!
//! The Frame widget is a Bin that surrounds its child with a decorative frame and
//! an optional label. If present, the label is drawn in a gap in the top side of
//! the frame. The position of the label can be controlled with set_label_align().

class Frame : public Bin
{
	friend class G::Object;
	friend class FrameClass;

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

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

//! @}
//  Override this do_ method when you want to change the default behaviour of the GtkFrame.
	
	virtual void do_compute_child_allocation(GtkAllocation *allocation);

//  Properties

	typedef G::Property<String> LabelPropertyType;
	typedef G::PropertyProxy<G::Object, LabelPropertyType> LabelPropertyProxy;
	static const LabelPropertyType label_property;

	typedef G::Property<float> LabelXalignPropertyType;
	typedef G::PropertyProxy<G::Object, LabelXalignPropertyType> LabelXalignPropertyProxy;
	static const LabelXalignPropertyType label_xalign_property;

	typedef G::Property<float> LabelYalignPropertyType;
	typedef G::PropertyProxy<G::Object, LabelYalignPropertyType> LabelYalignPropertyProxy;
	static const LabelYalignPropertyType label_yalign_property;

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

	typedef G::Property<Widget*, G::Object*> LabelWidgetPropertyType;
	typedef G::PropertyProxy<G::Object, LabelWidgetPropertyType> LabelWidgetPropertyProxy;
	static const LabelWidgetPropertyType label_widget_property;

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

	explicit Frame(ShadowType type = SHADOW_ETCHED_IN);
	//!< Construct a new Frame with the specified ShadowType and no label.
	//!< @param type The shadow type.

	explicit Frame(const String& label, ShadowType type = SHADOW_ETCHED_IN);
	//!< Construct a new Frame with the specified label and ShadowType.
	//!< @param label The label text.
	//!< @param type The shadow type.

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

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

	GtkFrameClass* gtk_frame_class() const;
	//!< Get a pointer to the GtkFixedClass structure.

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

	String get_label() const;
	//!< If the frame has a label widget and it is a Label, return the text in the label widget,
	//!< otherwise returns a null String.

	Widget* get_label_widget() const;
	//! Retrieves the label widget for the frame (see set_label_widget()).
	
	void get_label_align(float *xalign, float *yalign) const;
	//!< Retrieves the X and Y alignment of the frame's label (see set_label_align()).
	//!< @param xalign The location to store X alignment of frame's label, or null.
	//!< @param yalign The location to store Y alignment of frame's label, or null.

	ShadowType get_shadow_type() const;
	//!< Retrieves the shadow type of the frame (see set_shadow_type()).

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

	void remove_label();
	//!< Removes the current label, if any.

	void set_label(const String& label);
	//!< Set the text of the label.
	//!< @param label The new label text.

	void set_label_widget(Widget& label_widget);
	//!< Set the label widget for the frame. 
	//!< @param label_widget The new label widget.
	//!<
	//!< <BR>This is the widget that will appear embedded in the top edge of the frame as a title.
	
	void set_label_align(float xalign, float yalign);
	//!< Set the alignment of the Frame widget's label. 
	//!< @param xalign The position of the label along the top edge of the widget.
	//!< @param yalign The y alignment of the label.
	//!<
	//!< <BR>The default alignment value for a newly created Frame is 0.0. An xalign value
	//!< of 0.0 represents left alignment; 1.0 represents right alignment. A yalign value
	//!< 0.0 represents below the top edge; 1.0 represents above the top edge.
	
	void set_shadow_type(ShadowType type);
	//!< Set the shadow type for the Frame widget.
	//!< @param type The new shadow type.

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

	const LabelPropertyProxy prop_label()
	{
		return LabelPropertyProxy(this, &label_property);
	}
	//!< Text of the frame's label (String : Read / Write).

	const LabelXalignPropertyProxy prop_label_xalign()
	{
		return LabelXalignPropertyProxy(this, &label_xalign_property);
	}
	//!< The horizontal alignment of the label (float : Read / Write).

	const LabelYalignPropertyProxy prop_label_yalign()
	{
		return LabelYalignPropertyProxy(this, &label_yalign_property);
	}
	//!< The vertical alignment of the label (float : Read / Write).

	const ShadowTypePropertyProxy prop_shadow_type()
	{
		return ShadowTypePropertyProxy(this, &shadow_type_property);
	}
	//!< Apearance of the frame border (ShadowType : Read / Write).

	const LabelWidgetPropertyProxy prop_label_widget()
	{
		return LabelWidgetPropertyProxy(this, &label_widget_property);
	}
	//!< A widget to display in place of the usual frame label (Widget* : Read / Write).

//! @}
};

} // namespace Gtk

} // namespace Inti

#endif // INTI_GTK_FRAME_H

