core/vgui/vgui_slider_tableau.h
Go to the documentation of this file.
00001 #ifndef vgui_slider_tableau_h_
00002 #define vgui_slider_tableau_h_
00003 //:
00004 // \file
00005 // \author Amitha Perera
00006 // \date   Feb 2005
00007 
00008 #include <vcl_list.h>
00009 #include <vgui/vgui_tableau.h>
00010 #include "vgui_slider_tableau_sptr.h"
00011 
00012 //: A slider implementation
00013 //
00014 // Implements a tableau that can be used as a slider. This can be used
00015 // to provide platform-independent scrollbar-like capabilities. (It
00016 // may be stretching the design parameters of vgui, but hey...)
00017 //
00018 // One use of it is in conjunction with vgui_poly_tableau to place the
00019 // slider somewhere. For example:
00020 // \code
00021 //   vgui_tableau_sptr main_tab; // some tableau
00022 //   vgui_slider_tableau_new slider_h( vgui_slider_tableau::horiz );
00023 //   vgui_slider_tableau_new slider_v( vgui_slider_tableau::vert );
00024 //   vgui_poly_tableau_new poly;
00025 //   poly->add( easy_tab, 0.1, 0.1, 0.9, 0.9 );
00026 //   poly->add( slider_h, 0.1, 0.0, 0.9, 0.1 );
00027 //   poly->add( slider_v, 0.0, 0.1, 0.1, 0.9 );
00028 // \endcode
00029 //
00030 class vgui_slider_tableau
00031   : public vgui_tableau
00032 {
00033  public:
00034   //: Direction of slider
00035   enum slider_type { horiz, vert };
00036 
00037   //: Callback function type
00038   //
00039   // The parameter \a tab will be a pointer to the slider tableau
00040   // performing the callback. \a data contains data that was specified
00041   // when this callback was registered.
00042   typedef void (*callback)( vgui_slider_tableau* tab, void* data );
00043 
00044 
00045   // Internal structure used to store the callback pointer and
00046   // associated data. It needs to be public because it is used to
00047   // instantiate a vcl_list. It also needs to be complete at the time
00048   // of instantiation, so we can't simply forward declare it.
00049   struct callback_info {
00050     callback func_;
00051     void* data_;
00052     callback_info( callback f, void* d ) : func_(f), data_(d) { }
00053   };
00054 
00055 
00056   //: A handle used to refer to callback functions added to this slider
00057   typedef vcl_list< callback_info >::iterator cb_handle;
00058 
00059   //: Add a callback.
00060   //
00061   // The callback function \a cb will be called whenever the slider
00062   // value changes. The callback function will be provided the data in
00063   // \a data as the second parameter.
00064   cb_handle add_motion_callback( callback cb, void* data );
00065 
00066   //: Add a callback.
00067   //
00068   // The callback function \a cb will be called whenever user finished
00069   // picking a new slider value. The callback function will be
00070   // provided the data in \a data as the second parameter.
00071   cb_handle add_final_callback( callback cb, void* data );
00072 
00073   //: Remove a callback
00074   //
00075   // \a cbh is the handle returned by add_motion_callback() when the callback
00076   // was added to this slider.
00077   void remove_motion_callback( cb_handle cbh );
00078 
00079   //: Remove a callback
00080   //
00081   // \a cbh is the handle returned by add_final_callback() when the callback
00082   // was added to this slider.
00083   void remove_final_callback( cb_handle cbh );
00084 
00085   //: Current value of the slider, in [0,1]
00086   float value() const { return loc_; }
00087 
00088   //: Set the slider to value \a v.
00089   //
00090   // \a v will be clipped to [0,1]. The callbacks associated with the
00091   // slider will be called, as if the slider was changed
00092   // interactively.
00093   void set_value( float v );
00094 
00095   //: Set the slider to value \a v.
00096   //
00097   // \a v will be clipped to [0,1]. The callbacks will not be called.
00098   void set_value_no_callbacks( float v );
00099 
00100   ~vgui_slider_tableau();
00101 
00102   virtual bool handle(const vgui_event&);
00103 
00104  private:
00105   //: Draw the slider at the current position
00106   void draw_bar() const;
00107 
00108   //: Call each of the callbacks in \a cbs
00109   void call_callbacks( vcl_list< callback_info > const& cbs );
00110 
00111   //: Update the slider location
00112   // \a newx and \a newy give the latest mouse position in window coordinates
00113   void update_location( int newx, int newy );
00114 
00115   friend struct vgui_slider_tableau_new;
00116 
00117   //: Constructor - don't use this, use vgui_slider_tableau_new
00118   vgui_slider_tableau( slider_type type );
00119 
00120   //: Current location of slider, in [0:1]
00121   float loc_;
00122 
00123   //: Slider is horizontal or vertical?
00124   bool horiz_;
00125 
00126   //: Mouse is currently pressed?
00127   bool down_;
00128 
00129   //: Location of bar when mouse was pressed
00130   float last_loc_;
00131 
00132   //: Window coords of last mouse press
00133   int last_x_, last_y_;
00134 
00135   //: Callbacks called on every change of the slider
00136   vcl_list< callback_info > motion_callbacks_;
00137 
00138   //: Callbacks called only at the final position of the slider
00139   vcl_list< callback_info > final_callbacks_;
00140 };
00141 
00142 //: Create a smart-pointer to a vgui_displaybase_tableau tableau.
00143 struct vgui_slider_tableau_new : public vgui_slider_tableau_sptr
00144 {
00145   typedef vgui_slider_tableau_sptr base;
00146   vgui_slider_tableau_new( vgui_slider_tableau::slider_type type )
00147     : base( new vgui_slider_tableau( type ) ) {}
00148 };
00149 
00150 
00151 #endif // vgui_slider_tableau_h_