wg_scrollbar.cpp

00001 // wg_scrollbar.cpp
00002 //
00003 // CScrollBar class implementation
00004 //
00005 //
00006 // Copyright (c) 2002-2004 Rob Wiskow
00007 // rob-dev@boxedchaos.com
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00017 // Lesser General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00022 //
00023 
00024 
00025 #include "wgui_include_config.h"
00026 #include "wg_application.h"
00027 #include "wg_scrollbar.h"
00028 #include "wg_message_server.h"
00029 #include "wg_error.h"
00030 #include "wg_resources.h"
00031 #include "std_ex.h"
00032 
00033 
00034 namespace wGui
00035 {
00036 
00037 CScrollBar::CScrollBar(const CRect& WindowRect, CWindow* pParent, EScrollBarType ScrollBarType) :
00038      CRangeControl<int>(WindowRect, pParent, 0, 100, 1, 0),
00039      m_ScrollBarType(ScrollBarType),
00040      m_iJumpAmount(5),
00041      m_bDragging(false)
00042 {
00043      m_BackgroundColor = CApplication::Instance()->GetDefaultForegroundColor();
00044      switch (m_ScrollBarType)
00045      {
00046      case VERTICAL:
00047           m_ClientRect = CRect(0, m_WindowRect.Width(), m_WindowRect.Width() - 1, m_WindowRect.Height() - m_WindowRect.Width() - 1);
00048           m_pBtnUpLeft = new CPictureButton(CRect(0, -m_ClientRect.Width(), m_ClientRect.Width() - 1, -1),
00049                this, CwgBitmapResourceHandle(WGRES_UP_ARROW_BITMAP));
00050           m_pBtnDownRight = new CPictureButton(
00051                CRect(0, m_ClientRect.Height() + 1, m_ClientRect.Width() - 1, m_ClientRect.Height() + m_ClientRect.Width()),
00052                this, CwgBitmapResourceHandle(WGRES_DOWN_ARROW_BITMAP));
00053           break;
00054      case HORIZONTAL:
00055           m_ClientRect = CRect(m_WindowRect.Height(), 0, m_WindowRect.Width() - m_WindowRect.Height() - 1, m_WindowRect.Height() - 1);
00056           m_pBtnUpLeft = new CPictureButton(CRect(-m_ClientRect.Height(), 0, -1, m_ClientRect.Height() - 1),
00057                this, CwgBitmapResourceHandle(WGRES_LEFT_ARROW_BITMAP));
00058           m_pBtnDownRight = new CPictureButton(
00059                CRect(m_ClientRect.Width() + 1, 0, m_ClientRect.Width() + m_ClientRect.Height(), m_ClientRect.Height() - 1),
00060                this, CwgBitmapResourceHandle(WGRES_RIGHT_ARROW_BITMAP));
00061           break;
00062      default:
00063           throw(Wg_Ex_App(L"CScrollBar::CScrollBar:  Unrecognized ScrollBar Type."));
00064           break;
00065      }
00066      m_ThumbRect = m_ClientRect;
00067      RepositionThumb();
00068      CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_BUTTONUP);
00069      CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_MOVE);
00070      CMessageServer::Instance().RegisterMessageClient(this, CMessage::CTRL_SINGLELCLICK);
00071      Draw();
00072 }
00073 
00074 
00075 CScrollBar::~CScrollBar(void)
00076 {
00077 
00078 }
00079 
00080 
00081 void CScrollBar::SetValue(int iValue, bool bRedraw)  // virtual
00082 {
00083      CRangeControl<int>::SetValue(iValue, false);
00084      RepositionThumb();
00085      if (bRedraw)
00086      {
00087           Draw();
00088      }
00089 }
00090 
00091 
00092 void CScrollBar::Draw(void) const
00093 {
00094      CWindow::Draw();
00095 
00096      if (m_pSDLSurface)
00097      {
00098           CPainter Painter(m_pSDLSurface, CPainter::PAINT_REPLACE);
00099           if (m_MinLimit != m_MaxLimit)
00100           {
00101                Painter.DrawRect(m_ThumbRect, false, COLOR_BLACK);
00102                CRect SubRect(m_ThumbRect);
00103                SubRect.Grow(-1);
00104                Painter.DrawRect(SubRect, true, COLOR_LIGHTGRAY, m_BackgroundColor);
00105                Painter.DrawHLine(SubRect.Left(), SubRect.Right(), SubRect.Bottom(), COLOR_DARKGRAY);
00106                Painter.DrawVLine(SubRect.Top(), SubRect.Bottom(), SubRect.Right(), COLOR_DARKGRAY);
00107           }
00108      }
00109 }
00110 
00111 
00112 void CScrollBar::SetWindowRect(const CRect& WindowRect)
00113 {
00114      CWindow::SetWindowRect(WindowRect);
00115      // Resposition the thumb rect and the button controls
00116      switch (m_ScrollBarType)
00117      {
00118      case VERTICAL:
00119      {
00120           m_ClientRect = CRect(0, m_WindowRect.Width(), m_WindowRect.Width() - 1, m_WindowRect.Height() - m_WindowRect.Width() - 1);
00121           m_pBtnUpLeft->SetWindowRect(CRect(0, -m_ClientRect.Width(), m_ClientRect.Width() - 1, -1));
00122           m_pBtnDownRight->SetWindowRect(CRect(0, m_ClientRect.Height() + 1, m_ClientRect.Width() - 1, m_ClientRect.Height() + m_ClientRect.Width()));
00123           break;
00124      }
00125      case HORIZONTAL:
00126      {
00127           m_ClientRect = CRect(m_WindowRect.Height(), 0, m_WindowRect.Width() - m_WindowRect.Height() - 1, m_WindowRect.Height() - 1);
00128           m_pBtnUpLeft->SetWindowRect(CRect(-m_ClientRect.Height(), 0, -1, m_ClientRect.Height() - 1));
00129           m_pBtnDownRight->SetWindowRect(CRect(m_ClientRect.Width() + 1, 0, m_ClientRect.Width() + m_ClientRect.Height(), m_ClientRect.Height() - 1));
00130           break;
00131      }
00132      default:
00133           throw(Wg_Ex_App(L"CScrollBar::SetWindowRect:  Unrecognized ScrollBar Type."));
00134           break;
00135      }
00136      SetValue(m_Value);
00137 }
00138 
00139 
00140 void CScrollBar::MoveWindow(const CPoint& MoveDistance)
00141 {
00142      CWindow::MoveWindow(MoveDistance);
00143      m_ThumbRect = m_ThumbRect + MoveDistance;
00144 }
00145 
00146 
00147 bool CScrollBar::OnMouseButtonDown(CPoint Point, unsigned int Button)
00148 {
00149      bool bResult = CWindow::OnMouseButtonDown(Point, Button);
00150 
00151      if (!bResult && m_bVisible && m_ClientRect.HitTest(ViewToWindow(Point)) == CRect::RELPOS_INSIDE)
00152      {
00153           if (Button == CMouseMessage::WHEELUP)
00154           {
00155                Decrement();
00156                bResult = true;
00157           }
00158           else if (Button == CMouseMessage::WHEELDOWN)
00159           {
00160                Increment();
00161                bResult = true;
00162           }
00163           else if (Button == CMouseMessage::LEFT)
00164           {
00165                switch (m_ThumbRect.HitTest(ViewToWindow(Point)))
00166                {
00167                case CRect::RELPOS_INSIDE:
00168                     m_bDragging = true;
00169                     break;
00170                case CRect::RELPOS_ABOVE:
00171                case CRect::RELPOS_LEFT:
00172                     SetValue(m_Value - m_iJumpAmount);
00173                     break;
00174                case CRect::RELPOS_BELOW:
00175                case CRect::RELPOS_RIGHT:
00176                     SetValue(m_Value + m_iJumpAmount);
00177                     break;
00178                }
00179                bResult = true;
00180           }
00181      }
00182 
00183      return bResult;
00184 }
00185 
00186 
00187 bool CScrollBar::HandleMessage(CMessage* pMessage)
00188 {
00189      bool bHandled = false;
00190 
00191      if (pMessage)
00192      {
00193           switch(pMessage->MessageType())
00194           {
00195           case CMessage::MOUSE_BUTTONUP:
00196           {
00197                CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage);
00198                if (pMouseMessage && m_bDragging && pMouseMessage->Button == CMouseMessage::LEFT)
00199                {
00200                     m_bDragging = false;
00201                     CMessageServer::Instance().QueueMessage(new TIntMessage(CMessage::CTRL_VALUECHANGE, m_pParentWindow, this, m_Value));
00202                     bHandled = true;
00203                }
00204                break;
00205           }
00206           case CMessage::MOUSE_MOVE:
00207                if (m_bDragging)
00208                {
00209                     CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage);
00210                     if (pMouseMessage)
00211                     {
00212                          int iOldPosition = m_Value;
00213                          switch (m_ScrollBarType)
00214                          {
00215                          case VERTICAL:
00216                               m_Value = ConstrainValue((ViewToWindow(pMouseMessage->Point).YPos() - m_ClientRect.Top() - m_ThumbRect.Height() / 2) *
00217                                    (m_MaxLimit - m_MinLimit) / (m_ClientRect.Height() - m_ThumbRect.Height()) + m_MinLimit);
00218                               break;
00219                          case HORIZONTAL:
00220                               m_Value = ConstrainValue((ViewToWindow(pMouseMessage->Point).XPos() - m_ClientRect.Left() - m_ThumbRect.Width() / 2) *
00221                                    (m_MaxLimit - m_MinLimit) / (m_ClientRect.Width() - m_ThumbRect.Width()) + m_MinLimit);
00222                               break;
00223                          default:
00224                               throw(Wg_Ex_App(L"CScrollBar::HandleMessage:  Unrecognized ScrollBar Type."));
00225                               break;
00226                          }
00227                          if (iOldPosition != m_Value)
00228                          {
00229                               CMessageServer::Instance().QueueMessage(new TIntMessage(CMessage::CTRL_VALUECHANGING, m_pParentWindow, this, m_Value));
00230                               RepositionThumb();
00231                               Draw();
00232                          }
00233                     }
00234                }
00235                break;
00236           case CMessage::CTRL_SINGLELCLICK:
00237           {
00238                if (pMessage->Destination() == this)
00239                {
00240                     if (pMessage->Source() == m_pBtnUpLeft)
00241                     {
00242                          Decrement();
00243                          bHandled = true;
00244                     }
00245                     else if (pMessage->Source() == m_pBtnDownRight)
00246                     {
00247                          Increment();
00248                          bHandled = true;
00249                     }
00250                }
00251                break;
00252           }
00253           default :
00254                bHandled = CWindow::HandleMessage(pMessage);
00255                break;
00256           }
00257      }
00258 
00259      return bHandled;
00260 }
00261 
00262 
00263 void CScrollBar::RepositionThumb(void)  // virtual
00264 {
00265      if (m_MinLimit != m_MaxLimit)
00266      {
00267           switch (m_ScrollBarType)
00268           {
00269           case VERTICAL:
00270           {
00271                int iThumbHeight = m_ClientRect.Height() / (m_MaxLimit - m_MinLimit + 1);
00272                if (iThumbHeight < 10)
00273                {
00274                     iThumbHeight = 10;
00275                }
00276                m_ThumbRect.SetTop(m_ClientRect.Top() + (m_ClientRect.Height() - iThumbHeight) * (m_Value - m_MinLimit) / (m_MaxLimit - m_MinLimit));
00277                m_ThumbRect.SetBottom(m_ThumbRect.Top() + iThumbHeight + 1);
00278                break;
00279           }
00280           case HORIZONTAL:
00281           {
00282                int iThumbWidth = m_ClientRect.Width() / (m_MaxLimit - m_MinLimit + 1);
00283                if (iThumbWidth < 10)
00284                {
00285                     iThumbWidth = 10;
00286                }
00287                m_ThumbRect.SetLeft(m_ClientRect.Left() + (m_ClientRect.Width() - iThumbWidth) * (m_Value - m_MinLimit) / (m_MaxLimit - m_MinLimit));
00288                m_ThumbRect.SetRight(m_ThumbRect.Left() + iThumbWidth + 1);
00289                break;
00290           }
00291           default:
00292                throw(Wg_Ex_App(L"CScrollBar::RepositionThumb:  Unrecognized ScrollBar Type."));
00293                break;
00294           }
00295      }
00296 }
00297 
00298 }
00299 

Generated on Wed May 16 23:11:26 2007 for wGui by  doxygen 1.5.1