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

pgscrollwidget.cpp

Go to the documentation of this file.
00001 /*
00002     ParaGUI - crossplatform widgetset
00003     Copyright (C) 2000,2001,2002  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/pgscrollwidget.cpp,v $
00025     CVS/RCS Revision: $Revision: 1.2 $
00026     Status:           $State: Exp $
00027 */
00028 
00029 #include "pgscrollwidget.h"
00030 #include "pgscrollarea.h"
00031 #include "pgapplication.h"
00032 #include "pglog.h"
00033 
00034 PG_ScrollWidget::PG_ScrollWidget(PG_Widget* parent, const PG_Rect& r, const std::string& style) : PG_ThemeWidget(parent, r, style),
00035                 my_objVerticalScrollbar(NULL),
00036                 my_objHorizontalScrollbar(NULL) ,
00037       my_scrollarea(NULL),
00038       my_scrollLineSize(-1)
00039 {
00040         my_enableVerticalScrollbar = true;
00041         my_enableHorizontalScrollbar = true;
00042         my_widthScrollbar = my_heightHorizontalScrollbar = 5;
00043 
00044         // It is important to make sure that the substractions below won't
00045         // render values < 0 and, eventually,
00046         // surface widths such as 32768 or 65535 when cast to an unsigned type.
00047         // This can lead to segfaults later on in, for example, DrawGradient...
00048         if (my_widthScrollbar > r.my_width)
00049                 my_widthScrollbar = r.my_width;
00050 
00051         if (my_heightHorizontalScrollbar > r.my_height)
00052                 my_heightHorizontalScrollbar = r.my_height;
00053 
00054         my_objVerticalScrollbar = new PG_ScrollBar(this, PG_Rect(0,0,my_widthScrollbar,r.h), PG_ScrollBar::VERTICAL, IDWIDGETLIST_VSCROLL, style);
00055         my_objVerticalScrollbar->SetRange(0,0);
00056         my_widthScrollbar = my_objVerticalScrollbar->Width();
00057         my_objVerticalScrollbar->Hide();
00058         my_objVerticalScrollbar->sigScrollPos.connect(slot(*this, &PG_ScrollWidget::handleScrollPos));
00059         my_objVerticalScrollbar->sigScrollTrack.connect(slot(*this, &PG_ScrollWidget::handleScrollTrack));
00060 
00061         my_objHorizontalScrollbar = new PG_ScrollBar(this, PG_Rect(0,0,r.w, my_heightHorizontalScrollbar), PG_ScrollBar::HORIZONTAL, IDWIDGETLIST_HSCROLL, style);
00062         my_objHorizontalScrollbar->SetRange(0,0);
00063         my_heightHorizontalScrollbar = my_objHorizontalScrollbar->Height();
00064         my_objHorizontalScrollbar->Hide();
00065         my_objHorizontalScrollbar->sigScrollPos.connect(slot(*this, &PG_ScrollWidget::handleScrollPos));
00066         my_objHorizontalScrollbar->sigScrollTrack.connect(slot(*this, &PG_ScrollWidget::handleScrollTrack));
00067 
00068         my_scrollarea = new PG_ScrollArea(this);
00069         RecalcPositions(false,false);
00070         my_scrollarea->sigAreaChangedHeight.connect(slot(*this, &PG_ScrollWidget::handleAreaChangedHeight));
00071         my_scrollarea->sigAreaChangedHeight.connect(sigAreaChangedHeight.slot());
00072         my_scrollarea->sigAreaChangedWidth.connect(slot(*this, &PG_ScrollWidget::handleAreaChangedWidth));
00073         my_scrollarea->sigAreaChangedWidth.connect(sigAreaChangedWidth.slot());
00074         my_scrollarea->SetShiftOnRemove(false, false);
00075 }
00076 
00077 PG_ScrollWidget::~PG_ScrollWidget() {
00078         my_scrollarea->DeleteAll();
00079 }
00080 
00081 void PG_ScrollWidget::CalcScrollbarVisibility() {
00082         bool origV = !my_objVerticalScrollbar->IsNull();
00083         bool origH = !my_objHorizontalScrollbar->IsNull();
00084 
00085         bool v;
00086         bool h;
00087 
00088         int area_width = my_width - my_bordersize*2;
00089         int area_height = my_height - my_bordersize*2;
00090 
00091         if ( my_scrollarea->GetAreaHeight() > area_height && my_enableVerticalScrollbar ) {
00092                 v = true;
00093                 area_width -= my_widthScrollbar;
00094         } else
00095                 v = false;
00096 
00097         if ( my_scrollarea->GetAreaWidth() > area_width && my_enableHorizontalScrollbar ) {
00098                 h = true;
00099                 area_height -= my_heightHorizontalScrollbar;
00100         } else
00101                 h = false;
00102 
00104         if ( my_scrollarea->GetAreaHeight() > area_height && my_enableVerticalScrollbar ) {
00105                 v = true;
00106         } else
00107                 v = false;
00108 
00109         RecalcPositions( v, h );
00110 
00111         if ( origV != v ) {
00112                 if ( v )
00113                         my_objVerticalScrollbar->Show();
00114                 else
00115                         my_objVerticalScrollbar->Hide();
00116         }
00117 
00118         if ( origH != h ) {
00119                 if ( h )
00120                         my_objHorizontalScrollbar->Show();
00121                 else
00122                         my_objHorizontalScrollbar->Hide();
00123         }
00124 
00125 }
00126 
00127 
00128 
00129 void PG_ScrollWidget::RecalcPositions(bool bV, bool bH) {
00130         PG_Rect my_rectVerticalScrollbar = *my_objVerticalScrollbar;
00131         PG_Rect my_rectHorizontalScrollbar = *my_objHorizontalScrollbar;
00132         PG_Rect my_rectList = *my_scrollarea;
00133 
00134         // only vertical
00135         if(bV && !bH) {
00136                 my_rectVerticalScrollbar.SetRect(
00137                     my_width - (my_widthScrollbar + my_bordersize),
00138                     my_bordersize,
00139                     my_widthScrollbar,
00140                     my_height - my_bordersize*2);
00141                 my_rectHorizontalScrollbar.SetRect(0,0,0,0);
00142         }
00143 
00144         // only horizontal
00145         if(!bV && bH) {
00146                 my_rectHorizontalScrollbar.SetRect(
00147                     my_bordersize,
00148                     my_height - (my_heightHorizontalScrollbar + my_bordersize),
00149                     my_width - my_bordersize*2,
00150                     my_heightHorizontalScrollbar);
00151                 my_rectVerticalScrollbar.SetRect(0,0,0,0);
00152         }
00153 
00154         // both
00155         if(bV && bH) {
00156                 my_rectVerticalScrollbar.SetRect(
00157                     my_width - (my_widthScrollbar + my_bordersize),
00158                     my_bordersize,
00159                     my_widthScrollbar,
00160                     my_height - (my_heightHorizontalScrollbar + my_bordersize*2));
00161 
00162                 my_rectHorizontalScrollbar.SetRect(
00163                     my_bordersize,
00164                     my_height - (my_heightHorizontalScrollbar + my_bordersize),
00165                     my_width - (my_widthScrollbar+my_bordersize*2),
00166                     my_heightHorizontalScrollbar);
00167         }
00168 
00169         // none
00170         if(!bV && !bH) {
00171                 my_rectHorizontalScrollbar.SetRect(0,0,0,0);
00172                 my_rectVerticalScrollbar.SetRect(0,0,0,0);
00173         }
00174 
00175         // scrollarea
00176         my_rectList.SetRect(
00177             my_bordersize, my_bordersize,
00178             my_width - (my_rectVerticalScrollbar.w + my_bordersize*2),
00179             my_height - (my_rectHorizontalScrollbar.h + my_bordersize*2));
00180 
00181         if(*my_objVerticalScrollbar != my_rectVerticalScrollbar) {
00182                 my_objVerticalScrollbar->MoveWidget(my_rectVerticalScrollbar);
00183         }
00184 
00185         if(*my_objHorizontalScrollbar != my_rectHorizontalScrollbar) {
00186                 my_objHorizontalScrollbar->MoveWidget(my_rectHorizontalScrollbar);
00187         }
00188 
00189         if(*my_scrollarea != my_rectList) {
00190                 my_scrollarea->MoveWidget(my_rectList);
00191         }
00192 }
00193 
00194 void PG_ScrollWidget::LoadThemeStyle(const std::string& widgettype) {
00195         PG_ThemeWidget::LoadThemeStyle(widgettype);
00196         my_objVerticalScrollbar->LoadThemeStyle(widgettype);
00197         my_objHorizontalScrollbar->LoadThemeStyle(widgettype);
00198 
00199         // if the scrollbars have currently the size 0 because they are disabled, we don't want that
00200         // to be the nominal size because they would stay invisible even if they are enabled
00201         if ( my_objVerticalScrollbar->Width() )
00202                 my_widthScrollbar = my_objVerticalScrollbar->Width();
00203 
00204         if ( my_objHorizontalScrollbar->Height() )
00205                 my_heightHorizontalScrollbar = my_objHorizontalScrollbar->Height();
00206 
00207         RecalcPositions(my_objVerticalScrollbar->IsVisible(), my_objHorizontalScrollbar->IsVisible());
00208 }
00209 
00210 void PG_ScrollWidget::eventSizeWidget(Uint16 w, Uint16 h) {
00211 
00212         PG_ThemeWidget::eventSizeWidget(w,h);
00213 
00214         my_height = h;
00215         my_width = w;
00216         my_scrollarea->SizeWidget(w, h);
00217         CalcScrollbarVisibility();
00218         CheckScrollBars();
00219 }
00220 
00221 bool PG_ScrollWidget::eventMouseButtonDown(const SDL_MouseButtonEvent* button)
00222 {
00223    if ( my_objVerticalScrollbar->IsVisible() ) {
00224       if ( button->button == 4 ) {
00225          
00226          int y = GetScrollPosY();
00227          if ( y < my_objVerticalScrollbar->GetLineSize() )
00228             y = 0;
00229          else
00230             y -= my_objVerticalScrollbar->GetLineSize();
00231          
00232          ScrollTo( GetScrollPosX(), y );
00233          return true;
00234       }
00235       if ( button->button == 5 ) {
00236          ScrollTo( GetScrollPosX(), GetScrollPosY() + my_objVerticalScrollbar->GetLineSize() );
00237          return true;
00238       }
00239    }
00240    return false;   
00241 }
00242 
00243 
00244 bool PG_ScrollWidget::handleScrollPos(PG_ScrollBar* widget, long data) {
00245         if(widget == my_objVerticalScrollbar) {
00246                 my_scrollarea->ScrollTo(my_scrollarea->GetScrollPosX(), data);
00247                 return true;
00248         }
00249 
00250         if(widget == my_objHorizontalScrollbar) {
00251                 my_scrollarea->ScrollTo(data, my_scrollarea->GetScrollPosY());
00252                 return true;
00253         }
00254 
00255         return true;
00256 }
00257 
00258 bool PG_ScrollWidget::handleScrollTrack(PG_ScrollBar* widget, long data) {
00259         if(widget == my_objVerticalScrollbar) {
00260                 my_scrollarea->ScrollTo(my_scrollarea->GetScrollPosX(), data);
00261                 return true;
00262         }
00263 
00264         if(widget == my_objHorizontalScrollbar) {
00265                 my_scrollarea->ScrollTo(data, my_scrollarea->GetScrollPosY());
00266                 return true;
00267         }
00268 
00269         return true;
00270 }
00271 
00272 void PG_ScrollWidget::AddChild(PG_Widget* w) {
00273         if(w == NULL) {
00274                 return;
00275         }
00276 
00277         if (my_objVerticalScrollbar == NULL || my_objHorizontalScrollbar == NULL || my_scrollarea == NULL) {
00278                 PG_Widget::AddChild(w);
00279                 return;
00280         }
00281 
00282         my_scrollarea->AddChild(w);
00283 }
00284 
00285 void PG_ScrollWidget::SetLineSize( int linesize )
00286 {
00287    my_scrollLineSize = linesize;
00288 }
00289 
00290 int PG_ScrollWidget::GetLineSize()
00291 {
00292    return my_scrollLineSize;
00293 }
00294 
00295 
00296 
00297 void PG_ScrollWidget::CheckScrollBars() {
00298         int ls = 0, i;
00299         PG_ScrollBar *scrollBars[] = { my_objVerticalScrollbar, my_objHorizontalScrollbar };
00300         Uint32 listsizes[] = { GetListHeight(), GetListWidth() };
00301         Uint16 sizes[] = { my_scrollarea->Height(), my_scrollarea->Width() };
00302         Uint16 pos[] = { my_scrollarea->GetScrollPosY(), my_scrollarea->GetScrollPosX() };
00303         for (i = 0; i < 2; i++) {
00304            if ( my_scrollLineSize > 0 )
00305               scrollBars[i]->SetLineSize(my_scrollLineSize);
00306            else {
00307                 if(GetWidgetCount() != 0) {
00308                         ls = listsizes[i] / GetWidgetCount();
00309    
00310                         if(ls == 0) {
00311                                 ls = 1;
00312                         }
00313                         scrollBars[i]->SetLineSize(ls);
00314                 } else {
00315                         scrollBars[i]->SetLineSize(10);
00316                 }
00317         }
00318         
00319                 scrollBars[i]->SetRange(0, listsizes[i] -  sizes[i] );
00320                 scrollBars[i]->SetPageSize(sizes[i]);
00321                 scrollBars[i]->SetPosition(pos[i]);
00322         }
00323 
00324 }
00325 
00326 void PG_ScrollWidget::EnableScrollBar(bool enable, PG_ScrollBar::ScrollDirection direction) {
00327         if (direction == PG_ScrollBar::VERTICAL) {
00328                 my_enableVerticalScrollbar = enable;
00329         } else if (direction == PG_ScrollBar::HORIZONTAL) {
00330                 my_enableHorizontalScrollbar = enable;
00331         }
00332         RecalcPositions(my_objVerticalScrollbar->IsNull(), my_objHorizontalScrollbar->IsNull());
00333         CheckScrollBars();
00334 }
00335 
00336 void PG_ScrollWidget::ScrollToWidget(PG_Widget* widget, bool bVertical) {
00337         my_scrollarea->ScrollToWidget(widget, bVertical);
00338         RecalcPositions(!my_objVerticalScrollbar->IsNull(), !my_objHorizontalScrollbar->IsNull());
00339         CheckScrollBars();
00340 }
00341 
00342 Uint16 PG_ScrollWidget::GetListHeight() {
00343         return my_scrollarea->GetAreaHeight();
00344 }
00345 
00346 Uint16 PG_ScrollWidget::GetListWidth() {
00347         return my_scrollarea->GetAreaWidth();
00348 }
00349 
00350 Uint16 PG_ScrollWidget::GetWidgetCount() {
00351         return my_scrollarea->GetWidgetCount();
00352 }
00353 
00354 bool PG_ScrollWidget::handleAreaChangedHeight(PG_ScrollArea* area, Uint16 h) {
00355         CalcScrollbarVisibility();
00356 
00357         Sint32 max_y = my_scrollarea->GetAreaHeight() - my_scrollarea->GetScrollPosY();
00358         if(max_y < my_scrollarea->my_height) {
00359                 max_y = my_scrollarea->GetAreaHeight() - my_scrollarea->my_height;
00360                 if(max_y < 0) {
00361                         max_y = 0;
00362                 }
00363                 my_scrollarea->ScrollTo(my_scrollarea->GetScrollPosX(), max_y);
00364         }
00365 
00366         CheckScrollBars();
00367         return true;
00368 }
00369 
00370 bool PG_ScrollWidget::handleAreaChangedWidth(PG_ScrollArea* area, Uint16 w) {
00371         CalcScrollbarVisibility();
00372 
00373         Sint32 max_x = my_scrollarea->GetAreaWidth() - my_scrollarea->GetScrollPosX();
00374         if(max_x < my_scrollarea->my_width) {
00375                 max_x = my_scrollarea->GetAreaWidth() - my_scrollarea->my_width;
00376                 if(max_x < 0) {
00377                         max_x = 0;
00378                 }
00379                 my_scrollarea->ScrollTo(max_x, my_scrollarea->GetScrollPosY());
00380         }
00381 
00382         CheckScrollBars();
00383         return true;
00384 }
00385 
00386 PG_Widget* PG_ScrollWidget::GetFirstInList() {
00387         return my_scrollarea->GetFirstInList();
00388 }
00389 
00390 void PG_ScrollWidget::ScrollTo( int x, int y) {
00391         my_scrollarea->ScrollTo(x, y);
00392         RecalcPositions(!my_objVerticalScrollbar->IsNull(), !my_objHorizontalScrollbar->IsNull());
00393         CheckScrollBars();
00394 }
00395 
00396 void PG_ScrollWidget::DeleteAll() {
00397         my_scrollarea->DeleteAll();
00398 }
00399 
00400 void PG_ScrollWidget::RemoveAll() {
00401         my_scrollarea->RemoveAll();
00402 }
00403 
00404 void PG_ScrollWidget::SetShiftOnRemove(bool shiftx, bool shifty) {
00405         my_scrollarea->SetShiftOnRemove(shiftx, shifty);
00406 }
00407 
00408 Uint16 PG_ScrollWidget::GetScrollPosX() {
00409         return my_scrollarea->GetScrollPosX();
00410 }
00411 
00412 Uint16 PG_ScrollWidget::GetScrollPosY() {
00413         return my_scrollarea->GetScrollPosY();
00414 }
00415 
00416 void PG_ScrollWidget::SetAutoResize(bool bRemove, bool bAdd) {
00417         my_scrollarea->SetResizeParent(bRemove, bAdd);
00418 }

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