Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 244 | chris | 1 | #include "ScrollbarWidget.h" |
| 2 | #include "WidgetManager.h" |
||
| 3 | #include "ScrollListener.h" |
||
| 4 | #include "ScrollbuttonWidget.h" |
||
| 5 | |||
| 6 | using namespace Sexy; |
||
| 7 | |||
| 8 | ScrollbarWidget::ScrollbarWidget(int theId, ScrollListener* theScrollListener) |
||
| 9 | { |
||
| 10 | mId = theId; |
||
| 11 | mScrollListener = theScrollListener; |
||
| 12 | |||
| 13 | SetDisabled(true); |
||
| 14 | |||
| 15 | mUpButton = new ScrollbuttonWidget(0, this); |
||
| 16 | mUpButton->SetDisabled(true); |
||
| 17 | |||
| 18 | mDownButton = new ScrollbuttonWidget(1, this); |
||
| 19 | mDownButton->SetDisabled(true); |
||
| 20 | |||
| 21 | mInvisIfNoScroll = false; |
||
| 22 | mPressedOnThumb = false; |
||
| 23 | mValue = 0; |
||
| 24 | mMaxValue = 0; |
||
| 25 | mPageSize = 0; |
||
| 26 | mUpdateAcc = 0; |
||
| 27 | mButtonAcc = 0; |
||
| 28 | mUpdateMode = 0; |
||
| 29 | mHorizontal = false; |
||
| 30 | |||
| 31 | AddWidget(mUpButton); |
||
| 32 | AddWidget(mDownButton); |
||
| 33 | } |
||
| 34 | |||
| 35 | ScrollbarWidget::~ScrollbarWidget() |
||
| 36 | { |
||
| 37 | RemoveAllWidgets(true); |
||
| 38 | } |
||
| 39 | |||
| 40 | void ScrollbarWidget::SetInvisIfNoScroll(bool invisIfNoScroll) |
||
| 41 | { |
||
| 42 | mInvisIfNoScroll = invisIfNoScroll; |
||
| 43 | |||
| 44 | if (mInvisIfNoScroll) |
||
| 45 | { |
||
| 46 | SetVisible(false); |
||
| 47 | mDownButton->SetVisible(false); |
||
| 48 | mUpButton->SetVisible(false); |
||
| 49 | } |
||
| 50 | } |
||
| 51 | |||
| 52 | void ScrollbarWidget::SetHorizontal(bool isHorizontal) |
||
| 53 | { |
||
| 54 | mHorizontal = isHorizontal; |
||
| 55 | mDownButton->mHorizontal = mHorizontal; |
||
| 56 | mUpButton->mHorizontal = mHorizontal; |
||
| 57 | } |
||
| 58 | |||
| 59 | |||
| 60 | void ScrollbarWidget::ResizeScrollbar(int theX, int theY, int theWidth, int theHeight) |
||
| 61 | { |
||
| 62 | Resize(theX, theY, theWidth, theHeight); |
||
| 63 | if (mHorizontal) |
||
| 64 | { |
||
| 65 | theX = theY = 0; // Use New Container Stuff |
||
| 66 | mUpButton->Resize(theX, theY, theHeight, theHeight); |
||
| 67 | mDownButton->Resize(theX + theWidth - theHeight, theY, theHeight, theHeight); |
||
| 68 | } |
||
| 69 | else |
||
| 70 | { |
||
| 71 | theX = theY = 0; // Use New Container Stuff |
||
| 72 | mUpButton->Resize(theX, theY, theWidth, theWidth); |
||
| 73 | mDownButton->Resize(theX, theY + theHeight - theWidth, theWidth, theWidth); |
||
| 74 | } |
||
| 75 | } |
||
| 76 | |||
| 77 | void ScrollbarWidget::SetMaxValue(double theNewMaxValue) |
||
| 78 | { |
||
| 79 | mMaxValue = theNewMaxValue; |
||
| 80 | ClampValue(); |
||
| 81 | MarkDirty(); |
||
| 82 | } |
||
| 83 | |||
| 84 | void ScrollbarWidget::SetPageSize(double theNewPageSize) |
||
| 85 | { |
||
| 86 | mPageSize = theNewPageSize; |
||
| 87 | ClampValue(); |
||
| 88 | MarkDirty(); |
||
| 89 | } |
||
| 90 | |||
| 91 | void ScrollbarWidget::SetValue(double theNewValue) |
||
| 92 | { |
||
| 93 | mValue = theNewValue; |
||
| 94 | ClampValue(); |
||
| 95 | mScrollListener->ScrollPosition(mId, mValue); |
||
| 96 | MarkDirty(); |
||
| 97 | } |
||
| 98 | |||
| 99 | bool ScrollbarWidget::AtBottom() |
||
| 100 | { |
||
| 101 | return mMaxValue - mPageSize - mValue <= 1.0; |
||
| 102 | } |
||
| 103 | |||
| 104 | void ScrollbarWidget::GoToBottom() |
||
| 105 | { |
||
| 106 | mValue = mMaxValue - mPageSize; |
||
| 107 | ClampValue(); |
||
| 108 | SetValue(mValue); |
||
| 109 | } |
||
| 110 | |||
| 111 | void ScrollbarWidget::DrawThumb(Graphics *g, int theX, int theY, int theWidth, int theHeight) |
||
| 112 | { |
||
| 113 | g->SetColor(Color(212, 212, 212)); |
||
| 114 | g->FillRect(theX, theY, theWidth, theHeight); |
||
| 115 | |||
| 116 | g->SetColor(Color(255, 255, 255)); |
||
| 117 | g->FillRect(theX + 1, theY + 1, theWidth-2, 1); |
||
| 118 | g->FillRect(theX + 1, theY + 1, 1, theHeight-2); |
||
| 119 | |||
| 120 | g->SetColor(Color::Black); |
||
| 121 | g->FillRect(theX, theY + theHeight - 1, theWidth, 1); |
||
| 122 | g->FillRect(theX + theWidth - 1, theY, 1, theHeight); |
||
| 123 | |||
| 124 | g->SetColor(Color(132, 132, 132)); |
||
| 125 | g->FillRect(theX + 1, theY + theHeight - 2, theWidth - 2, 1); |
||
| 126 | g->FillRect(theX + theWidth - 2, theY + 1, 1, theHeight - 2); |
||
| 127 | } |
||
| 128 | |||
| 129 | int ScrollbarWidget::GetTrackSize() |
||
| 130 | { |
||
| 131 | if (mHorizontal) |
||
| 132 | return mWidth-2*mUpButton->mWidth; |
||
| 133 | else |
||
| 134 | return mHeight-2*mUpButton->mWidth; |
||
| 135 | } |
||
| 136 | |||
| 137 | int ScrollbarWidget::GetThumbSize() |
||
| 138 | { |
||
| 139 | if (mPageSize > mMaxValue) |
||
| 140 | return 0; |
||
| 141 | |||
| 142 | int aThumbSize = (int) ((double) ((GetTrackSize() * mPageSize / mMaxValue)) + 0.5); |
||
| 143 | return max(8, aThumbSize); |
||
| 144 | } |
||
| 145 | |||
| 146 | int ScrollbarWidget::GetThumbPosition() |
||
| 147 | { |
||
| 148 | if (mPageSize > mMaxValue) return mUpButton->mWidth; |
||
| 149 | return (int) ((double) (((mValue * (GetTrackSize() - GetThumbSize())) / (mMaxValue - mPageSize))) + 0.5) + mUpButton->mWidth; |
||
| 150 | } |
||
| 151 | |||
| 152 | void ScrollbarWidget::Draw(Graphics *g) |
||
| 153 | { |
||
| 154 | int aThumbSize = GetThumbSize(); |
||
| 155 | int aThumbPosition = GetThumbPosition(); |
||
| 156 | |||
| 157 | if (mHorizontal) |
||
| 158 | { |
||
| 159 | if (mUpdateMode == UPDATE_MODE_PGUP) |
||
| 160 | g->SetColor(Color(48, 48, 48)); |
||
| 161 | else |
||
| 162 | g->SetColor(Color(232, 232, 232)); |
||
| 163 | g->FillRect(0, 0, aThumbPosition, mHeight); |
||
| 164 | |||
| 165 | if (aThumbSize > 0) |
||
| 166 | DrawThumb(g, aThumbPosition, 0, aThumbSize, mHeight); |
||
| 167 | |||
| 168 | if (mUpdateMode == UPDATE_MODE_PGDN) |
||
| 169 | g->SetColor(Color(48, 48, 48)); |
||
| 170 | else |
||
| 171 | g->SetColor(Color(232, 232, 232)); |
||
| 172 | g->FillRect(aThumbPosition + aThumbSize, 0, mWidth - aThumbPosition - aThumbSize, mHeight); |
||
| 173 | } |
||
| 174 | else |
||
| 175 | { |
||
| 176 | if (mUpdateMode == UPDATE_MODE_PGUP) |
||
| 177 | g->SetColor(Color(48, 48, 48)); |
||
| 178 | else |
||
| 179 | g->SetColor(Color(232, 232, 232)); |
||
| 180 | g->FillRect(0, 0, mWidth, aThumbPosition); |
||
| 181 | |||
| 182 | if (aThumbSize > 0) |
||
| 183 | DrawThumb(g, 0, aThumbPosition, mWidth, aThumbSize); |
||
| 184 | |||
| 185 | if (mUpdateMode == UPDATE_MODE_PGDN) |
||
| 186 | g->SetColor(Color(48, 48, 48)); |
||
| 187 | else |
||
| 188 | g->SetColor(Color(232, 232, 232)); |
||
| 189 | g->FillRect(0, aThumbPosition + aThumbSize, mWidth, mHeight - aThumbPosition - aThumbSize); |
||
| 190 | } |
||
| 191 | } |
||
| 192 | |||
| 193 | void ScrollbarWidget::ClampValue() |
||
| 194 | { |
||
| 195 | double anOldValue = mValue; |
||
| 196 | |||
| 197 | if (mValue > mMaxValue - mPageSize) |
||
| 198 | mValue = mMaxValue - mPageSize; |
||
| 199 | if (mValue < 0.0) |
||
| 200 | mValue = 0.0; |
||
| 201 | |||
| 202 | bool canScroll = mPageSize < mMaxValue; |
||
| 203 | |||
| 204 | SetDisabled(!canScroll); |
||
| 205 | mUpButton->SetDisabled(!canScroll); |
||
| 206 | mDownButton->SetDisabled(!canScroll); |
||
| 207 | |||
| 208 | if (mInvisIfNoScroll) |
||
| 209 | { |
||
| 210 | SetVisible(canScroll); |
||
| 211 | mDownButton->SetVisible(canScroll); |
||
| 212 | mUpButton->SetVisible(canScroll); |
||
| 213 | } |
||
| 214 | |||
| 215 | if (mValue != anOldValue) mScrollListener->ScrollPosition(mId, mValue); |
||
| 216 | } |
||
| 217 | |||
| 218 | void ScrollbarWidget::SetThumbPosition(int thePosition) |
||
| 219 | { |
||
| 220 | SetValue(((thePosition-mUpButton->mWidth) * (mMaxValue - mPageSize)) / (GetTrackSize() - GetThumbSize())); |
||
| 221 | } |
||
| 222 | |||
| 223 | void ScrollbarWidget::ButtonPress(int theId) |
||
| 224 | { |
||
| 225 | mButtonAcc = 0; |
||
| 226 | |||
| 227 | if (theId == 0) |
||
| 228 | SetValue(mValue-1); |
||
| 229 | else |
||
| 230 | SetValue(mValue+1); |
||
| 231 | } |
||
| 232 | |||
| 233 | void ScrollbarWidget::ButtonDepress(int theId) |
||
| 234 | { |
||
| 235 | } |
||
| 236 | |||
| 237 | void ScrollbarWidget::ButtonDownTick(int theId) |
||
| 238 | { |
||
| 239 | if (theId == 0) |
||
| 240 | { |
||
| 241 | if (++mButtonAcc >= 25) |
||
| 242 | { |
||
| 243 | SetValue(mValue-1); |
||
| 244 | mButtonAcc = 24; |
||
| 245 | } |
||
| 246 | } |
||
| 247 | else |
||
| 248 | { |
||
| 249 | if (++mButtonAcc >= 25) |
||
| 250 | { |
||
| 251 | SetValue(mValue+1); |
||
| 252 | mButtonAcc = 24; |
||
| 253 | } |
||
| 254 | } |
||
| 255 | } |
||
| 256 | |||
| 257 | void ScrollbarWidget::Update() |
||
| 258 | { |
||
| 259 | Widget::Update(); |
||
| 260 | |||
| 261 | switch (mUpdateMode) |
||
| 262 | { |
||
| 263 | case UPDATE_MODE_PGUP: |
||
| 264 | if (ThumbCompare(mLastMouseX, mLastMouseY) != -1) |
||
| 265 | { |
||
| 266 | mUpdateMode = UPDATE_MODE_IDLE; |
||
| 267 | MarkDirty(); |
||
| 268 | } |
||
| 269 | else if (++mUpdateAcc >= 25) |
||
| 270 | { |
||
| 271 | SetValue(mValue - mPageSize); |
||
| 272 | mUpdateAcc = 20; |
||
| 273 | } |
||
| 274 | break; |
||
| 275 | case UPDATE_MODE_PGDN: |
||
| 276 | if (ThumbCompare(mLastMouseX, mLastMouseY) != 1) |
||
| 277 | { |
||
| 278 | mUpdateMode = UPDATE_MODE_IDLE; |
||
| 279 | MarkDirty(); |
||
| 280 | } |
||
| 281 | else if (++mUpdateAcc >= 25) |
||
| 282 | { |
||
| 283 | SetValue(mValue + mPageSize); |
||
| 284 | mUpdateAcc = 20; |
||
| 285 | } |
||
| 286 | break; |
||
| 287 | } |
||
| 288 | } |
||
| 289 | |||
| 290 | int ScrollbarWidget::ThumbCompare(int x, int y) |
||
| 291 | { |
||
| 292 | int aTrackPosition; |
||
| 293 | |||
| 294 | if (mHorizontal) |
||
| 295 | aTrackPosition = x; |
||
| 296 | else |
||
| 297 | aTrackPosition = y; |
||
| 298 | |||
| 299 | if (aTrackPosition < GetThumbPosition()) |
||
| 300 | return -1; |
||
| 301 | |||
| 302 | if (aTrackPosition >= GetThumbPosition() + GetThumbSize()) |
||
| 303 | return 1; |
||
| 304 | |||
| 305 | return 0; |
||
| 306 | } |
||
| 307 | |||
| 308 | void ScrollbarWidget::MouseDown(int x, int y, int theBtnNum, int theClickCount) |
||
| 309 | { |
||
| 310 | Widget::MouseDown(x, y, theBtnNum, theClickCount); |
||
| 311 | |||
| 312 | if (!mDisabled) |
||
| 313 | { |
||
| 314 | switch (ThumbCompare(x, y)) |
||
| 315 | { |
||
| 316 | case -1: |
||
| 317 | SetValue(mValue - mPageSize); |
||
| 318 | mUpdateMode = UPDATE_MODE_PGUP; |
||
| 319 | mUpdateAcc = 0; |
||
| 320 | break; |
||
| 321 | case 0: |
||
| 322 | mPressedOnThumb = true; |
||
| 323 | mMouseDownThumbPos = GetThumbPosition(); |
||
| 324 | mMouseDownX = x; |
||
| 325 | mMouseDownY = y; |
||
| 326 | break; |
||
| 327 | case 1: |
||
| 328 | SetValue(mValue + mPageSize); |
||
| 329 | mUpdateMode = UPDATE_MODE_PGDN; |
||
| 330 | mUpdateAcc = 0; |
||
| 331 | break; |
||
| 332 | } |
||
| 333 | } |
||
| 334 | |||
| 335 | mLastMouseX = x; |
||
| 336 | mLastMouseY = y; |
||
| 337 | } |
||
| 338 | |||
| 339 | void ScrollbarWidget::MouseUp(int x, int y, int theBtnNum, int theClickCount) |
||
| 340 | { |
||
| 341 | Widget::MouseUp(x, y, theBtnNum, theClickCount); |
||
| 342 | |||
| 343 | mUpdateMode = 0; |
||
| 344 | mPressedOnThumb = false; |
||
| 345 | MarkDirty(); |
||
| 346 | } |
||
| 347 | |||
| 348 | void ScrollbarWidget::MouseDrag(int x, int y) |
||
| 349 | { |
||
| 350 | Widget::MouseDrag(x, y); |
||
| 351 | |||
| 352 | if (mPressedOnThumb) |
||
| 353 | { |
||
| 354 | if (mHorizontal) |
||
| 355 | SetThumbPosition(mMouseDownThumbPos + x - mMouseDownX); |
||
| 356 | else |
||
| 357 | SetThumbPosition(mMouseDownThumbPos + y - mMouseDownY); |
||
| 358 | } |
||
| 359 | |||
| 360 | mLastMouseX = x; |
||
| 361 | mLastMouseY = y; |
||
| 362 | } |