btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / deskbar / InlineScrollView.cpp
blob27cbafbac26a024a1a0927c0a13f7f65cd7db512
1 /*
2 * Copyright 2012, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Marc Flerackers (mflerackers@androme.be)
7 * Stefano Ceccherini (stefano.ceccherini@gmail.com)
8 * John Scipione (jscipione@gmail.com)
9 */
12 #include "InlineScrollView.h"
14 #include <ControlLook.h>
15 #include <Debug.h>
16 #include <InterfaceDefs.h>
17 #include <Menu.h>
18 #include <Point.h>
19 #include <Screen.h>
20 #include <Window.h>
23 const int kDefaultScrollStep = 19;
24 const int kScrollerDimension = 12;
27 class ScrollArrow : public BView {
28 public:
29 ScrollArrow(BRect frame);
30 virtual ~ScrollArrow();
32 bool IsEnabled() const { return fEnabled; };
33 void SetEnabled(bool enabled);
35 private:
36 bool fEnabled;
40 class UpScrollArrow : public ScrollArrow {
41 public:
42 UpScrollArrow(BRect frame);
43 virtual ~UpScrollArrow();
45 virtual void Draw(BRect updateRect);
46 virtual void MouseDown(BPoint where);
50 class DownScrollArrow : public ScrollArrow {
51 public:
52 DownScrollArrow(BRect frame);
53 virtual ~DownScrollArrow();
55 virtual void Draw(BRect updateRect);
56 virtual void MouseDown(BPoint where);
60 class LeftScrollArrow : public ScrollArrow {
61 public:
62 LeftScrollArrow(BRect frame);
63 virtual ~LeftScrollArrow();
65 virtual void Draw(BRect updateRect);
66 virtual void MouseDown(BPoint where);
70 class RightScrollArrow : public ScrollArrow {
71 public:
72 RightScrollArrow(BRect frame);
73 virtual ~RightScrollArrow();
75 virtual void Draw(BRect updateRect);
76 virtual void MouseDown(BPoint where);
80 // #pragma mark -
83 ScrollArrow::ScrollArrow(BRect frame)
85 BView(frame, "menu scroll arrow", B_FOLLOW_NONE, B_WILL_DRAW),
86 fEnabled(false)
88 SetViewUIColor(B_MENU_BACKGROUND_COLOR);
92 ScrollArrow::~ScrollArrow()
97 void
98 ScrollArrow::SetEnabled(bool enabled)
100 fEnabled = enabled;
101 Invalidate();
105 // #pragma mark -
108 UpScrollArrow::UpScrollArrow(BRect frame)
110 ScrollArrow(frame)
115 UpScrollArrow::~UpScrollArrow()
120 void
121 UpScrollArrow::Draw(BRect updateRect)
123 SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
124 B_DARKEN_1_TINT));
126 if (IsEnabled())
127 SetHighColor(0, 0, 0);
128 else {
129 SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
130 B_DARKEN_2_TINT));
133 FillRect(Bounds(), B_SOLID_LOW);
135 float middle = Bounds().right / 2;
136 FillTriangle(BPoint(middle, (kScrollerDimension / 2) - 3),
137 BPoint(middle + 5, (kScrollerDimension / 2) + 2),
138 BPoint(middle - 5, (kScrollerDimension / 2) + 2));
142 void
143 UpScrollArrow::MouseDown(BPoint where)
145 if (!IsEnabled())
146 return;
148 TInlineScrollView* parent = dynamic_cast<TInlineScrollView*>(Parent());
149 if (parent == NULL)
150 return;
152 float smallStep;
153 float largeStep;
154 parent->GetSteps(&smallStep, &largeStep);
156 BMessage* message = Window()->CurrentMessage();
157 int32 modifiers = 0;
158 message->FindInt32("modifiers", &modifiers);
159 // pressing the shift key scrolls faster
160 if ((modifiers & B_SHIFT_KEY) != 0)
161 parent->ScrollBy(-largeStep);
162 else
163 parent->ScrollBy(-smallStep);
165 snooze(5000);
169 // #pragma mark -
172 DownScrollArrow::DownScrollArrow(BRect frame)
174 ScrollArrow(frame)
179 DownScrollArrow::~DownScrollArrow()
184 void
185 DownScrollArrow::Draw(BRect updateRect)
187 SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
188 B_DARKEN_1_TINT));
190 if (IsEnabled())
191 SetHighColor(0, 0, 0);
192 else {
193 SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
194 B_DARKEN_2_TINT));
197 BRect frame = Bounds();
198 FillRect(frame, B_SOLID_LOW);
200 float middle = Bounds().right / 2;
201 FillTriangle(BPoint(middle, frame.bottom - (kScrollerDimension / 2) + 3),
202 BPoint(middle + 5, frame.bottom - (kScrollerDimension / 2) - 2),
203 BPoint(middle - 5, frame.bottom - (kScrollerDimension / 2) - 2));
207 void
208 DownScrollArrow::MouseDown(BPoint where)
210 if (!IsEnabled())
211 return;
213 TInlineScrollView* grandparent
214 = dynamic_cast<TInlineScrollView*>(Parent()->Parent());
215 if (grandparent == NULL)
216 return;
218 float smallStep;
219 float largeStep;
220 grandparent->GetSteps(&smallStep, &largeStep);
222 BMessage* message = Window()->CurrentMessage();
223 int32 modifiers = 0;
224 message->FindInt32("modifiers", &modifiers);
225 // pressing the shift key scrolls faster
226 if ((modifiers & B_SHIFT_KEY) != 0)
227 grandparent->ScrollBy(largeStep);
228 else
229 grandparent->ScrollBy(smallStep);
231 snooze(5000);
235 // #pragma mark -
238 LeftScrollArrow::LeftScrollArrow(BRect frame)
240 ScrollArrow(frame)
245 LeftScrollArrow::~LeftScrollArrow()
250 void
251 LeftScrollArrow::Draw(BRect updateRect)
253 SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT));
255 if (IsEnabled())
256 SetHighColor(0, 0, 0);
257 else {
258 SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
259 B_DARKEN_2_TINT));
262 FillRect(Bounds(), B_SOLID_LOW);
264 float middle = Bounds().bottom / 2;
265 FillTriangle(BPoint((kScrollerDimension / 2) - 3, middle),
266 BPoint((kScrollerDimension / 2) + 2, middle + 5),
267 BPoint((kScrollerDimension / 2) + 2, middle - 5));
271 void
272 LeftScrollArrow::MouseDown(BPoint where)
274 if (!IsEnabled())
275 return;
277 TInlineScrollView* parent = dynamic_cast<TInlineScrollView*>(Parent());
278 if (parent == NULL)
279 return;
281 float smallStep;
282 float largeStep;
283 parent->GetSteps(&smallStep, &largeStep);
285 BMessage* message = Window()->CurrentMessage();
286 int32 modifiers = 0;
287 message->FindInt32("modifiers", &modifiers);
288 // pressing the shift key scrolls faster
289 if ((modifiers & B_SHIFT_KEY) != 0)
290 parent->ScrollBy(-largeStep);
291 else
292 parent->ScrollBy(-smallStep);
294 snooze(5000);
298 // #pragma mark -
301 RightScrollArrow::RightScrollArrow(BRect frame)
303 ScrollArrow(frame)
308 RightScrollArrow::~RightScrollArrow()
313 void
314 RightScrollArrow::Draw(BRect updateRect)
316 SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT));
318 if (IsEnabled())
319 SetHighColor(0, 0, 0);
320 else {
321 SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
322 B_DARKEN_2_TINT));
325 BRect frame = Bounds();
326 FillRect(frame, B_SOLID_LOW);
328 float middle = Bounds().bottom / 2;
329 FillTriangle(BPoint(kScrollerDimension / 2 + 3, middle),
330 BPoint(kScrollerDimension / 2 - 2, middle + 5),
331 BPoint(kScrollerDimension / 2 - 2, middle - 5));
335 void
336 RightScrollArrow::MouseDown(BPoint where)
338 if (!IsEnabled())
339 return;
341 TInlineScrollView* grandparent
342 = dynamic_cast<TInlineScrollView*>(Parent()->Parent());
343 if (grandparent == NULL)
344 return;
346 float smallStep;
347 float largeStep;
348 grandparent->GetSteps(&smallStep, &largeStep);
350 BMessage* message = Window()->CurrentMessage();
351 int32 modifiers = 0;
352 message->FindInt32("modifiers", &modifiers);
353 // pressing the shift key scrolls faster
354 if ((modifiers & B_SHIFT_KEY) != 0)
355 grandparent->ScrollBy(largeStep);
356 else
357 grandparent->ScrollBy(smallStep);
359 snooze(5000);
363 // #pragma mark -
366 TInlineScrollView::TInlineScrollView(BView* target,
367 enum orientation orientation)
369 BView(BRect(0, 0, 0, 0), "inline scroll view", B_FOLLOW_NONE, B_WILL_DRAW),
370 fTarget(target),
371 fBeginScrollArrow(NULL),
372 fEndScrollArrow(NULL),
373 fScrollStep(kDefaultScrollStep),
374 fScrollValue(0),
375 fScrollLimit(0),
376 fOrientation(orientation)
381 TInlineScrollView::~TInlineScrollView()
383 if (fBeginScrollArrow != NULL) {
384 fBeginScrollArrow->RemoveSelf();
385 delete fBeginScrollArrow;
386 fBeginScrollArrow = NULL;
389 if (fEndScrollArrow != NULL) {
390 fEndScrollArrow->RemoveSelf();
391 delete fEndScrollArrow;
392 fEndScrollArrow = NULL;
397 void
398 TInlineScrollView::AttachedToWindow()
400 BView::AttachedToWindow();
402 if (fTarget == NULL)
403 return;
405 AddChild(fTarget);
406 fTarget->MoveTo(0, 0);
410 void
411 TInlineScrollView::DetachedFromWindow()
413 BView::DetachedFromWindow();
415 if (fTarget != NULL)
416 fTarget->RemoveSelf();
418 if (fBeginScrollArrow != NULL)
419 fBeginScrollArrow->RemoveSelf();
421 if (fEndScrollArrow != NULL)
422 fEndScrollArrow->RemoveSelf();
426 void
427 TInlineScrollView::Draw(BRect updateRect)
429 BRect frame = Bounds();
430 be_control_look->DrawButtonBackground(this, frame, updateRect,
431 ui_color(B_MENU_BACKGROUND_COLOR));
435 // #pragma mark -
438 void
439 TInlineScrollView::AttachScrollers()
441 if (fTarget == NULL)
442 return;
444 BRect frame = Bounds();
446 if (HasScrollers()) {
447 if (fOrientation == B_VERTICAL) {
448 fScrollLimit = fTarget->Bounds().Height()
449 - (frame.Height() - 2 * kScrollerDimension);
450 } else {
451 fScrollLimit = fTarget->Bounds().Width()
452 - (frame.Width() - 2 * kScrollerDimension);
455 if (fScrollValue > fScrollLimit) {
456 // If scroll value is above limit scroll back
457 float delta = fScrollLimit - fScrollValue;
458 if (fOrientation == B_VERTICAL)
459 fTarget->ScrollBy(0, delta);
460 else
461 fTarget->ScrollBy(delta, 0);
463 fScrollValue = fScrollLimit;
465 return;
468 fTarget->MakeFocus(true);
470 if (fOrientation == B_VERTICAL) {
471 if (fBeginScrollArrow == NULL) {
472 fBeginScrollArrow = new UpScrollArrow(
473 BRect(frame.left, frame.top, frame.right,
474 kScrollerDimension - 1));
475 AddChild(fBeginScrollArrow);
478 if (fEndScrollArrow == NULL) {
479 fEndScrollArrow = new DownScrollArrow(
480 BRect(0, frame.bottom - 2 * kScrollerDimension + 1, frame.right,
481 frame.bottom - kScrollerDimension));
482 fTarget->AddChild(fEndScrollArrow);
485 fTarget->MoveBy(0, kScrollerDimension);
487 fScrollLimit = fTarget->Bounds().Height()
488 - (frame.Height() - 2 * kScrollerDimension);
489 } else {
490 if (fBeginScrollArrow == NULL) {
491 fBeginScrollArrow = new LeftScrollArrow(
492 BRect(frame.left, frame.top,
493 frame.left + kScrollerDimension - 1, frame.bottom));
494 AddChild(fBeginScrollArrow);
497 if (fEndScrollArrow == NULL) {
498 fEndScrollArrow = new RightScrollArrow(
499 BRect(frame.right - 2 * kScrollerDimension + 1, frame.top,
500 frame.right, frame.bottom));
501 fTarget->AddChild(fEndScrollArrow);
504 fTarget->MoveBy(kScrollerDimension, 0);
506 fScrollLimit = fTarget->Bounds().Width()
507 - (frame.Width() - 2 * kScrollerDimension);
510 fBeginScrollArrow->SetEnabled(false);
511 fEndScrollArrow->SetEnabled(true);
513 fScrollValue = 0;
517 void
518 TInlineScrollView::DetachScrollers()
520 if (!HasScrollers())
521 return;
523 if (fEndScrollArrow) {
524 fEndScrollArrow->RemoveSelf();
525 delete fEndScrollArrow;
526 fEndScrollArrow = NULL;
529 if (fBeginScrollArrow) {
530 fBeginScrollArrow->RemoveSelf();
531 delete fBeginScrollArrow;
532 fBeginScrollArrow = NULL;
535 if (fTarget) {
536 // We don't remember the position where the last scrolling
537 // ended, so scroll back to the beginning.
538 if (fOrientation == B_VERTICAL)
539 fTarget->MoveBy(0, -kScrollerDimension);
540 else
541 fTarget->MoveBy(-kScrollerDimension, 0);
543 fTarget->ScrollTo(0, 0);
544 fScrollValue = 0;
549 bool
550 TInlineScrollView::HasScrollers() const
552 return fTarget != NULL && fBeginScrollArrow != NULL
553 && fEndScrollArrow != NULL;
557 void
558 TInlineScrollView::SetSmallStep(float step)
560 fScrollStep = step;
564 void
565 TInlineScrollView::GetSteps(float* _smallStep, float* _largeStep) const
567 if (_smallStep != NULL)
568 *_smallStep = fScrollStep;
569 if (_largeStep != NULL) {
570 *_largeStep = fScrollStep * 3;
575 void
576 TInlineScrollView::ScrollBy(const float& step)
578 if (!HasScrollers())
579 return;
581 if (step > 0) {
582 if (fScrollValue == 0)
583 fBeginScrollArrow->SetEnabled(true);
585 if (fScrollValue + step >= fScrollLimit) {
586 // If we reached the limit, only scroll to the end
587 if (fOrientation == B_VERTICAL) {
588 fTarget->ScrollBy(0, fScrollLimit - fScrollValue);
589 fEndScrollArrow->MoveBy(0, fScrollLimit - fScrollValue);
590 } else {
591 fTarget->ScrollBy(fScrollLimit - fScrollValue, 0);
592 fEndScrollArrow->MoveBy(fScrollLimit - fScrollValue, 0);
594 fEndScrollArrow->SetEnabled(false);
595 fScrollValue = fScrollLimit;
596 } else {
597 if (fOrientation == B_VERTICAL) {
598 fTarget->ScrollBy(0, step);
599 fEndScrollArrow->MoveBy(0, step);
600 } else {
601 fTarget->ScrollBy(step, 0);
602 fEndScrollArrow->MoveBy(step, 0);
604 fScrollValue += step;
606 } else if (step < 0) {
607 if (fScrollValue == fScrollLimit)
608 fEndScrollArrow->SetEnabled(true);
610 if (fScrollValue + step <= 0) {
611 if (fOrientation == B_VERTICAL) {
612 fTarget->ScrollBy(0, -fScrollValue);
613 fEndScrollArrow->MoveBy(0, -fScrollValue);
614 } else {
615 fTarget->ScrollBy(-fScrollValue, 0);
616 fEndScrollArrow->MoveBy(-fScrollValue, 0);
618 fBeginScrollArrow->SetEnabled(false);
619 fScrollValue = 0;
620 } else {
621 if (fOrientation == B_VERTICAL) {
622 fTarget->ScrollBy(0, step);
623 fEndScrollArrow->MoveBy(0, step);
624 } else {
625 fTarget->ScrollBy(step, 0);
626 fEndScrollArrow->MoveBy(step, 0);
628 fScrollValue += step;
632 //fTarget->Invalidate();