- documentet cairo_widget.hh

git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@1143 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
paolo 2006-09-14 11:47:36 +00:00
parent 9cb356a3f8
commit c39ecfed50
1 changed files with 197 additions and 18 deletions

View File

@ -30,9 +30,62 @@
namespace sgpem
{
/**
* \brief Base abstract class to derive widgets that use cairo graphic output.
*
* This class is the starting point to derive graphics widgets using cairo.
* It provides explicit in memory double buffering, and scaling.
* In order to build a new widget that uses cairo output the developer should
* use this as base class.
*
* The implementer:
* - must
* - implement draw_widget() to draw in the widget client area \see draw_widget()
* - should
* - define calc_drawing_size() to provide correct size calculation
* - call resize_redraw() to calc size and redraw
* - can
* - define calc_widget_size() to get predefined widget dimensions
* - set the desired scaling mode \see set_scaling_mode()
* - call redraw() to only redraw the widget
*
*/
class CairoWidget : public Gtk::Widget
{
public:
/**
* \brief Defines cairo widget scaling modes.
*
* Scaling is the geometric operation that maps draw_widget()'s output
* into client area.
* There are some ways to scale the output to fit in client area.
* The developer does'n need to know how to build the scaling but
* only how it works.
* The defined modes are:
* - scaling_none without any scaling
* - scaling_to_w uses width to calculate scale factor
* - scaling_to_h uses height to calculate scale factor
* - scaling_min uses minimum scale factor from width, height
* - scaling_max uses maximum scale factor from width, height
* - scaling_all scale to stretch into client area
*
* Each mode has advantages and disvantages.
* - scaling_none doesn't do any scaling at all.
* The graphics are rendered as they are drawn.
* - scaling_to_w calc both x and y scaling to fit the client width.
* Probably the draw will exceed the client area height.
* - scaling_to_h calc both x and y scaling to fit the client height.
* Probably the draw will exceed the client area width.
* - scaling_min calc both x and y scaling to enter in the client area.
* The draw will always fit in the window.
* - scaling_max calc both x and y scaling to not enter in the client area.
* The draw will rarely fit in the window.
* - scaling_all calc x and y scaling to fit exactly in the client area.
* The draw will always fit the entire client area.
* NOTE: This scaling mode stretch the drawing and not respect the
* ratio between width and height.
*
*/
enum scaling_mode
{
scaling_none = 0, // without any scaling
@ -43,69 +96,195 @@ namespace sgpem
scaling_all = 1 << 4 // scale to stretch into client area
};
/**
* \brief Unique constructor, initialize data members.
*/
CairoWidget();
/**
* \brief Widget's destructor.
*/
virtual ~CairoWidget();
// scaling related functions
/**
* \brief Assign the desired scaling mode and returns the old one.
*
* Change scaling mode; default is scaling_none.
* The programmer must call resize_redraw() becous it take effect.
*
* \param scaling_mode The new desired scaling mode.
* \return Previous scaling mode.
*/
scaling_mode set_scaling_mode(scaling_mode scaling_mode);
scaling_mode get_scaling_mode();
// need for redrawing the widget (double buffering related)
/**
* \brief Retrieve current scaling mode.
*
* \return Previous scaling mode.
*/
scaling_mode get_scaling_mode() const;
/**
* \brief Force the widgets readrawing without calc new size.
*
* Useful for redrawing the widget (double buffering related).
*/
void redraw();
// need for auto resizing and redrawing the widget (double buffering related)
/**
* \brief Force the widgets readrawing without calc new size.
*
* Need for auto resizing and redrawing the widget (double buffering related).
*/
void resize_redraw();
// TODO - temporary: will be removed soon
// void change_scaling_mode();
protected:
/**
* \brief Widgets size type.
*/
typedef unsigned int size_t;
// implements fundamental widget's method
// implementation of fundamental widget's method
/**
* \brief Implements standard widget's on_realize() mehtod.
*
* The on_realize() function is called by the Gtk windowing system
* before it creates a new widget.
* See gtkmm documentation for more informations.
*/
virtual void on_realize();
virtual void on_size_allocate(const Gtk::Allocation& allocation);
virtual void on_size_request(Gtk::Requisition* request);
virtual bool on_expose_event(GdkEventExpose* event);
virtual bool on_button_press_event(GdkEventButton* event);
// in this method the implemented widget must "do the things"
/**
* \brief Implements standard widget's on_size_allocate() mehtod.
*
* The on_size_allocate() function is called by the Gtk windowing system
* after creation of a new widget asking the desired widget dimensions.
* See gtkmm documentation for more informations.
*/
virtual void on_size_allocate(const Gtk::Allocation& allocation);
/**
* \brief Implements standard widget's on_size_request() mehtod.
*
* The on_size_request() function is called by the Gtk windowing system
* when need to change the widget dimensions.
* See gtkmm documentation for more informations.
*/
virtual void on_size_request(Gtk::Requisition* request);
/**
* \brief Implements standard widget's on_expose_event() mehtod.
*
* The on_expose_event() function is called by the Gtk windowing system
* when the widgets' redrawing is requested after creation or to update.
* See gtkmm documentation for more informations.
*/
virtual bool on_expose_event(GdkEventExpose* event);
/*
to delete asap
virtual bool on_button_press_event(GdkEventButton* event);
*/
/**
* \brief Client area drawing method.
*
* In this method the implemented widget must "do the things"
* and (obviously) its implementation is a need.
* The programmer then use the passed cairo context, ctx, to
* draw in the widgets client area.
* See cairo documentation for more informations.
*/
virtual void draw_widget(cairo_t* ctx) = 0;
// with this method CairoWidget tells the needed drawing dimensions
/**
* \brief Method to calculate widget dimensions.
*
* The user should implement this method to allow scaling factors calculation.
* Is necessary if scaling is needed/used.
*/
virtual void calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height);
// with this method CairoWidget tells the needed widgwt dimensions
// with this method CairoWidget tells the needed widget dimensions
/**
* \brief Method to define default widget dimensions.
*
* The user can implement this method to give default dimensions.
* It isn't necessary because scaling (and resizing) take care of calc_drawing_size() results.
*/
virtual void calc_widget_size(size_t& width, size_t& height);
/**
* \brief Calculate scaling factors to apply during widget's redrawing.
*
* This method is used internally to recomute scaling factors.
* Implementors of derived calsses doesn't worry about it.
*/
void calc_scale_factors();
/*
I don't know the meaning of these definition!
Paolo
typedef Gdk::Rectangle area_t;
typedef sigc::mem_functor0<void, CairoWidget> method0_t;
typedef std::pair<area_t, method0_t> area_callback_t;
typedef std::vector<area_callback_t> areas_vect_t;
*/
/**
* \brief Calculated width of drawing.
*;
mutable size_t _draw_w;
/**
* \brief Calculated height of drawing.
*;
mutable size_t _draw_h;
private:
// The width and height the widget will assume, must be determined
// before starting drawing by calc_size()
// drawing dimensions required
// window client area
/**
* \brief Client area width of widget.
*/
mutable size_t _client_w;
/**
* \brief Client area height of widget.
*/
mutable size_t _client_h;
// pixmap client area
/**
* \brief Client area width of pixmap.
*/
mutable size_t _pixmap_w;
/**
* \brief Client area width of pixmap.
*/
mutable size_t _pixmap_h;
// cairo scale factors
/**
* \brief Cairo x scale factor.
*/
mutable double _scale_x;
/**
* \brief Cairo y scale factor.
*/
mutable double _scale_y;
/**
* \brief Flag to signal require redrawing.
*/
mutable bool _need_redraw;
/**
* \brief Actual scaling mode.
*/
scaling_mode _scaling_mode;
// The offscreen pixmap we use for double-buffering
/**
* \brief Offscreen pixmap used for double-buffering.
*/
Glib::RefPtr<Gdk::Pixmap> _buf;
};