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

pgscrollbar.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/pgscrollbar.cpp,v $
00025     CVS/RCS Revision: $Revision: 1.2 $
00026     Status:           $State: Exp $
00027 */
00028 
00029 #include <cmath>
00030 
00031 #include "pgscrollbar.h"
00032 #include "pgapplication.h"
00033 #include "pgeventsupplier.h"
00034 
00035 #include "propstrings_priv.h"
00036 
00037 PG_ScrollBar::PG_ScrollBar(PG_Widget* parent, const PG_Rect& r, ScrollDirection direction, int id, const std::string& style) : PG_ThemeWidget(parent, r, style) {
00038         sb_direction = direction;
00039 
00040         SetID(id);
00041 
00042         scroll_min = 0;
00043         scroll_max = 4;
00044         scroll_current = 0;
00045 
00046         my_linesize = 1;
00047         my_pagesize = 1;
00048 
00049         scrollbutton[0] = new PG_Button(this);
00050         scrollbutton[0]->SetID((direction == VERTICAL) ? IDSCROLLBAR_UP : IDSCROLLBAR_LEFT);
00051         scrollbutton[0]->sigClick.connect(slot(*this, &PG_ScrollBar::handleButtonClick));
00052 
00053         scrollbutton[1] = new PG_Button(this);
00054         scrollbutton[1]->SetID((direction == VERTICAL) ? IDSCROLLBAR_DOWN : IDSCROLLBAR_RIGHT);
00055         scrollbutton[1]->sigClick.connect(slot(*this, &PG_ScrollBar::handleButtonClick));
00056 
00057         dragbutton = new ScrollButton(this);
00058         dragbutton->SetID(IDSCROLLBAR_DRAG);
00059         dragbutton->sigClick.connect(slot(*this, &PG_ScrollBar::handleButtonClick));
00060 
00061         if(style != PG_PropStr::Scrollbar) {
00062                 LoadThemeStyle(PG_PropStr::Scrollbar);
00063         }
00064         LoadThemeStyle(style);
00065         SetPosition(0);
00066 }
00067 
00068 PG_ScrollBar::~PG_ScrollBar() {}
00069 
00070 void PG_ScrollBar::LoadThemeStyle(const std::string& widgettype) {
00071 
00072         PG_ThemeWidget::LoadThemeStyle(widgettype, PG_PropStr::Scrollbar);
00073 
00074         if(sb_direction == VERTICAL) {
00075                 scrollbutton[0]->LoadThemeStyle(widgettype, PG_PropStr::ScrollbarUp);
00076                 scrollbutton[1]->LoadThemeStyle(widgettype, PG_PropStr::ScrollbarDown);
00077         } else {
00078                 scrollbutton[0]->LoadThemeStyle(widgettype, PG_PropStr::ScrollbarLeft);
00079                 scrollbutton[1]->LoadThemeStyle(widgettype, PG_PropStr::ScrollbarRight);
00080         }
00081 
00082         dragbutton->LoadThemeStyle(widgettype, PG_PropStr::ScrollbarDrag);
00083 
00084         if(sb_direction == VERTICAL) {
00085                 dragbutton->LoadThemeStyle(widgettype, PG_PropStr::ScrollbarDragV);
00086                 PG_ThemeWidget::LoadThemeStyle(widgettype, PG_PropStr::ScrollbarV);
00087         } else {
00088                 dragbutton->LoadThemeStyle(widgettype, PG_PropStr::ScrollbarDragH);
00089                 PG_ThemeWidget::LoadThemeStyle(widgettype, PG_PropStr::ScrollbarH);
00090         }
00091         RecalcPositions();
00092 }
00093 
00094 void PG_ScrollBar::RecalcPositions() {
00095 
00096         if(sb_direction == VERTICAL) {
00097                 position[0].x = 0;
00098                 position[0].y = 0;
00099                 position[0].w = w;
00100                 position[0].h = w;
00101 
00102                 position[1].x = 0;
00103                 position[1].y = abs(h-w);
00104                 position[1].w = w;
00105                 position[1].h = w;
00106 
00107                 position[2].x = 0;
00108                 position[2].y = w;
00109                 position[2].w = w;
00110                 position[2].h = abs(h-(w*2));
00111 
00112                 position[3].x = 0;
00113                 position[3].w = w;
00114                 position[3].h = position[2].h / 2;
00115 
00116                 if ( my_pagesize <= 0 || scroll_max - scroll_min <= 0 )
00117                         position[3].h = position[2].h;
00118                 else {
00119                         position[3].h = (position[2].h * my_pagesize ) / (scroll_max - scroll_min + my_pagesize );
00120                         if ( position[3].h < position[3].w * 3 / 2)
00121                                 position[3].h = position[3].w * 3 / 2 ;
00122                 }
00123         } else {
00124                 position[0].x = 0;
00125                 position[0].y = 0;
00126                 position[0].w = h;
00127                 position[0].h = h;
00128 
00129                 position[1].x = abs(w - h);
00130                 position[1].y = 0;
00131                 position[1].w = h;
00132                 position[1].h = h;
00133 
00134                 position[2].x = h;
00135                 position[2].y = 0;
00136                 position[2].w = abs(w-(h*2));
00137                 position[2].h = h;
00138 
00139                 position[3].y = 0;
00140                 position[3].w = (Uint16)((double)position[2].w / 2.0);
00141                 position[3].h = h;
00142 
00143                 if ( my_pagesize <= 0 || scroll_max - scroll_min <= 0 )
00144                         position[3].w = position[2].w;
00145                 else {
00146                         position[3].w = (position[2].w * my_pagesize ) / (scroll_max - scroll_min + my_pagesize  );
00147                         if ( position[3].w < position[3].h * 3 / 2)
00148                                 position[3].w = position[3].h * 3 / 2;
00149                 }
00150         }
00151 
00152         int pos =       scroll_current - scroll_min;
00153 
00154         if(sb_direction == VERTICAL) {
00155                 position[3].x = 0;
00156                 if ( (scroll_max - scroll_min) * pos <= 0 )
00157                         position[3].y = position[0].h;
00158                 else
00159                         position[3].y = (Uint16)(position[0].h + (((double)position[2].h - (double)position[3].h) / (double)(scroll_max - scroll_min)) * (double)pos);
00160         } else {
00161                 position[3].y = 0;
00162                 if ( (scroll_max - scroll_min) * pos <= 0 )
00163                         position[3].x = position[0].w;
00164                 else
00165                         position[3].x = (Uint16)(position[0].w + (((double)position[2].w - (double)position[3].w) / (double)(scroll_max - scroll_min)) * (double)pos);
00166         }
00167 
00168         // bordersize
00169         for(int i=0; i<4; i++) {
00170                 if(i == 3 || i == 2) {
00171                         if(sb_direction == VERTICAL) {
00172                                 position[i].x += my_bordersize;
00173                                 if(position[i].w > 2*my_bordersize) {
00174                                         position[i].w -= 2*my_bordersize;
00175                                 }
00176                         } else {
00177                                 position[i].y += my_bordersize;
00178                                 if(position[i].h > 2*my_bordersize) {
00179                                         position[i].h -= 2*my_bordersize;
00180                                 }
00181                         }
00182                         continue;
00183                 }
00184                 position[i].x += my_bordersize;
00185                 position[i].y += my_bordersize;
00186                 if(position[i].w > 2*my_bordersize) {
00187                         position[i].w -= 2*my_bordersize;
00188                 }
00189                 if(position[i].h > 2*my_bordersize) {
00190                         position[i].h -= 2*my_bordersize;
00191                 }
00192         }
00193         if(scrollbutton[0] != NULL) {
00194                 scrollbutton[0]->MoveWidget(position[0]);
00195         }
00196         if(scrollbutton[1] != NULL) {
00197                 scrollbutton[1]->MoveWidget(position[1]);
00198         }
00199         dragbutton->MoveWidget(position[3]);
00200 }
00201 
00202 void PG_ScrollBar::eventSizeWidget(Uint16 w, Uint16 h) {
00203 
00204         PG_ThemeWidget::eventSizeWidget(w, h);
00205 
00206         my_height = h;
00207         my_width = w;
00208 
00209         RecalcPositions();
00210         SetPosition(scroll_current);
00211         return;
00212 }
00213 
00215 bool PG_ScrollBar::eventMouseMotion(const SDL_MouseMotionEvent* motion) {
00216         return PG_ThemeWidget::eventMouseMotion(motion);
00217 }
00218 
00220 bool PG_ScrollBar::eventMouseButtonUp(const SDL_MouseButtonEvent* button) {
00221         int x;
00222         int y;
00223         int mx = dragbutton->my_xpos + dragbutton->my_width / 2;
00224         int my = dragbutton->my_ypos + dragbutton->my_height / 2;
00225 
00226         PG_Application::GetEventSupplier()->GetMouseState(x,y);
00227 
00228         switch (button->button) {
00229                 case 1:
00230                         if(sb_direction == VERTICAL) {
00231                                 if(y < my) {
00232                                         SetPosition(scroll_current - my_pagesize);
00233                                 } else {
00234                                         SetPosition(scroll_current + my_pagesize);
00235                                 }
00236                         } else {
00237                                 if(x < mx) {
00238                                         SetPosition(scroll_current - my_pagesize);
00239                                 } else {
00240                                         SetPosition(scroll_current + my_pagesize);
00241                                 }
00242                         }
00243 
00244                         sigScrollPos(this, scroll_current);
00245                         return true;
00246 
00247                 case 4:
00248                         if(scroll_current <= scroll_min + my_linesize) {
00249                                 SetPosition(scroll_min);
00250                         } else {
00251                                 SetPosition(scroll_current - my_linesize);
00252                         }
00253                         sigScrollPos(this, scroll_current);
00254                         return true;
00255 
00256                 case 5:
00257                         SetPosition(scroll_current + my_linesize);
00258                         sigScrollPos(this, scroll_current);
00259                         return true;
00260         }
00261 
00262         return PG_ThemeWidget::eventMouseButtonUp(button);
00263 }
00264 
00265 
00266 PG_ScrollBar::ScrollButton::ScrollButton(PG_ScrollBar* parent, const PG_Rect& r) : PG_Button(parent, r) {
00267         SetID(IDSCROLLBAR_DRAG);
00268         my_tickMode = false;
00269 }
00270 
00271 PG_ScrollBar::ScrollButton::~ScrollButton() {}
00272 
00274 bool PG_ScrollBar::ScrollButton::eventMouseMotion(const SDL_MouseMotionEvent* motion) {
00275         PG_Point p;
00276 
00277         if(GetPressed()) {
00278 
00279                 p = GetParent()->ScreenToClient(motion->x, motion->y);
00280 
00281                 if(GetParent()->sb_direction == VERTICAL) {
00282                         p.y -= offset.y;
00283 
00284                         if(p.y < GetParent()->position[2].y) {
00285                                 p.y = GetParent()->position[2].y;
00286                         }
00287 
00288                         int maxy;
00289                         if(!my_tickMode) {
00290                                 maxy = GetParent()->position[2].y + (GetParent()->position[2].h) - my_height;
00291                         } else {
00292                                 maxy = GetParent()->my_height - my_height;
00293                         }
00294 
00295                         if(p.y > maxy) {
00296                                 p.y = maxy;
00297                         }
00298 
00299                         MoveWidget(GetParent()->position[2].x, p.y);
00300                 } else {
00301                         p.x -= offset.x;
00302 
00303                         if(p.x < GetParent()->position[2].x) {
00304                                 p.x = GetParent()->position[2].x;
00305                         }
00306 
00307                         int maxx;
00308                         if(!my_tickMode) {
00309                                 maxx = GetParent()->position[2].x + (GetParent()->position[2].w) - (my_width);
00310                         } else {
00311                                 maxx = GetParent()->my_width - my_width;
00312                         }
00313 
00314                         if(p.x > maxx) {
00315                                 p.x = maxx;
00316                         }
00317 
00318                         MoveWidget(p.x, GetParent()->position[2].y);
00319                 }
00320 
00321                 int pos = GetPosFromPoint(p);
00322                 if(GetParent()->scroll_current != pos || my_tickMode) {
00323                         GetParent()->scroll_current = pos;
00324                         GetParent()->sigScrollTrack(GetParent(), pos);
00325                 }
00326 
00327         }
00328 
00329         return true;
00330 }
00331 
00333 bool PG_ScrollBar::ScrollButton::eventMouseButtonDown(const SDL_MouseButtonEvent* button) {
00334         int x,y;
00335 
00336         if(button->button == 1) {
00337                 PG_Application::GetEventSupplier()->GetMouseState(x,y);
00338                 offset = ScreenToClient(x, y);
00339         }
00340 
00341         return PG_Button::eventMouseButtonDown(button);
00342 }
00343 
00345 PG_ScrollBar* PG_ScrollBar::ScrollButton::GetParent() {
00346         return (PG_ScrollBar*)PG_Button::GetParent();
00347 }
00348 
00350 void PG_ScrollBar::SetPosition(int pos) {
00351 
00352         if(pos < scroll_min) {
00353                 pos = scroll_min;
00354         }
00355 
00356         if(pos > scroll_max) {
00357                 pos = scroll_max;
00358         }
00359 
00360         scroll_current = pos;
00361         pos -= scroll_min;
00362 
00363         // check if we are currently in a drag operation
00364         if(dragbutton->GetPressed()) {
00365                 return;
00366         }
00367 
00368         RecalcPositions();
00369 }
00370 
00371 int PG_ScrollBar::GetPosition() {
00372         return scroll_current;
00373 }
00374 
00376 bool PG_ScrollBar::handleButtonClick(PG_Button* button) {
00377 
00378         if(button == scrollbutton[0]) {         // UP | LEFT
00379                 if(scroll_current == scroll_min) {
00380                         return false;
00381                 }
00382                 SetPosition(scroll_current - my_linesize);
00383                 sigScrollPos(this, scroll_current);
00384                 return true;
00385         }
00386 
00387         if(button == scrollbutton[1]) {         // DOWN | RIGHT
00388                 if(scroll_current == scroll_max) {
00389                         return false;
00390                 }
00391                 SetPosition(scroll_current + my_linesize);
00392                 sigScrollPos(this, scroll_current);
00393                 return true;
00394 
00395         }
00396 
00397         return false;
00398 }
00399 
00401 bool PG_ScrollBar::eventMouseButtonDown(const SDL_MouseButtonEvent* button) {
00402         return false;
00403 }
00404 
00406 bool PG_ScrollBar::ScrollButton::eventMouseButtonUp(const SDL_MouseButtonEvent* button) {
00407         int pos = GetParent()->scroll_current; //my_tempPos;
00408 
00409         if(button->button != 1) {
00410                 return false;
00411         }
00412 
00413         PG_Button::eventMouseButtonUp(button);
00414 
00415         //GetParent()->SetPosition(pos);
00416         GetParent()->sigScrollPos(GetParent(), pos);
00417 
00418         return true;
00419 }
00420 
00421 void PG_ScrollBar::ScrollButton::SetTickMode(bool on) {
00422         my_tickMode = on;
00423 }
00424 
00426 void PG_ScrollBar::SetRange(Uint32 min, Uint32 max) {
00427         scroll_min = min;
00428         scroll_max = max;
00429 
00430         // checks if the position is valid and recalculates the size
00431         SetPosition( scroll_current );
00432 }
00433 
00434 int PG_ScrollBar::GetMinRange() {
00435         return scroll_min;
00436 }
00437 
00439 int PG_ScrollBar::GetMaxRange() {
00440         return scroll_max;
00441 }
00442 
00443 int intround( double f)
00444 {
00445    return (int)(std::floor(f + 0.5));
00446 }
00447 
00448 
00450 int PG_ScrollBar::ScrollButton::GetPosFromPoint(PG_Point p) {
00451         Uint32 range = (GetParent()->scroll_max - GetParent()->scroll_min);
00452         int pos = 0;
00453 
00454         if(p.x < 0)
00455                 p.x = 0;
00456         if(p.y < 0)
00457                 p.y = 0;
00458 
00459         //if(!my_tickMode) {
00460         if(GetParent()->sb_direction == VERTICAL) {
00461                 pos = intround((double)(p.y - GetParent()->position[2].y) / (((double)GetParent()->position[2].h - (double)GetParent()->position[3].h) / (double)range));
00462         } else {
00463                 pos = intround((double)(p.x - GetParent()->position[2].x) / (((double)GetParent()->position[2].w - (double)GetParent()->position[3].w) / (double)range));
00464         }
00465         /*} else {
00466                 if(GetParent()->sb_direction == VERTICAL) {
00467                         pos = (int)( (((double)(p.y)) * (double)(range)) / ( (double)GetParent()->position[2].h - (double)GetParent()->position[3].h) + .5 );
00468                 } else {
00469                         pos = (int)( (((double)(p.x)) * (double)(range)) / ( (double)GetParent()->position[2].w - (double)GetParent()->position[3].w) + .5 );
00470                 }
00471         }*/
00472 
00473         if(pos < 0)
00474                 pos = 0;
00475 
00476         pos = GetParent()->scroll_min+pos;
00477 
00478         if(pos > GetParent()->scroll_max) {
00479                 pos = GetParent()->scroll_max;
00480         }
00481 
00482         if(pos < GetParent()->scroll_min) {
00483                 pos = GetParent()->scroll_min;
00484         }
00485 
00486         return pos;
00487 }
00488 
00489 void PG_ScrollBar::SetLineSize(int ls) {
00490         my_linesize = ls;
00491 }
00492 
00493 int  PG_ScrollBar::GetLineSize()
00494 {
00495    return my_linesize;
00496 }
00497 
00498 
00499 void PG_ScrollBar::SetPageSize(int ps) {
00500         my_pagesize = ps;
00501         RecalcPositions();
00502 }

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