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_