/*  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/ruler.h
//! @brief A GtkRuler, GtkHRuler and GtkVRuler C++ wrapper interface.
//!
//! Provides Ruler, a widget that is the base class for horizontal and vertical rulers.
//! Rulers are used to show the mouse pointer's location in a window.

#ifndef INTI_GTK_RULER_H
#define INTI_GTK_RULER_H

#ifndef INTI_GTK_WIDGET_H
#include <inti/gtk/widget.h>
#endif

#ifndef __GTK_HRULER_H__
#include <gtk/gtkhruler.h>
#endif

#ifndef __GTK_VRULER_H__
#include <gtk/gtkvruler.h>
#endif

namespace Inti {

namespace Gtk {

class RulerClass;
class HRulerClass;
class VRulerClass;

//! @class Ruler ruler.h inti/gtk/ruler.h
//! @brief A GtkRuler C++ wrapper class.
//!
//! The Ruler widget is a base class for horizontal and vertical rulers. Rulers are used to show
//! the mouse pointer's location in a window. The ruler can either be horizontal or vertical on
//! the window. Within the ruler a small triangle indicates the location of the mouse relative to
//! the horizontal or vertical ruler. See HRuler to learn how to create a new horizontal ruler.
//! See VRuler to learn how to create a new vertical ruler. 

class Ruler : public Widget
{
	friend class G::Object;
	friend class RulerClass;

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

	Ruler();
	//!< Construct a new Ruler.

	explicit Ruler(GtkRuler *ruler, bool reference = false);
	//!< Construct a new Ruler from an existing GtkRuler.
	//!< @param ruler A pointer to a GtkRuler.
	//!< @param reference Set false if the initial reference count is floating, set true if it's not.
	//!<
	//!< <BR>The <EM>ruler</EM> can be a newly created GtkRuler or an existing
	//!< GtkRuler (see G::Object::Object).
	
	virtual ~Ruler() = 0;
	//!< Destructor.
	
//! @}
//  Override these do_ methods only when you want change the default behaviour GtkRuler.

	virtual void do_draw_ticks();

	virtual void do_draw_pos();

//  Properties

	typedef G::Property<double> LowerPropertyType;
	typedef G::PropertyProxy<G::Object, LowerPropertyType> LowerPropertyProxy;
	static const LowerPropertyType lower_property;

	typedef G::Property<double> UpperPropertyType;
	typedef G::PropertyProxy<G::Object, UpperPropertyType> UpperPropertyProxy;
	static const UpperPropertyType upper_property;

	typedef G::Property<double> PositionPropertyType;
	typedef G::PropertyProxy<G::Object, PositionPropertyType> PositionPropertyProxy;
	static const PositionPropertyType position_property;

	typedef G::Property<double> MaxSizePropertyType;
	typedef G::PropertyProxy<G::Object, MaxSizePropertyType> MaxSizePropertyProxy;
	static const MaxSizePropertyType max_size_property;

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

	GtkRuler* gtk_ruler() const { return (GtkRuler*)instance; }
	//!< Get a pointer to the GtkRuler structure.
	
	GtkRulerClass* gtk_ruler_class() const;
	//!< Get a pointer to the GtkRulerClass structure.
	
	operator GtkRuler* () const;
	//!< Conversion operator; safely converts a Ruler to a GtkRuler pointer.
	
	MetricType get_metric() const;
	//!< Gets the units used for a Ruler (see gtk_ruler_set_metric()).
	//!< @return The units currently used for the ruler. 

	double get_lower() const;
	//!< Gets the lower limit of the ruler.
	
 	double get_upper() const;
 	//!< Gets the upper limit of the ruler.
	
	double get_position() const;
	//!< Gets the current position of the mark on the ruler.
	
 	void get_range(double *lower, double *upper, double *position, double *max_size = 0);
	//!< Retrieves values indicating the range and current position of the ruler (see set_range()).
	//!< @param lower The location to store lower limit of the ruler, or null. 
	//!< @param upper The location to store upper limit of the ruler, or null. 
	//!< @param position The location to store the current position of the mark on the ruler, or null. 
	//!< @param max_size The location to store the maximum size of the ruler used when calculating
	//!<                 the space to leave for the text, or null.
  	
//! @}
//! @name Methods
//! @{

	void set_metric(MetricType metric = PIXELS);
	//!< Sets the ruler to the units defined. 
	//!< @param metric The unit of measurement. 
	//!<
	//!< <BR>Available units are PIXELS, INCHES, or CENTIMETERS. The default unit of measurement
	//!< is PIXELS. 

 	void set_range(double lower, double upper, double position, double max_size);
	//!< Sets the range of the ruler using <EM>lower</EM>, <EM>upper</EM>, <EM>position</EM>,
	//!< and <EM>max_size</EM>. 
	//!< @param lower The upper limit of the ruler. 
	//!< @param upper The lower limit of the ruler. 
	//!< @param position The mark on the ruler.
 	//!< @param max_size The maximum size of the ruler. 
	
	void draw_ticks();
	//!< Draws the tick marks on the ruler.
	
	void draw_pos();
	//!< Draws the position mark on the ruler.

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

	const LowerPropertyProxy prop_lower()
	{
		return LowerPropertyProxy(this, &lower_property);
	}
	//!< Lower limit of the ruler (double : Read / Write).

	const UpperPropertyProxy prop_upper()
	{
		return UpperPropertyProxy(this, &upper_property);
	}
	//!< Upper limit of ruler (double : Read / Write).

	const PositionPropertyProxy prop_position()
	{
		return PositionPropertyProxy(this, &position_property);
	}
	//!< Position of the mark on the ruler (double : Read / Write).

	const MaxSizePropertyProxy prop_max_size()
	{
		return MaxSizePropertyProxy(this, &max_size_property);
	}
	//!< Maximum size of the ruler (double : Read / Write).

//! @}
};

//! @class HRuler ruler.h inti/gtk/ruler.h
//! @brief A GtkHRuler C++ wrapper class.
//!
//! The HRuler widget is a widget arranged horizontally creating a ruler that is utilized
//! around other widgets such as a text widget. The ruler is used to show the location of
//! the mouse on the window and to show the size of the window in specified units. The 
//! available units of measurement are PIXELS (the default), INCHES and CENTIMETERS. 

class HRuler : public Ruler
{
	friend class G::Object;
	friend class HRulerClass;

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

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

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

	HRuler();
	//!< Contruct a new horizontal ruler.
	
	virtual ~HRuler();
	//!< Destructor.
	
//! @}
//! @name Accessors
//! @{

	GtkHRuler* gtk_hruler() const { return (GtkHRuler*)instance; }
	//!< Get a pointer to the GtkHRuler structure.
	
	GtkHRulerClass* gtk_hruler_class() const;
	//!< Get a pointer to the GtkHRulerClass structure.
	
	operator GtkHRuler* () const;
	//!< Conversion operator; safely converts a HRuler to a GtkHRuler pointer.
	
//! @}
};

//! @class VRuler ruler.h inti/gtk/ruler.h
//! @brief A GtkVRuler C++ wrapper class.

class VRuler : public Ruler
{
	friend class G::Object;
	friend class VRulerClass;

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

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

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

	VRuler();
	//!< Construct a new vertical ruler.
	
	virtual ~VRuler();
	//!< Destructor.
	
//! @}
//! @name Accessors
//! @{

	GtkVRuler* gtk_vruler() const { return (GtkVRuler*)instance; }
	//!< Get a pointer to the GtkVRuler structure.
	
	GtkVRulerClass* gtk_vruler_class() const;
	//!< Get a pointer to the GtkVRulerClass structure.
	
	operator GtkVRuler* () const;
	//!< Conversion operator; safely converts a VRuler to a GtkVRuler pointer.
	
//! @}
};

} // namespace Gtk

} // namespace Inti

#endif // INTI_GTK_RULER_H

