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 #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)
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
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)
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