00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00045
00046
00047
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
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
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
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
00170 if(!bV && !bH) {
00171 my_rectHorizontalScrollbar.SetRect(0,0,0,0);
00172 my_rectVerticalScrollbar.SetRect(0,0,0,0);
00173 }
00174
00175
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
00200
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 }