/* * pawscrollbar.h - Author: Andrew Craig * * Copyright (C) 2003 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation (version 2 of the License) * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ // pawscrollbar.cpp: implementation of the pawscrollbar class. // ////////////////////////////////////////////////////////////////////// #include #include #include "pawscrollbar.h" #include "pawsmanager.h" #include "pawsbutton.h" #define SCROLL_TICKS 150 #define THUMB_IMAGE "ScrollBar Thumb" #define THUMB_MOVING_IMAGE "ScrollBar Thumb Moving" #define THUMB_MARGIN 2 #define SCROLL_UP_SND "gui.scrollup" #define SCROLL_DOWN_SND "gui.scrolldown" class pawsThumb : public pawsWidget { public: bool OnMouseUp( int button, int modifiers, int x, int y ) { if ( parent ) return parent->OnMouseUp( button, modifiers, x, y ); else return false; } }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// pawsScrollBar::pawsScrollBar() { currentValue = 0; maxValue = 0; minValue = 0; tickValue = 1; horizontal = false; reversed = false; limited = true; // Used when the mouse button is held down clock = CS_QUERY_REGISTRY( PawsManager::GetSingleton().GetObjectRegistry(), iVirtualClock ); scrollTicks = clock->GetCurrentTicks(); mouseDown = false; upButton = downButton = NULL; thumb = NULL; mouseIsDraggingThumb = false; } pawsScrollBar::~pawsScrollBar() { } bool pawsScrollBar::Setup( iDocumentNode* node ) { // Check for direction csRef directionAttribute = node->GetAttribute("direction"); if ( directionAttribute ) { csString value( directionAttribute->GetValue() ); if ( value == "horizontal" ) SetHorizontal(true); else SetHorizontal(false); } return true; } void pawsScrollBar::SetMaxValue( float value ) { maxValue = value; if ( limited ) LimitCurrentValue(); if (parent != NULL) parent->OnScroll( SCROLL_AUTO, this ); SetThumbLayout(); } void pawsScrollBar::SetMinValue( float value ) { minValue = value; if ( limited ) LimitCurrentValue(); if (parent != NULL) parent->OnScroll( SCROLL_AUTO, this ); SetThumbLayout(); } void pawsScrollBar::SetCurrentValue( float value, bool triggerEvent ) { if (reversed) currentValue = maxValue-value; else currentValue = value; if ( limited ) LimitCurrentValue(); SetThumbLayout(); if (triggerEvent) parent->OnScroll( SCROLL_SET, this ); } void pawsScrollBar::SetHorizontal (bool value) { horizontal = value; SetThumbLayout(); } bool pawsScrollBar::PostSetup() { // Create the scroll up/left button upButton = (pawsButton*)PawsManager::GetSingleton().CreateWidget( "pawsButton" ); upButton->SetParent( this ); int flags; if (!horizontal) { flags = ATTACH_TOP | ATTACH_RIGHT; upButton->SetBackground("Up Arrow"); } else { flags = ATTACH_LEFT | ATTACH_BOTTOM; upButton->SetBackground("Left Arrow"); } //Add the sound upButton->SetSound(SCROLL_UP_SND); upButton->SetAttachFlags( flags ); upButton->SetID( SCROLL_UP ); AddChild( upButton ); // Create the scroll down button. downButton = ( pawsButton *) PawsManager::GetSingleton().CreateWidget( "pawsButton" ); downButton->SetParent( this ); if (!horizontal) { flags = ATTACH_BOTTOM | ATTACH_RIGHT; downButton->SetBackground("Down Arrow"); } else { flags = ATTACH_RIGHT | ATTACH_BOTTOM; downButton->SetBackground("Right Arrow"); } //Add the sound downButton->SetSound(SCROLL_DOWN_SND); downButton->SetAttachFlags( flags ); downButton->SetID( SCROLL_DOWN ); AddChild( downButton ); SetButtonLayout(); thumb = new pawsThumb(); AddChild(thumb); thumb->SetBackground(THUMB_IMAGE); thumb->SetID(SCROLL_THUMB); SetThumbVisibility(); if (thumb->IsVisible()) SetThumbLayout(); return true; } void pawsScrollBar::SetThumbVisibility() { if (thumb != NULL) { if (GetScrollBarSize()*1 < GetThumbScaleLength()) thumb->Show(); else thumb->Hide(); } } void pawsScrollBar::OnResize() { SetThumbVisibility(); if (thumb!=NULL && thumb->IsVisible()) SetThumbLayout(); SetButtonLayout(); } void pawsScrollBar::SetThumbLayout() { int scrollBarSize = GetScrollBarSize(); if (thumb == NULL) return; thumb->SetSize(scrollBarSize-2*THUMB_MARGIN, scrollBarSize-2*THUMB_MARGIN); if (maxValue == 0) { if (horizontal) thumb->MoveTo(screenFrame.xmin+scrollBarSize, screenFrame.ymin+THUMB_MARGIN); else thumb->MoveTo(screenFrame.xmin+THUMB_MARGIN, screenFrame.ymin+scrollBarSize); } else { if (horizontal) thumb->MoveTo(screenFrame.xmin+scrollBarSize + int((currentValue-minValue)/(maxValue-minValue)*GetThumbScaleLength()), screenFrame.ymin+THUMB_MARGIN); else { thumb->MoveTo(screenFrame.xmin+THUMB_MARGIN, screenFrame.ymin+scrollBarSize + int((currentValue-minValue)/(maxValue-minValue)*GetThumbScaleLength())); } } } bool pawsScrollBar::OnMouseDown( int button, int modifiers, int x, int y ) { if (WidgetAt(x, y) == thumb) { if (horizontal) thumbDragPoint = x - thumb->ScreenFrame().xmin; else thumbDragPoint = y - thumb->ScreenFrame().ymin; mouseIsDraggingThumb = true; thumb->SetBackground(THUMB_MOVING_IMAGE); } else MoveThumbToMouse(); return true; } bool pawsScrollBar::OnMouseUp( int button, int modifiers, int x, int y ) { mouseIsDraggingThumb = false; thumb->SetBackground(THUMB_IMAGE); return true; } bool pawsScrollBar::OnMouseExit() { psPoint pos = PawsManager::GetSingleton().GetMouse()->GetPosition(); pawsWidget* widget = WidgetAt( pos.x, pos.y ); if(widget == thumb) return false; return true; } float pawsScrollBar::GetCurrentValue() { if (reversed) return maxValue-currentValue; else return currentValue; } void pawsScrollBar::SetTickValue( float tick ) { tickValue = tick; } void pawsScrollBar::LimitCurrentValue() { if ( currentValue > maxValue ) currentValue = maxValue; if ( currentValue < minValue ) currentValue = minValue; } bool pawsScrollBar::OnButtonPressed( int button, int keyModifier, pawsWidget* widget ) { mouseDown = true; scrollTicks = clock->GetCurrentTicks(); lastButton = button; lastModifiers = keyModifier; lastWidget = widget; switch( widget->GetID() ) { case SCROLL_DOWN: if ( currentValue < maxValue || !limited ) { currentValue += tickValue; if ( limited ) LimitCurrentValue(); SetThumbLayout(); return parent->OnScroll( widget->GetID(), this ); } break; case SCROLL_UP: if ( currentValue > minValue || !limited ) { currentValue -= tickValue; if ( limited ) LimitCurrentValue(); SetThumbLayout(); return parent->OnScroll( widget->GetID(), this ); } break; } return false; } bool pawsScrollBar::OnButtonReleased( int button, pawsWidget* widget ) { mouseDown = false; return true; } void pawsScrollBar::MoveThumbToMouse() { psPoint mousePos; int relMouseCoord, // coordinate of mouse cursor relative to the rectangle that constraints thumb movement rectBegin, // coordinate of the constraint rectangle rectSize, // size of the constraint rectangle thumbPos; // coordinate of thumb relative to the constraint rectangle int scrollBarSize = GetScrollBarSize(); mousePos = PawsManager::GetSingleton().GetMouse()->GetPosition(); if (horizontal) { rectBegin = screenFrame.xmin + scrollBarSize; relMouseCoord = mousePos.x - rectBegin; } else { rectBegin = screenFrame.ymin + scrollBarSize; relMouseCoord = mousePos.y - rectBegin; } rectSize = GetThumbScaleLength(); if (mouseIsDraggingThumb) thumbPos = relMouseCoord - thumbDragPoint; else thumbPos = relMouseCoord - (scrollBarSize - 2*THUMB_MARGIN) / 2; thumbPos = MAX(thumbPos, 0); thumbPos = MIN(thumbPos, rectSize); if (horizontal) thumb->MoveTo(rectBegin+thumbPos, thumb->ScreenFrame().ymin); else thumb->MoveTo(thumb->ScreenFrame().xmin, rectBegin+thumbPos); currentValue = minValue + (float(thumbPos) / rectSize * (maxValue-minValue)); if ( limited ) LimitCurrentValue(); if (parent != NULL) parent->OnScroll( SCROLL_THUMB, this ); } void pawsScrollBar::Draw() { if (mouseIsDraggingThumb && maxValue>0) MoveThumbToMouse(); pawsWidget::Draw(); if ( mouseDown && (clock->GetCurrentTicks() - scrollTicks > SCROLL_TICKS )) OnButtonPressed(lastButton, lastModifiers, lastWidget); } void pawsScrollBar::EnableValueLimit( bool limited ) { this->limited = limited; } int pawsScrollBar::GetScrollBarSize() { return horizontal ? screenFrame.Height() : screenFrame.Width(); } void pawsScrollBar::SetButtonLayout() { int scrollBarSize = GetScrollBarSize(); if (upButton != NULL) { if (!horizontal) upButton->SetRelativeFrame( 0,0, scrollBarSize,scrollBarSize ); else upButton->SetRelativeFrame(0,0,scrollBarSize,scrollBarSize); } if (downButton != NULL) { if (!horizontal) downButton->SetRelativeFrame( 0, defaultFrame.Height()-scrollBarSize, scrollBarSize,scrollBarSize ); else downButton->SetRelativeFrame(defaultFrame.Width()-scrollBarSize,0,scrollBarSize,scrollBarSize); } } int pawsScrollBar::GetThumbScaleLength() { int scrollBarSize = GetScrollBarSize(); if (horizontal) return screenFrame.Width() - 3*scrollBarSize + 2*THUMB_MARGIN; else return screenFrame.Height() - 3*scrollBarSize + 2*THUMB_MARGIN; }