00001 /* $Id: scrollbar.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */ 00002 /* 00003 Copyright (C) 2008 - 2012 by Mark de Wever <koraq@xs4all.nl> 00004 Part of the Battle for Wesnoth Project http://www.wesnoth.org/ 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY. 00012 00013 See the COPYING file for more details. 00014 */ 00015 00016 #ifndef GUI_WIDGETS_SCROLLBAR_HPP_INCLUDED 00017 #define GUI_WIDGETS_SCROLLBAR_HPP_INCLUDED 00018 00019 #include "gui/auxiliary/notifier.hpp" 00020 #include "gui/widgets/control.hpp" 00021 00022 #include <boost/function.hpp> 00023 00024 namespace gui2 { 00025 00026 /** 00027 * Base class for a scroll bar. 00028 * 00029 * class will be subclassed for the horizontal and vertical scroll bar. 00030 * It might be subclassed for a slider class. 00031 * 00032 * To make this class generic we talk a lot about offset and length and use 00033 * pure virtual functions. The classes implementing us can use the heights or 00034 * widths, whichever is applicable. 00035 * 00036 * The NOTIFY_MODIFIED event is send when the position of scrollbar is changed. 00037 * 00038 * Common signal handlers: 00039 * - connect_signal_notify_modified 00040 */ 00041 class tscrollbar_ : public tcontrol 00042 { 00043 /** @todo Abstract the code so this friend is no longer needed. */ 00044 friend class tslider; 00045 public: 00046 00047 tscrollbar_(); 00048 00049 /** 00050 * scroll 'step size'. 00051 * 00052 * When scrolling we always scroll a 'fixed' amount, these are the 00053 * parameters for these amounts. 00054 */ 00055 enum tscroll { 00056 BEGIN, /**< Go to begin position. */ 00057 ITEM_BACKWARDS, /**< Go one item towards the begin. */ 00058 HALF_JUMP_BACKWARDS, /**< Go half the visible items towards the begin. */ 00059 JUMP_BACKWARDS, /**< Go the visibile items towards the begin. */ 00060 END, /**< Go to the end position. */ 00061 ITEM_FORWARD, /**< Go one item towards the end. */ 00062 HALF_JUMP_FORWARD, /**< Go half the visible items towards the end. */ 00063 JUMP_FORWARD }; /**< Go the visible items towards the end. */ 00064 00065 /** 00066 * Sets the item position. 00067 * 00068 * We scroll a predefined step. 00069 * 00070 * @param scroll 'step size' to scroll. 00071 */ 00072 void scroll(const tscroll scroll); 00073 00074 /** Is the positioner at the beginning of the scrollbar? */ 00075 bool at_begin() const { return item_position_ == 0; } 00076 00077 /** 00078 * Is the positioner at the and of the scrollbar? 00079 * 00080 * Note both begin and end might be true at the same time. 00081 */ 00082 bool at_end() const 00083 { return item_position_ + visible_items_ >= item_count_; } 00084 00085 /** Are all items visible? */ 00086 bool all_items_visible() const { return visible_items_ >= item_count_; } 00087 00088 /***** ***** ***** ***** layout functions ***** ***** ***** *****/ 00089 00090 /** Inherited from tcontrol. */ 00091 void place(const tpoint& origin, const tpoint& size); 00092 00093 /***** ***** ***** ***** Inherited ***** ***** ***** *****/ 00094 00095 /** Inherited from tcontrol. */ 00096 void set_active(const bool active) 00097 { if(get_active() != active) set_state(active ? ENABLED : DISABLED); }; 00098 00099 /** Inherited from tcontrol. */ 00100 bool get_active() const { return state_ != DISABLED; } 00101 00102 /** Inherited from tcontrol. */ 00103 unsigned get_state() const { return state_; } 00104 00105 /***** ***** ***** setters / getters for members ***** ****** *****/ 00106 00107 void set_item_count(const unsigned item_count) 00108 { item_count_ = item_count; recalculate(); } 00109 unsigned get_item_count() const { return item_count_; } 00110 00111 /** 00112 * Note the position isn't guaranteed to be the wanted position 00113 * the step size is honoured. The value will be rouded down. 00114 */ 00115 void set_item_position(const unsigned item_position); 00116 unsigned get_item_position() const { return item_position_; } 00117 00118 unsigned get_visible_items() const { return visible_items_; } 00119 void set_visible_items(const unsigned visible_items) 00120 { visible_items_ = visible_items; recalculate(); } 00121 00122 unsigned get_step_size() const { return step_size_; } 00123 void set_step_size(const unsigned step_size) 00124 { step_size_ = step_size; recalculate(); } 00125 00126 protected: 00127 unsigned get_positioner_offset() const { return positioner_offset_; } 00128 00129 unsigned get_positioner_length() const { return positioner_length_; } 00130 00131 /** After a recalculation the canvasses also need to be updated. */ 00132 virtual void update_canvas(); 00133 00134 /** 00135 * Callback for subclasses to get notified about positioner movement. 00136 * 00137 * @todo This is a kind of hack due to the fact there's no simple 00138 * callback slot mechanism. See whether we can implement a generic way to 00139 * attach callback which would remove quite some extra code. 00140 */ 00141 virtual void child_callback_positioner_moved() {} 00142 private: 00143 00144 /** 00145 * Possible states of the widget. 00146 * 00147 * Note the order of the states must be the same as defined in settings.hpp. 00148 */ 00149 enum tstate { ENABLED, DISABLED, PRESSED, FOCUSSED, COUNT }; 00150 00151 void set_state(const tstate state); 00152 /** 00153 * Current state of the widget. 00154 * 00155 * The state of the widget determines what to render and how the widget 00156 * reacts to certain 'events'. 00157 */ 00158 tstate state_; 00159 00160 /** The number of items the scrollbar 'holds'. */ 00161 unsigned item_count_; 00162 00163 /** The item the positioner is at, starts at 0. */ 00164 unsigned item_position_; 00165 00166 /** 00167 * The number of items which can be shown at the same time. 00168 * 00169 * As long as all items are visible we don't need to scroll. 00170 */ 00171 unsigned visible_items_; 00172 00173 /** 00174 * Number of items moved when scrolling. 00175 * 00176 * The step size is the minimum number of items we scroll through when we 00177 * move. Normally this value is 1, we can move per item. But for example 00178 * sliders want for example to move per 5 items. 00179 */ 00180 unsigned step_size_; 00181 00182 /** 00183 * Number of pixels per step. 00184 * 00185 * The number of pixels the positioner needs to move to go to the next step. 00186 * Note if there is too little space it can happen 1 pixel does more than 1 00187 * step. 00188 */ 00189 float pixels_per_step_; 00190 00191 /** 00192 * The position the mouse was at the last movement. 00193 * 00194 * This is used during dragging the positioner. 00195 */ 00196 tpoint mouse_; 00197 00198 /** 00199 * The start offset of the positioner. 00200 * 00201 * This takes the offset before in consideration. 00202 */ 00203 unsigned positioner_offset_; 00204 00205 /** The current length of the positioner. */ 00206 unsigned positioner_length_; 00207 00208 /***** ***** ***** ***** Pure virtual functions ***** ***** ***** *****/ 00209 00210 /** Get the length of the scrollbar. */ 00211 virtual unsigned get_length() const = 0; 00212 00213 /** The minimum length of the positioner. */ 00214 virtual unsigned minimum_positioner_length() const = 0; 00215 00216 /** The maximum length of the positioner. */ 00217 virtual unsigned maximum_positioner_length() const = 0; 00218 00219 /** 00220 * The number of pixels we can't use since they're used for borders. 00221 * 00222 * These are the pixels before the widget (left side if horizontal, 00223 * top side if vertical). 00224 */ 00225 virtual unsigned offset_before() const = 0; 00226 00227 /** 00228 * The number of pixels we can't use since they're used for borders. 00229 * 00230 * These are the pixels after the widget (right side if horizontal, 00231 * bottom side if vertical). 00232 */ 00233 virtual unsigned offset_after() const = 0; 00234 00235 /** 00236 * Is the coordinate on the positioner? 00237 * 00238 * @param coordinate Coordinate to test whether it's on the 00239 * positioner. 00240 * 00241 * @returns Whether the location on the positioner is. 00242 */ 00243 virtual bool on_positioner(const tpoint& coordinate) const = 0; 00244 00245 /** 00246 * Is the coordinate on the bar? 00247 * 00248 * @param coordinate Coordinate to test whether it's on the 00249 * bar. 00250 * 00251 * @returns Whether the location on the bar is. 00252 * @retval -1 Coordinate is on the bar before positioner. 00253 * @retval 0 Coordinate is not on the bar. 00254 * @retval 1 Coordinate is on the bar after the positioner. 00255 */ 00256 virtual int on_bar(const tpoint& coordinate) const = 0; 00257 00258 /** 00259 * Gets the relevant difference in between the two positions. 00260 * 00261 * This function is used to determine how much the positioner needs to be 00262 * moved. 00263 */ 00264 virtual int get_length_difference( 00265 const tpoint& original, const tpoint& current) const = 0; 00266 00267 /***** ***** ***** ***** Private functions ***** ***** ***** *****/ 00268 00269 /** 00270 * Updates the scrollbar. 00271 * 00272 * Needs to be called when someting changes eg number of items 00273 * or available size. It can only be called once we have a size 00274 * otherwise we can't calulate a thing. 00275 */ 00276 void recalculate(); 00277 00278 /** 00279 * Updates the positioner. 00280 * 00281 * This is a helper for recalculate(). 00282 */ 00283 void recalculate_positioner(); 00284 00285 /** 00286 * Moves the positioner. 00287 * 00288 * @param distance The distance moved, negative to begin, positive 00289 * to end. 00290 */ 00291 void move_positioner(const int distance); 00292 00293 /** Inherited from tcontrol. */ 00294 void load_config_extra(); 00295 00296 /***** ***** ***** signal handlers ***** ****** *****/ 00297 00298 void signal_handler_mouse_enter( 00299 const event::tevent event, bool& handled, bool& halt); 00300 00301 void signal_handler_mouse_motion( 00302 const event::tevent event 00303 , bool& handled 00304 , bool& halt 00305 , const tpoint& coordinate); 00306 00307 void signal_handler_mouse_leave(const event::tevent event, bool& handled); 00308 00309 void signal_handler_left_button_down( 00310 const event::tevent event, bool& handled); 00311 00312 void signal_handler_left_button_up( 00313 const event::tevent event, bool& handled); 00314 00315 }; 00316 00317 } // namespace gui2 00318 00319 #endif 00320
| Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:59 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |