Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define GETTEXT_DOMAIN "wesnoth-lib"
00019
00020 #include "global.hpp"
00021
00022 #include <algorithm>
00023
00024 #include "widgets/scrollpane.hpp"
00025
00026 namespace {
00027 class widget_finder {
00028 public:
00029 widget_finder(gui::widget* w) : w_(w) {};
00030
00031 bool operator()(const std::pair<int, gui::scrollpane::scrollpane_widget>& p)
00032 {
00033 if(p.second.w == w_)
00034 return true;
00035 return false;
00036 }
00037 private:
00038 gui::widget* w_;
00039 };
00040 }
00041
00042 namespace gui {
00043
00044 scrollpane::scrollpane(CVideo &video) : scrollarea(video), border_(5)
00045 {
00046 content_pos_.x = 0;
00047 content_pos_.y = 0;
00048 update_content_size();
00049 set_scroll_rate(40);
00050 }
00051
00052 void scrollpane::clear()
00053 {
00054 content_.clear();
00055 update_content_size();
00056 }
00057
00058 void scrollpane::set_location(SDL_Rect const& rect)
00059 {
00060 scrollarea::set_location(rect);
00061 set_shown_size(client_area().h);
00062 update_widget_positions();
00063 }
00064
00065 void scrollpane::hide(bool value)
00066 {
00067 for(widget_map::iterator itor = content_.begin(); itor != content_.end(); ++itor) {
00068 itor->second.w->hide_override(value);
00069 }
00070 }
00071
00072 void scrollpane::add_widget(widget* w, int x, int y, int z_order)
00073 {
00074 if (w == NULL)
00075 return;
00076
00077 widget_map::iterator itor = std::find_if(content_.begin(), content_.end(), widget_finder(w));
00078 if (itor != content_.end())
00079 return;
00080
00081 scrollpane_widget spw(w, x, y, z_order);
00082
00083 w->set_clip_rect(client_area());
00084 content_.insert(std::pair<int, scrollpane_widget>(z_order, spw));
00085
00086 position_widget(spw);
00087
00088
00089 update_content_size();
00090 }
00091
00092 void scrollpane::remove_widget(widget* w)
00093 {
00094 widget_map::iterator itor = std::find_if(content_.begin(), content_.end(), widget_finder(w));
00095
00096 if (itor != content_.end())
00097 content_.erase(itor);
00098
00099 update_content_size();
00100 }
00101
00102 void scrollpane::set_inner_location(const SDL_Rect& )
00103 {
00104 for(widget_map::iterator itor = content_.begin(); itor != content_.end(); ++itor) {
00105 itor->second.w->set_clip_rect(client_area());
00106 }
00107 }
00108
00109 void scrollpane::draw()
00110 {
00111
00112 }
00113
00114 void scrollpane::scroll(unsigned int pos)
00115 {
00116 if (static_cast<int>(pos) == content_pos_.y)
00117 return;
00118
00119 content_pos_.y = pos;
00120 update_widget_positions();
00121 }
00122
00123 void scrollpane::update_widget_positions()
00124 {
00125 widget_map::iterator itor;
00126 std::vector<bool> hidden(content_.size());
00127 int i = 0;
00128 for(itor = content_.begin(); itor != content_.end(); ++itor) {
00129 hidden[i++] = (itor->second.w->state_ == HIDDEN);
00130 itor->second.w->hide();
00131 }
00132
00133 for(itor = content_.begin(); itor != content_.end(); ++itor) {
00134 position_widget(itor->second);
00135 }
00136
00137 i = 0;
00138 for(itor = content_.begin(); itor != content_.end(); ++itor) {
00139 if (!hidden[i++])
00140 itor->second.w->hide(false);
00141 }
00142
00143 set_dirty();
00144 }
00145
00146 void scrollpane::position_widget(scrollpane_widget& spw)
00147 {
00148 spw.w->set_location(spw.x + location().x + border_,
00149 spw.y + location().y - content_pos_.y + border_);
00150 }
00151
00152 SDL_Rect scrollpane::client_area() const
00153 {
00154 SDL_Rect res;
00155
00156 res.x = location().x + border_;
00157 res.y = location().y + border_;
00158 res.w = location().w > 2 * border_ ? location().w - 2 * border_ : 0;
00159 res.h = location().h > 2 * border_ ? location().h - 2 * border_ : 0;
00160
00161 return res;
00162 }
00163
00164 void scrollpane::update_content_size()
00165 {
00166 unsigned int maxx = 0;
00167 unsigned int maxy = 0;
00168
00169 for(widget_map::iterator itor = content_.begin(); itor != content_.end(); ++itor) {
00170 if(itor->second.x + itor->second.w->width() > maxx) {
00171 maxx = itor->second.x + itor->second.w->width();
00172 }
00173 if(itor->second.y + itor->second.w->height() > maxy) {
00174 maxy = itor->second.y + itor->second.w->height();
00175 }
00176 }
00177
00178 content_pos_.w = maxx;
00179 content_pos_.h = maxy;
00180
00181 set_full_size(maxy);
00182 set_shown_size(client_area().h);
00183
00184 set_dirty();
00185 }
00186
00187 }
00188