scrollpane.cpp

Go to the documentation of this file.
00001 /* $Id: scrollpane.cpp 23842 2008-02-16 08:47:16Z mordante $ */
00002 /*
00003    Copyright (C) 2004 - 2008 by Philippe Plantier <ayin@anathas.org>
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 version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 //! @file widgets/scrollpane.cpp
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     // Recalculates the whole content size
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& /*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     //draws the scrollpane background
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 } // namespace gui
00185 

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs