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 "gui/widgets/slider.hpp"
00019
00020 #include "foreach.hpp"
00021 #include "formatter.hpp"
00022 #include "gui/auxiliary/log.hpp"
00023 #include "gui/auxiliary/widget_definition/slider.hpp"
00024 #include "gui/auxiliary/window_builder/slider.hpp"
00025 #include "gui/widgets/window.hpp"
00026 #include "gui/widgets/settings.hpp"
00027 #include "sound.hpp"
00028
00029 #include <boost/bind.hpp>
00030
00031 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
00032 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
00033
00034 namespace gui2 {
00035
00036 REGISTER_WIDGET(slider)
00037
00038 static int distance(const int a, const int b)
00039 {
00040
00041
00042
00043
00044 int result = b - a;
00045 assert(result >= 0);
00046 return result;
00047 }
00048
00049 tslider::tslider():
00050 tscrollbar_(),
00051 best_slider_length_(0),
00052 minimum_value_(0),
00053 minimum_value_label_(),
00054 maximum_value_label_(),
00055 value_labels_()
00056 {
00057 connect_signal<event::SDL_KEY_DOWN>(boost::bind(
00058 &tslider::signal_handler_sdl_key_down, this, _2, _3, _5));
00059 connect_signal<event::LEFT_BUTTON_UP>(boost::bind(
00060 &tslider::signal_handler_left_button_up, this, _2, _3));
00061
00062 }
00063
00064 tpoint tslider::calculate_best_size() const
00065 {
00066 log_scope2(log_gui_layout, LOG_SCOPE_HEADER);
00067
00068
00069 tpoint result = tcontrol::calculate_best_size();
00070 if(best_slider_length_ != 0) {
00071
00072
00073 boost::intrusive_ptr<const tslider_definition::tresolution> conf =
00074 boost::dynamic_pointer_cast<const tslider_definition::tresolution>
00075 (config());
00076
00077 assert(conf);
00078
00079 result.x = conf->left_offset + best_slider_length_ + conf->right_offset;
00080 }
00081
00082 DBG_GUI_L << LOG_HEADER
00083 << " best_slider_length " << best_slider_length_
00084 << " result " << result
00085 << ".\n";
00086 return result;
00087
00088 }
00089
00090 void tslider::set_value(const int value)
00091 {
00092 if(value == get_value()) {
00093 return;
00094 }
00095
00096 if(value < minimum_value_) {
00097 set_value(minimum_value_);
00098 } else if(value > get_maximum_value()) {
00099 set_value(get_maximum_value());
00100 } else {
00101 set_item_position(distance(minimum_value_, value));
00102 }
00103 }
00104
00105 void tslider::set_minimum_value(const int minimum_value)
00106 {
00107 if(minimum_value == minimum_value_) {
00108 return;
00109 }
00110
00111
00112 assert(minimum_value <= get_maximum_value());
00113
00114 const int value = get_value();
00115 const int maximum_value = get_maximum_value();
00116 minimum_value_ = minimum_value;
00117
00118
00119 set_item_count(distance(minimum_value_, maximum_value) + 1);
00120
00121 if(value < minimum_value_) {
00122 set_item_position(0);
00123 } else {
00124 set_item_position(minimum_value_ + value);
00125 }
00126 }
00127
00128 void tslider::set_maximum_value(const int maximum_value)
00129 {
00130 if(maximum_value == get_maximum_value()) {
00131 return;
00132 }
00133
00134
00135 assert(minimum_value_ <= maximum_value);
00136
00137 const int value = get_value();
00138
00139
00140 set_item_count(distance(minimum_value_, maximum_value) + 1);
00141
00142 if(value > maximum_value) {
00143 set_item_position(get_maximum_value());
00144 } else {
00145 set_item_position(minimum_value_ + value);
00146 }
00147 }
00148
00149 t_string tslider::get_value_label() const
00150 {
00151 if(!value_labels_.empty()) {
00152 assert(value_labels_.size() == get_item_count());
00153 return value_labels_[get_item_position()];
00154 } else if(!minimum_value_label_.empty()
00155 && get_value() == get_minimum_value()) {
00156 return minimum_value_label_;
00157 } else if(!maximum_value_label_.empty()
00158 && get_value() == get_maximum_value()) {
00159 return maximum_value_label_;
00160 } else {
00161 return t_string((formatter() << get_value()).str());
00162 }
00163 }
00164
00165 void tslider::child_callback_positioner_moved()
00166 {
00167 sound::play_UI_sound(settings::sound_slider_adjust);
00168 }
00169
00170 unsigned tslider::minimum_positioner_length() const
00171 {
00172 boost::intrusive_ptr<const tslider_definition::tresolution> conf =
00173 boost::dynamic_pointer_cast<const tslider_definition::tresolution>(config());
00174 assert(conf);
00175 return conf->minimum_positioner_length;
00176 }
00177
00178 unsigned tslider::maximum_positioner_length() const
00179 {
00180 boost::intrusive_ptr<const tslider_definition::tresolution> conf =
00181 boost::dynamic_pointer_cast<const tslider_definition::tresolution>(config());
00182 assert(conf);
00183 return conf->maximum_positioner_length;
00184 }
00185
00186 unsigned tslider::offset_before() const
00187 {
00188 boost::intrusive_ptr<const tslider_definition::tresolution> conf =
00189 boost::dynamic_pointer_cast<const tslider_definition::tresolution>(config());
00190 assert(conf);
00191 return conf->left_offset;
00192 }
00193
00194 unsigned tslider::offset_after() const
00195 {
00196 boost::intrusive_ptr<const tslider_definition::tresolution> conf =
00197 boost::dynamic_pointer_cast<const tslider_definition::tresolution>(config());
00198 assert(conf);
00199 return conf->right_offset;
00200 }
00201
00202 bool tslider::on_positioner(const tpoint& coordinate) const
00203 {
00204
00205 return coordinate.x >= static_cast<int>(get_positioner_offset())
00206 && coordinate.x < static_cast<int>(get_positioner_offset() + get_positioner_length())
00207 && coordinate.y > 0
00208 && coordinate.y < static_cast<int>(get_height());
00209 }
00210
00211 int tslider::on_bar(const tpoint& coordinate) const
00212 {
00213
00214 if(static_cast<size_t>(coordinate.x) > get_width()
00215 || static_cast<size_t>(coordinate.y) > get_height()) {
00216 return 0;
00217 }
00218
00219
00220 if(static_cast<size_t>(coordinate.x) < get_positioner_offset()) {
00221 return -1;
00222 } else if(static_cast<size_t>(coordinate.x) >get_positioner_offset() + get_positioner_length()) {
00223 return 1;
00224 } else {
00225 return 0;
00226 }
00227 }
00228
00229 void tslider::update_canvas()
00230 {
00231
00232
00233 tscrollbar_::update_canvas();
00234
00235 foreach(tcanvas& tmp, canvas()) {
00236 tmp.set_variable("text", variant(get_value_label()));
00237 }
00238 }
00239
00240 const std::string& tslider::get_control_type() const
00241 {
00242 static const std::string type = "slider";
00243 return type;
00244 }
00245
00246 void tslider::handle_key_decrease(bool& handled)
00247 {
00248 DBG_GUI_E << LOG_HEADER << '\n';
00249
00250 handled = true;
00251
00252 scroll(tscrollbar_::ITEM_BACKWARDS);
00253 }
00254
00255 void tslider::handle_key_increase(bool& handled)
00256 {
00257 DBG_GUI_E << LOG_HEADER << '\n';
00258
00259 handled = true;
00260
00261 scroll(tscrollbar_::ITEM_FORWARD);
00262 }
00263
00264 void tslider::signal_handler_sdl_key_down(const event::tevent event
00265 , bool& handled
00266 , const SDLKey key)
00267 {
00268
00269 DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
00270
00271 if (key == SDLK_DOWN || key == SDLK_LEFT) {
00272 handle_key_decrease(handled);
00273 } else if (key == SDLK_UP || key == SDLK_RIGHT) {
00274 handle_key_increase(handled);
00275 } else {
00276
00277 }
00278 }
00279
00280 void tslider::signal_handler_left_button_up(
00281 const event::tevent event, bool& handled)
00282 {
00283 DBG_GUI_E << LOG_HEADER << ' ' << event << ".\n";
00284
00285 get_window()->keyboard_capture(this);
00286
00287 handled = true;
00288 }
00289
00290 }
00291