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