Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

pgscrollarea.cpp

Go to the documentation of this file.
00001 /*
00002     ParaGUI - crossplatform widgetset
00003     Copyright (C) 2000-2004  Alexander Pipelka
00004  
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009  
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014  
00015     You should have received a copy of the GNU Library General Public
00016     License along with this library; if not, write to the Free
00017     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  
00019     Alexander Pipelka
00020     pipelka@teleweb.at
00021  
00022     Last Update:      $Author: mbickel $
00023     Update Date:      $Date: 2007-04-13 16:16:04 $
00024     Source File:      $Source: /home/cvspsrv/cvsroot/games/asc/source/libs/paragui/src/widgets/pgscrollarea.cpp,v $
00025     CVS/RCS Revision: $Revision: 1.2 $
00026     Status:           $State: Exp $
00027 */
00028 
00029 #include <algorithm>
00030 
00031 #include "pgscrollarea.h"
00032 #include "pglog.h"
00033 #include "pgapplication.h"
00034 
00035 PG_ScrollArea::PG_ScrollArea(PG_Widget* parent, const PG_Rect& r) : PG_Widget(parent, r),
00036 my_shiftx(false), my_shifty(false), my_AddResizeParent(false), my_RemoveResizeParent(false) {}
00037 
00038 PG_ScrollArea::~PG_ScrollArea() {}
00039 
00040 void PG_ScrollArea::ScrollTo( int x, int y) {
00041    if ( x < 0 )
00042       x = 0;
00043 
00044    if ( y < 0 )
00045       y = 0;
00046 
00047 
00048         if (my_area.x == x && my_area.y == y)
00049                 return;
00050 
00051         if(y > my_area.h - my_height ) {  
00052       if ( my_area.h > my_height ) {
00053                    y = my_area.h - my_height;
00054          if ( y < 0 )
00055             y = 0;
00056       } else
00057          y = 0;
00058         }
00059 
00060         if(x > my_area.w - my_width ) {  
00061       if ( my_area.w > my_width ) {
00062                    x = my_area.w - my_width;
00063          if ( x < 0 )
00064             x = 0;
00065       } else
00066          x = 0;
00067         }
00068 
00069         Sint32 dx = my_area.x - x;
00070         Sint32 dy = my_area.y - y;
00071 
00072         my_area.x = x;
00073         my_area.y = y;
00074 
00075         if(GetChildList() == NULL) {
00076                 Update();
00077                 return;
00078         }
00079 
00080         for(PG_Widget* i = GetChildList()->first(); i != NULL; i = i->next()) {
00081                 i->MoveRect(i->x + dx, i->y + dy);
00082         }
00083 
00084         Update();
00085 }
00086 
00087 void PG_ScrollArea::AddChild(PG_Widget* child) {
00088         PG_Widget::AddChild(child);
00089         child->MoveRect(child->x - my_area.x, child->y - my_area.y);
00090 
00091         if(child->x+child->w+my_area.x-my_xpos > my_area.w) {
00092                 my_area.w = child->x+child->w+my_area.x-my_xpos;
00093 
00094                 if(my_AddResizeParent) {
00095                         GetParent()->SizeWidget( my_area.w + GetParent()->GetBorderSize()*2, GetParent()->my_height);
00096                 }
00097                 sigAreaChangedWidth(this, my_area.w);
00098         }
00099         if(child->y+child->h+my_area.y-my_ypos > my_area.h) {
00100                 my_area.h = child->y+child->h+my_area.y-my_ypos;
00101 
00102                 if(my_AddResizeParent) {
00103                         GetParent()->SizeWidget(GetParent()->my_width, my_area.h + GetParent()->GetBorderSize()*2 );
00104                 }
00105                 sigAreaChangedHeight(this, my_area.h);
00106         }
00107 
00108         if(IsVisible()) {
00109                 child->Show();
00110         }
00111 }
00112 
00113 void PG_ScrollArea::ScrollToWidget(PG_Widget* widget, bool bVertical) {
00114         if(GetWidgetCount() == 0) {
00115                 return;
00116         }
00117 
00118         Uint16 ypos = 0;
00119         Uint16 xpos = 0;
00120 
00121         if(bVertical) {
00122                 // widget within visible area, no need to scroll
00123                 if(widget->y >= my_ypos && widget->y+widget->h <= my_ypos+my_height) {
00124                         return;
00125                 }
00126                 ypos = widget->y - my_ypos + my_area.y;
00127                 xpos = my_area.x;
00128                 if(my_area.h > my_height && ypos > my_area.h - my_height) {
00129                         ypos = my_area.h - my_height;
00130                 }
00131         } else {
00132                 // widget within visible area, no need to scroll
00133                 if(widget->x >= my_xpos && widget->x+widget->w <= my_xpos+my_width) {
00134                         return;
00135                 }
00136                 xpos = widget->x - my_xpos + my_area.x;
00137                 ypos = my_area.y;
00138                 if(my_area.w > my_width && xpos > my_area.w - my_width) {
00139                         xpos = my_area.w - my_width;
00140                 }
00141         }
00142 
00143         ScrollTo(xpos, ypos);
00144 }
00145 
00146 bool PG_ScrollArea::RemoveChild(PG_Widget* child) {
00147 
00148         // recalc scrollarea
00149         Uint16 w = 0;
00150         Uint16 h = 0;
00151 
00152         if(GetChildList() == NULL) {
00153                 return false;
00154         }
00155         if(GetChildList()->size() == 0) {
00156                 return false;
00157         }
00158 
00159         // remove widget
00160         PG_Rect r = *child;
00161         if(!PG_Widget::RemoveChild(child)) {
00162                 return false;
00163         }
00164 
00165         for(PG_Widget* i = GetChildList()->first(); i != NULL; i = i->next()) {
00166 
00167                 // check if i should move the widget (x)
00168                 if(my_shiftx && (i->x >= r.x+r.w)) {
00169                         i->MoveRect(i->x - r.w, i->y);
00170                 }
00171 
00172                 // check if i should move the widget (y)
00173                 if(my_shifty && (i->y >= r.y+r.h)) {
00174                         i->MoveRect(i->x, i->y - r.h);
00175                 }
00176 
00177                 // recalc new scrollarea
00178                 if(i->x+i->w+my_area.x-my_xpos > w) {
00179                         w = i->x+i->w+my_area.x-my_xpos;
00180                 }
00181                 if(i->y+i->h+my_area.y-my_ypos > h) {
00182                         h = i->y+i->h+my_area.y-my_ypos;
00183                 }
00184         }
00185 
00186         // signal changes
00187         if(w != my_area.w) {
00188                 my_area.w = w;
00189                 sigAreaChangedWidth(this, my_area.w);
00190 
00191                 if(my_RemoveResizeParent) {
00192                         GetParent()->SizeWidget(my_area.w, GetParent()->my_height);
00193                 }
00194         }
00195 
00196         if(h != my_area.h) {
00197                 my_area.h = h;
00198                 sigAreaChangedHeight(this, my_area.h);
00199 
00200                 if(my_RemoveResizeParent) {
00201                         GetParent()->SizeWidget(GetParent()->my_width, my_area.h);
00202                 }
00203         }
00204 
00205         Update();
00206         return true;
00207 }
00208 
00209 void PG_ScrollArea::RemoveAll() {
00210         if(GetChildList() == NULL) {
00211                 return;
00212         }
00213         GetChildList()->clear();
00214 
00215         if(my_shiftx) {
00216                 my_area.w = 0;
00217                 sigAreaChangedWidth(this, 0);
00218         }
00219 
00220         if(my_shifty) {
00221                 my_area.h = 0;
00222                 sigAreaChangedHeight(this, 0);
00223         }
00224 
00225         Update();
00226 }
00227 
00228 void PG_ScrollArea::DeleteAll() {
00229         if(GetChildList() == NULL) {
00230                 return;
00231         }
00232 
00233         PG_Widget* list = GetChildList()->first();
00234 
00235         GetChildList()->clear();
00236         Update();
00237 
00238         for(; list != NULL; ) {
00239                 PG_Widget* w = list;
00240                 list = list->next();
00241                 w->SetVisible(false);
00242                 delete w;
00243         }
00244         my_area.w = 0;
00245         my_area.h = 0;
00246         sigAreaChangedWidth(this, my_area.w);
00247         sigAreaChangedHeight(this, my_area.h);
00248 }
00249 
00250 Uint16 PG_ScrollArea::GetWidgetCount() {
00251         if(GetChildList() == NULL) {
00252                 return 0;
00253         }
00254 
00255         return GetChildList()->size();
00256 }
00257 
00258 Uint16 PG_ScrollArea::GetScrollPosX() {
00259         return my_area.x;
00260 }
00261 
00262 Uint16 PG_ScrollArea::GetScrollPosY() {
00263         return my_area.y;
00264 }
00265 
00266 void PG_ScrollArea::SetShiftOnRemove(bool shiftx, bool shifty) {
00267         my_shiftx = shiftx;
00268         my_shifty = shifty;
00269 }
00270 
00271 void PG_ScrollArea::SetAreaWidth(Uint16 w) {
00272         if(my_area.w == w) {
00273                 return;
00274         }
00275         my_area.w = w;
00276         sigAreaChangedWidth(this, my_area.w);
00277 }
00278 
00279 void PG_ScrollArea::SetAreaHeight(Uint16 h) {
00280         if(my_area.h == h) {
00281                 return;
00282         }
00283         my_area.h = h;
00284         sigAreaChangedHeight(this, my_area.h);
00285 }
00286 
00287 PG_Widget* PG_ScrollArea::GetFirstInList() {
00288         PG_RectList* list = GetChildList();
00289         if(list == NULL) {
00290                 return NULL;
00291         }
00292         return list->first();
00293 }
00294 
00295 void PG_ScrollArea::SetResizeParent(bool bRemove, bool bAdd) {
00296         if(GetParent() == NULL) {
00297                 return;
00298         }
00299 
00300         my_RemoveResizeParent = bRemove;
00301         my_AddResizeParent = bAdd;
00302 }
00303 
00304 void PG_ScrollArea::eventSizeWidget(Uint16 w, Uint16 h) {
00305         if(w != my_width) {
00306                 this->w = w;
00307                 // my_area doesn't change, so why should we issue a AreaChange event ? (Martin)
00308                 // sigAreaChangedWidth(this, my_area.w);
00309         }
00310         if(h != my_height) {
00311                 this->h = h;
00312                 // sigAreaChangedHeight(this, my_area.h);
00313         }
00314 }

Generated on Tue Jun 24 01:27:49 2008 for Advanced Strategic Command by  doxygen 1.4.2