widgets/scrollpane.cpp

Go to the documentation of this file.
00001 /* $Id: scrollpane.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2004 - 2012 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 as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /** @file */
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     // Recalculates the whole content size
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& /*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     //draws the scrollpane background
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 } // namespace gui
00188 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:15 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs