Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #define GETTEXT_DOMAIN "wesnoth-lib"
00017
00018 #include "global.hpp"
00019
00020 #include "widgets/slider.hpp"
00021 #include "game_config.hpp"
00022 #include "font.hpp"
00023 #include "image.hpp"
00024 #include "sound.hpp"
00025 #include "video.hpp"
00026
00027
00028 namespace {
00029 const std::string slider_image = "buttons/slider.png";
00030 const std::string selected_image = "buttons/slider-selected.png";
00031 }
00032
00033 namespace gui {
00034
00035 slider::slider(CVideo &video)
00036 : widget(video), image_(image::get_image(slider_image)),
00037 highlightedImage_(image::get_image(selected_image)),
00038 min_(-100000), max_(100000), value_(0),
00039 increment_(1), value_change_(false), state_(NORMAL)
00040 {
00041 }
00042
00043 void slider::enable(bool new_val)
00044 {
00045 if(new_val != enabled())
00046 {
00047 state_ = NORMAL;
00048 widget::enable(new_val);
00049 }
00050 }
00051
00052 void slider::set_location(SDL_Rect const &rect)
00053 {
00054 SDL_Rect r = rect;
00055 r.h = image_->h;
00056 widget::set_location(r);
00057 }
00058
00059 void slider::set_min(int value)
00060 {
00061 min_ = value;
00062 if (value_ < min_) {
00063 value_ = min_;
00064 value_change_ = true;
00065 }
00066 set_dirty(true);
00067 }
00068
00069 void slider::set_max(int value)
00070 {
00071 max_ = value;
00072 if (value_ > max_) {
00073 value_ = max_;
00074 value_change_ = true;
00075 }
00076 set_dirty(true);
00077 }
00078
00079 void slider::set_value(int value)
00080 {
00081 if (value > max_)
00082 value = max_;
00083 if (value < min_)
00084 value = min_;
00085
00086 if (increment_ > 1) {
00087 int hi = increment_ / 2;
00088 value = ((value + hi) / increment_) * increment_;
00089 }
00090
00091 if (value == value_)
00092 return;
00093
00094 value_ = value;
00095 value_change_ = true;
00096 set_dirty(true);
00097 }
00098
00099 void slider::set_increment(int increment)
00100 {
00101 increment_ = increment;
00102 }
00103
00104 int slider::value() const
00105 {
00106 return value_;
00107 }
00108
00109 int slider::max_value() const
00110 {
00111 return max_;
00112 }
00113
00114 bool slider::value_change()
00115 {
00116 if (value_change_) {
00117 value_change_ = false;
00118 return true;
00119 }
00120 return false;
00121 }
00122
00123 SDL_Rect slider::slider_area() const
00124 {
00125 static const SDL_Rect default_value = {0,0,0,0};
00126 SDL_Rect const &loc = location();
00127 if (image_.null() || image_->w >= loc.w)
00128 return default_value;
00129
00130 int xpos = loc.x + (value_ - min_) *
00131 static_cast<int>(loc.w - image_->w) / (max_ - min_);
00132 return create_rect(xpos, loc.y, image_->w, image_->h);
00133 }
00134
00135 void slider::draw_contents()
00136 {
00137 surface image(state_ != NORMAL ? highlightedImage_ : image_);
00138 if (image == NULL)
00139 return;
00140 SDL_Color line_color = font::NORMAL_COLOR;
00141 if (!enabled()) {
00142 image = greyscale_image(image);
00143 line_color = font::DISABLED_COLOR;
00144 }
00145
00146 SDL_Rect const &loc = location();
00147 if (image->w >= loc.w)
00148 return;
00149
00150 surface screen = video().getSurface();
00151
00152 SDL_Rect line_rect = create_rect(loc.x + image->w / 2
00153 , loc.y + loc.h / 2
00154 , loc.w - image->w
00155 , 1);
00156
00157 sdl_fill_rect(screen, &line_rect, SDL_MapRGB(screen->format,
00158 line_color.r, line_color.g, line_color.b));
00159
00160 SDL_Rect const &slider = slider_area();
00161 video().blit_surface(slider.x, slider.y, image);
00162 }
00163
00164 void slider::set_slider_position(int x)
00165 {
00166 SDL_Rect const &loc = location();
00167 int tmp = x - loc.x - image_->w / 2;
00168 if (tmp < 0)
00169 tmp = 0;
00170 if (tmp > loc.w - image_->w)
00171 tmp = loc.w - image_->w;
00172
00173 set_value(tmp * (max_ - min_) / static_cast<int>(loc.w - image_->w) + min_);
00174 }
00175
00176 void slider::mouse_motion(const SDL_MouseMotionEvent& event)
00177 {
00178 if (state_ == NORMAL || state_ == ACTIVE) {
00179 bool on = point_in_rect(event.x, event.y, slider_area());
00180 state_ = on ? ACTIVE : NORMAL;
00181 } else if (state_ == CLICKED || state_ == DRAGGED) {
00182 state_ = DRAGGED;
00183 bool prev_change = value_change_;
00184 value_change_ = false;
00185 set_slider_position(event.x);
00186 if(value_change_) {
00187 sound::play_UI_sound(game_config::sounds::slider_adjust);
00188 } else {
00189 value_change_ = prev_change;
00190 }
00191 }
00192 }
00193
00194 void slider::mouse_down(const SDL_MouseButtonEvent& event)
00195 {
00196 if (event.button != SDL_BUTTON_LEFT || !point_in_rect(event.x, event.y, location()))
00197 return;
00198
00199 state_ = CLICKED;
00200 bool prev_change = value_change_;
00201 value_change_ = false;
00202 set_focus(true);
00203 set_slider_position(event.x);
00204 if(value_change_) {
00205 sound::play_UI_sound(game_config::sounds::slider_adjust);
00206 } else {
00207 sound::play_UI_sound(game_config::sounds::button_press);
00208 value_change_ = prev_change;
00209 }
00210 }
00211
00212 bool slider::requires_event_focus(const SDL_Event* event) const
00213 {
00214 if(!focus_ || !enabled() || hidden()) {
00215 return false;
00216 }
00217 if(event == NULL) {
00218
00219 return true;
00220 }
00221
00222 if(event->type == SDL_KEYDOWN) {
00223 SDLKey key = event->key.keysym.sym;
00224 switch(key) {
00225 case SDLK_LEFT:
00226 case SDLK_RIGHT:
00227 return true;
00228 default:
00229 break;
00230 }
00231 }
00232
00233 return false;
00234 }
00235
00236 void slider::handle_event(const SDL_Event& event)
00237 {
00238 if (!enabled() || hidden())
00239 return;
00240
00241 STATE start_state = state_;
00242
00243 switch(event.type) {
00244 case SDL_MOUSEBUTTONUP:
00245 if (!mouse_locked())
00246 state_ = NORMAL;
00247 break;
00248 case SDL_MOUSEBUTTONDOWN:
00249 if (!mouse_locked())
00250 mouse_down(event.button);
00251 break;
00252 case SDL_MOUSEMOTION:
00253 if (!mouse_locked())
00254 mouse_motion(event.motion);
00255 break;
00256 case SDL_KEYDOWN:
00257 if(focus(&event)) {
00258 const SDL_keysym& key = reinterpret_cast<const SDL_KeyboardEvent&>(event).keysym;
00259 const int c = key.sym;
00260 if(c == SDLK_LEFT) {
00261 sound::play_UI_sound(game_config::sounds::slider_adjust);
00262 set_value(value_ - increment_);
00263 } else if(c == SDLK_RIGHT) {
00264 sound::play_UI_sound(game_config::sounds::slider_adjust);
00265 set_value(value_ + increment_);
00266 }
00267 }
00268 break;
00269 default:
00270 return;
00271 }
00272 if (start_state != state_)
00273 set_dirty(true);
00274 }
00275
00276 template<typename T>
00277 list_slider<T>::list_slider(CVideo &video) :
00278 slider(video)
00279 {
00280 set_min(0);
00281 set_increment(1);
00282 slider::set_value(0);
00283 }
00284
00285 template<typename T>
00286 list_slider<T>::list_slider(CVideo &video, const std::vector<T> &items) :
00287 slider(video),
00288 items_(items)
00289 {
00290 set_min(0);
00291 set_increment(1);
00292 if(items.size() > 0)
00293 {
00294 set_max(items.size() - 1);
00295 }
00296 slider::set_value(0);
00297 }
00298
00299 template<typename T>
00300 const T& list_slider<T>::item_selected() const
00301 {
00302 return items_[value()];
00303 }
00304
00305 template<typename T>
00306 bool list_slider<T>::select_item(const T& item)
00307 {
00308 for(unsigned i = 0, nb = items_.size(); i < nb; ++i)
00309 {
00310 if(item == items_[i])
00311 {
00312 slider::set_value(i);
00313 return true;
00314 }
00315 }
00316 return false;
00317 }
00318
00319 template<typename T>
00320 void list_slider<T>::set_items(const std::vector<T> &items)
00321 {
00322 items_ = items;
00323 if(items.size() > 0)
00324 {
00325 set_max(items.size() - 1);
00326 }
00327 slider::set_value(0);
00328 }
00329
00330
00331 template class list_slider< double >;
00332 template class list_slider< int >;
00333 template class list_slider< std::string >;
00334
00335 }