xref: /haiku/src/kits/interface/MenuWindow.cpp (revision 9e64a7ed1ba6e91718aeae9a5a32c74ba9ca5421)
1c7023acdSAxel Dörfler /*
2059ca4bdSStefano Ceccherini  * Copyright 2001-2007, Haiku, Inc.
3c7023acdSAxel Dörfler  * Distributed under the terms of the MIT License.
4c7023acdSAxel Dörfler  *
5c7023acdSAxel Dörfler  * Authors:
6c7023acdSAxel Dörfler  *		Marc Flerackers (mflerackers@androme.be)
7059ca4bdSStefano Ceccherini  *		Stefano Ceccherini (stefano.ceccherini@gmail.com)
8c7023acdSAxel Dörfler  */
9c7023acdSAxel Dörfler 
10c7023acdSAxel Dörfler //!	BMenuWindow is a custom BWindow for BMenus.
11c7023acdSAxel Dörfler 
12059ca4bdSStefano Ceccherini #include <Debug.h>
13446b8c19SStefano Ceccherini #include <Menu.h>
14446b8c19SStefano Ceccherini 
152c11ec31SStefano Ceccherini #include <MenuPrivate.h>
162c11ec31SStefano Ceccherini #include <MenuWindow.h>
17c7023acdSAxel Dörfler #include <WindowPrivate.h>
18c7023acdSAxel Dörfler 
19e411c658SStefano Ceccherini 
202628e60cSAxel Dörfler namespace BPrivate {
212628e60cSAxel Dörfler 
222628e60cSAxel Dörfler class BMenuScroller : public BView {
232628e60cSAxel Dörfler 	public:
243616859aSStefano Ceccherini 		BMenuScroller(BRect frame);
252628e60cSAxel Dörfler 
263616859aSStefano Ceccherini 		bool IsEnabled() const;
273616859aSStefano Ceccherini 		void SetEnabled(const bool &enabled);
282628e60cSAxel Dörfler 	private:
293616859aSStefano Ceccherini 		bool fEnabled;
302628e60cSAxel Dörfler };
312628e60cSAxel Dörfler 
323616859aSStefano Ceccherini 
332628e60cSAxel Dörfler class BMenuFrame : public BView {
342628e60cSAxel Dörfler 	public:
352628e60cSAxel Dörfler 		BMenuFrame(BMenu *menu);
362628e60cSAxel Dörfler 
372628e60cSAxel Dörfler 		virtual void AttachedToWindow();
382628e60cSAxel Dörfler 		virtual void DetachedFromWindow();
392628e60cSAxel Dörfler 		virtual void Draw(BRect updateRect);
402628e60cSAxel Dörfler 
412628e60cSAxel Dörfler 	private:
422628e60cSAxel Dörfler 		friend class BMenuWindow;
432628e60cSAxel Dörfler 
442628e60cSAxel Dörfler 		BMenu *fMenu;
452628e60cSAxel Dörfler };
462628e60cSAxel Dörfler 
473616859aSStefano Ceccherini 
483616859aSStefano Ceccherini class UpperScroller : public BMenuScroller {
493616859aSStefano Ceccherini public:
503616859aSStefano Ceccherini 	UpperScroller(BRect frame);
513616859aSStefano Ceccherini 	virtual void Draw(BRect updateRect);
523616859aSStefano Ceccherini };
533616859aSStefano Ceccherini 
54059ca4bdSStefano Ceccherini 
553616859aSStefano Ceccherini class LowerScroller : public BMenuScroller {
563616859aSStefano Ceccherini public:
573616859aSStefano Ceccherini 	LowerScroller(BRect frame);
583616859aSStefano Ceccherini 	virtual void Draw(BRect updateRect);
593616859aSStefano Ceccherini };
603616859aSStefano Ceccherini 
61059ca4bdSStefano Ceccherini 
622628e60cSAxel Dörfler }	// namespace BPrivate
632628e60cSAxel Dörfler 
643616859aSStefano Ceccherini 
652628e60cSAxel Dörfler using namespace BPrivate;
662628e60cSAxel Dörfler 
672628e60cSAxel Dörfler 
6827cc2508SStefano Ceccherini const int kScrollerHeight = 10;
69c7338938SStefano Ceccherini const int kScrollStep = 19;
705b752875SStefano Ceccherini 
712628e60cSAxel Dörfler 
723616859aSStefano Ceccherini BMenuScroller::BMenuScroller(BRect frame)
73c7338938SStefano Ceccherini 	: BView(frame, "menu scroller", 0, B_WILL_DRAW | B_FRAME_EVENTS),
743616859aSStefano Ceccherini 	fEnabled(false)
7527cc2508SStefano Ceccherini {
7627cc2508SStefano Ceccherini 	SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR));
7727cc2508SStefano Ceccherini }
7827cc2508SStefano Ceccherini 
7927cc2508SStefano Ceccherini 
80c7338938SStefano Ceccherini bool
813616859aSStefano Ceccherini BMenuScroller::IsEnabled() const
8227cc2508SStefano Ceccherini {
833616859aSStefano Ceccherini 	return fEnabled;
8427cc2508SStefano Ceccherini }
8527cc2508SStefano Ceccherini 
8627cc2508SStefano Ceccherini 
8727cc2508SStefano Ceccherini void
883616859aSStefano Ceccherini BMenuScroller::SetEnabled(const bool &enabled)
893616859aSStefano Ceccherini {
903616859aSStefano Ceccherini 	fEnabled = enabled;
913616859aSStefano Ceccherini }
923616859aSStefano Ceccherini 
933616859aSStefano Ceccherini 
943616859aSStefano Ceccherini //	#pragma mark -
953616859aSStefano Ceccherini 
963616859aSStefano Ceccherini 
973616859aSStefano Ceccherini UpperScroller::UpperScroller(BRect frame)
983616859aSStefano Ceccherini 	:
993616859aSStefano Ceccherini 	BMenuScroller(frame)
1003616859aSStefano Ceccherini {
1013616859aSStefano Ceccherini }
1023616859aSStefano Ceccherini 
1033616859aSStefano Ceccherini 
1043616859aSStefano Ceccherini void
1053616859aSStefano Ceccherini UpperScroller::Draw(BRect updateRect)
10627cc2508SStefano Ceccherini {
10727cc2508SStefano Ceccherini 	SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT));
10827cc2508SStefano Ceccherini 	float middle = Bounds().right / 2;
10927cc2508SStefano Ceccherini 
11027cc2508SStefano Ceccherini 	// Draw the upper arrow.
1113616859aSStefano Ceccherini 	if (IsEnabled())
11227cc2508SStefano Ceccherini 		SetHighColor(0, 0, 0);
11327cc2508SStefano Ceccherini 	else
11427cc2508SStefano Ceccherini 		SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
11527cc2508SStefano Ceccherini 					B_DARKEN_2_TINT));
11627cc2508SStefano Ceccherini 
1173616859aSStefano Ceccherini 	FillRect(Bounds(), B_SOLID_LOW);
11827cc2508SStefano Ceccherini 
11927cc2508SStefano Ceccherini 	FillTriangle(BPoint(middle, (kScrollerHeight / 2) - 3),
12027cc2508SStefano Ceccherini 			BPoint(middle + 5, (kScrollerHeight / 2) + 2),
12127cc2508SStefano Ceccherini 			BPoint(middle - 5, (kScrollerHeight / 2) + 2));
12227cc2508SStefano Ceccherini }
12327cc2508SStefano Ceccherini 
1243616859aSStefano Ceccherini 
1253616859aSStefano Ceccherini //	#pragma mark -
1263616859aSStefano Ceccherini 
1273616859aSStefano Ceccherini 
1283616859aSStefano Ceccherini LowerScroller::LowerScroller(BRect frame)
1293616859aSStefano Ceccherini 	:
1303616859aSStefano Ceccherini 	BMenuScroller(frame)
1313616859aSStefano Ceccherini {
1323616859aSStefano Ceccherini }
1333616859aSStefano Ceccherini 
1343616859aSStefano Ceccherini 
1353616859aSStefano Ceccherini void
1363616859aSStefano Ceccherini LowerScroller::Draw(BRect updateRect)
1373616859aSStefano Ceccherini {
1383616859aSStefano Ceccherini 	SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT));
1393616859aSStefano Ceccherini 
1403616859aSStefano Ceccherini 	BRect frame = Bounds();
14127cc2508SStefano Ceccherini 	// Draw the lower arrow.
1423616859aSStefano Ceccherini 	if (IsEnabled())
14327cc2508SStefano Ceccherini 		SetHighColor(0, 0, 0);
14427cc2508SStefano Ceccherini 	else
14527cc2508SStefano Ceccherini 		SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
14627cc2508SStefano Ceccherini 			B_DARKEN_2_TINT));
14727cc2508SStefano Ceccherini 
148059ca4bdSStefano Ceccherini 	FillRect(frame, B_SOLID_LOW);
14927cc2508SStefano Ceccherini 
1503616859aSStefano Ceccherini 	float middle = Bounds().right / 2;
1513616859aSStefano Ceccherini 
1523616859aSStefano Ceccherini 	FillTriangle(BPoint(middle, frame.bottom - (kScrollerHeight / 2) + 3),
1533616859aSStefano Ceccherini 			BPoint(middle + 5, frame.bottom - (kScrollerHeight / 2) - 2),
1543616859aSStefano Ceccherini 			BPoint(middle - 5, frame.bottom - (kScrollerHeight / 2) - 2));
15527cc2508SStefano Ceccherini }
15627cc2508SStefano Ceccherini 
15727cc2508SStefano Ceccherini 
15827cc2508SStefano Ceccherini //	#pragma mark -
1595b752875SStefano Ceccherini 
1605b752875SStefano Ceccherini 
1612628e60cSAxel Dörfler BMenuFrame::BMenuFrame(BMenu *menu)
1622628e60cSAxel Dörfler 	: BView(BRect(0, 0, 1, 1), "menu frame", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
1632628e60cSAxel Dörfler 	fMenu(menu)
1642628e60cSAxel Dörfler {
1652628e60cSAxel Dörfler }
1662628e60cSAxel Dörfler 
1672628e60cSAxel Dörfler 
1682628e60cSAxel Dörfler void
1692628e60cSAxel Dörfler BMenuFrame::AttachedToWindow()
1702628e60cSAxel Dörfler {
1712628e60cSAxel Dörfler 	BView::AttachedToWindow();
1722628e60cSAxel Dörfler 
1732628e60cSAxel Dörfler 	if (fMenu != NULL)
1742628e60cSAxel Dörfler 		AddChild(fMenu);
1752628e60cSAxel Dörfler 
1762628e60cSAxel Dörfler 	ResizeTo(Window()->Bounds().Width(), Window()->Bounds().Height());
1772628e60cSAxel Dörfler 	if (fMenu != NULL) {
1782628e60cSAxel Dörfler 		BFont font;
1792628e60cSAxel Dörfler 		fMenu->GetFont(&font);
1802628e60cSAxel Dörfler 		SetFont(&font);
1812628e60cSAxel Dörfler 	}
1822628e60cSAxel Dörfler }
1832628e60cSAxel Dörfler 
1842628e60cSAxel Dörfler 
1852628e60cSAxel Dörfler void
1862628e60cSAxel Dörfler BMenuFrame::DetachedFromWindow()
1872628e60cSAxel Dörfler {
1882628e60cSAxel Dörfler 	if (fMenu != NULL)
1892628e60cSAxel Dörfler 		RemoveChild(fMenu);
1902628e60cSAxel Dörfler }
1912628e60cSAxel Dörfler 
1922628e60cSAxel Dörfler 
1932628e60cSAxel Dörfler void
1942628e60cSAxel Dörfler BMenuFrame::Draw(BRect updateRect)
1952628e60cSAxel Dörfler {
1962628e60cSAxel Dörfler 	if (fMenu != NULL && fMenu->CountItems() == 0) {
1972628e60cSAxel Dörfler 		// TODO: Review this as it's a bit hacky.
1982628e60cSAxel Dörfler 		// Menu has a size of 0, 0, since there are no items in it.
1992628e60cSAxel Dörfler 		// So the BMenuFrame class has to fake it and draw an empty item.
2002628e60cSAxel Dörfler 		// Note that we can't add a real "empty" item because then we couldn't
2012628e60cSAxel Dörfler 		// tell if the item was added by us or not.
2022628e60cSAxel Dörfler 		// See also BMenu::UpdateWindowViewSize()
2032628e60cSAxel Dörfler 		SetHighColor(ui_color(B_MENU_BACKGROUND_COLOR));
2042628e60cSAxel Dörfler 		SetLowColor(HighColor());
2052628e60cSAxel Dörfler 		FillRect(updateRect);
2062628e60cSAxel Dörfler 
2072628e60cSAxel Dörfler 		font_height height;
2082628e60cSAxel Dörfler 		GetFontHeight(&height);
2092628e60cSAxel Dörfler 		SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT));
2102628e60cSAxel Dörfler 		BPoint where((Bounds().Width() - fMenu->StringWidth(kEmptyMenuLabel)) / 2, ceilf(height.ascent + 1));
2112628e60cSAxel Dörfler 		DrawString(kEmptyMenuLabel, where);
2122628e60cSAxel Dörfler 	}
2132628e60cSAxel Dörfler 
2142628e60cSAxel Dörfler 	SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT));
2152628e60cSAxel Dörfler 	BRect bounds(Bounds());
2162628e60cSAxel Dörfler 
2172628e60cSAxel Dörfler 	StrokeLine(BPoint(bounds.right, bounds.top),
2182628e60cSAxel Dörfler 		BPoint(bounds.right, bounds.bottom - 1));
2192628e60cSAxel Dörfler 	StrokeLine(BPoint(bounds.left + 1, bounds.bottom),
2202628e60cSAxel Dörfler 		BPoint(bounds.right, bounds.bottom));
2212628e60cSAxel Dörfler }
2222628e60cSAxel Dörfler 
2232628e60cSAxel Dörfler 
2243616859aSStefano Ceccherini 
2252628e60cSAxel Dörfler //	#pragma mark -
2262628e60cSAxel Dörfler 
2272628e60cSAxel Dörfler 
2284185bd8bSStefano Ceccherini BMenuWindow::BMenuWindow(const char *name)
2291664b981SStefano Ceccherini 	// The window will be resized by BMenu, so just pass a dummy rect
230c7023acdSAxel Dörfler 	: BWindow(BRect(0, 0, 0, 0), name, B_BORDERED_WINDOW_LOOK, kMenuWindowFeel,
231c7023acdSAxel Dörfler 			B_NOT_ZOOMABLE | B_AVOID_FOCUS),
2323616859aSStefano Ceccherini 	fMenu(NULL),
2333616859aSStefano Ceccherini 	fMenuFrame(NULL),
2343616859aSStefano Ceccherini 	fUpperScroller(NULL),
2353616859aSStefano Ceccherini 	fLowerScroller(NULL)
236446b8c19SStefano Ceccherini {
237446b8c19SStefano Ceccherini }
238446b8c19SStefano Ceccherini 
239446b8c19SStefano Ceccherini 
240446b8c19SStefano Ceccherini BMenuWindow::~BMenuWindow()
241446b8c19SStefano Ceccherini {
242059ca4bdSStefano Ceccherini 	DetachMenu();
243446b8c19SStefano Ceccherini }
2445aa032f1SStefano Ceccherini 
2455aa032f1SStefano Ceccherini 
24661ba5a32SStefano Ceccherini void
247*9e64a7edSStefano Ceccherini BMenuWindow::DispatchMessage(BMessage *message, BHandler *handler)
248*9e64a7edSStefano Ceccherini {
249*9e64a7edSStefano Ceccherini 	BWindow::DispatchMessage(message, handler);
250*9e64a7edSStefano Ceccherini }
251*9e64a7edSStefano Ceccherini 
252*9e64a7edSStefano Ceccherini 
253*9e64a7edSStefano Ceccherini void
2544185bd8bSStefano Ceccherini BMenuWindow::AttachMenu(BMenu *menu)
2554185bd8bSStefano Ceccherini {
25627cc2508SStefano Ceccherini 	if (fMenuFrame)
25727cc2508SStefano Ceccherini 		debugger("BMenuWindow: a menu is already attached!");
2584185bd8bSStefano Ceccherini 	if (menu != NULL) {
25927cc2508SStefano Ceccherini 		fMenuFrame = new BMenuFrame(menu);
26027cc2508SStefano Ceccherini 		AddChild(fMenuFrame);
26107dc2c69SAxel Dörfler 		menu->MakeFocus(true);
2623616859aSStefano Ceccherini 		fMenu = menu;
2634185bd8bSStefano Ceccherini 	}
2644185bd8bSStefano Ceccherini }
2654185bd8bSStefano Ceccherini 
2664185bd8bSStefano Ceccherini 
2674185bd8bSStefano Ceccherini void
2684185bd8bSStefano Ceccherini BMenuWindow::DetachMenu()
26961ba5a32SStefano Ceccherini {
27027cc2508SStefano Ceccherini 	DetachScrollers();
2713616859aSStefano Ceccherini 	if (fMenuFrame) {
27227cc2508SStefano Ceccherini 		RemoveChild(fMenuFrame);
27327cc2508SStefano Ceccherini 		delete fMenuFrame;
27427cc2508SStefano Ceccherini 		fMenuFrame = NULL;
2753616859aSStefano Ceccherini 		fMenu = NULL;
27627cc2508SStefano Ceccherini 	}
27727cc2508SStefano Ceccherini }
27827cc2508SStefano Ceccherini 
27927cc2508SStefano Ceccherini 
28027cc2508SStefano Ceccherini void
28127cc2508SStefano Ceccherini BMenuWindow::AttachScrollers()
28227cc2508SStefano Ceccherini {
28327cc2508SStefano Ceccherini 	// We want to attach a scroller only if there's a menu frame already
28427cc2508SStefano Ceccherini 	// existing.
2853616859aSStefano Ceccherini 	if (!fMenu || !fMenuFrame)
28627cc2508SStefano Ceccherini 		return;
28727cc2508SStefano Ceccherini 
288059ca4bdSStefano Ceccherini 	if (fUpperScroller || fLowerScroller)
289059ca4bdSStefano Ceccherini 		debugger("Scrollers are already attached!");
290059ca4bdSStefano Ceccherini 
2913616859aSStefano Ceccherini 	fMenu->MakeFocus(true);
29227cc2508SStefano Ceccherini 
2933616859aSStefano Ceccherini 	BRect frame = Bounds();
2943616859aSStefano Ceccherini 	fUpperScroller = new UpperScroller(BRect(0, 0, frame.right, kScrollerHeight));
2953616859aSStefano Ceccherini 	AddChild(fUpperScroller);
2963616859aSStefano Ceccherini 	fLowerScroller = new LowerScroller(BRect(0, frame.bottom - kScrollerHeight, frame.right, frame.bottom));
2973616859aSStefano Ceccherini 	AddChild(fLowerScroller);
2983616859aSStefano Ceccherini 
2993616859aSStefano Ceccherini 	fUpperScroller->SetEnabled(false);
3003616859aSStefano Ceccherini 	fLowerScroller->SetEnabled(true);
30127cc2508SStefano Ceccherini 
302cf5948aeSStefano Ceccherini 	fMenuFrame->ResizeBy(0, -2 * kScrollerHeight - 1);
30327cc2508SStefano Ceccherini 	fMenuFrame->MoveBy(0, kScrollerHeight);
3043616859aSStefano Ceccherini 
3053616859aSStefano Ceccherini 	fValue = 0;
3063616859aSStefano Ceccherini 	fLimit = fMenu->Bounds().Height() - (frame.Height() - 2 * kScrollerHeight);
30727cc2508SStefano Ceccherini }
30827cc2508SStefano Ceccherini 
30927cc2508SStefano Ceccherini 
31027cc2508SStefano Ceccherini void
31127cc2508SStefano Ceccherini BMenuWindow::DetachScrollers()
31227cc2508SStefano Ceccherini {
31327cc2508SStefano Ceccherini 	// BeOS doesn't remember the position where the last scrolling ended,
31427cc2508SStefano Ceccherini 	// so we just scroll back to the beginning.
315059ca4bdSStefano Ceccherini 	if (fMenu)
3163616859aSStefano Ceccherini 		fMenu->ScrollTo(0, 0);
31727cc2508SStefano Ceccherini 
3183616859aSStefano Ceccherini 	if (fLowerScroller) {
3193616859aSStefano Ceccherini 		RemoveChild(fLowerScroller);
3203616859aSStefano Ceccherini 		delete fLowerScroller;
3213616859aSStefano Ceccherini 		fLowerScroller = NULL;
3223616859aSStefano Ceccherini 	}
32327cc2508SStefano Ceccherini 
3243616859aSStefano Ceccherini 	if (fUpperScroller) {
3253616859aSStefano Ceccherini 		RemoveChild(fUpperScroller);
3263616859aSStefano Ceccherini 		delete fUpperScroller;
3273616859aSStefano Ceccherini 		fUpperScroller = NULL;
3283616859aSStefano Ceccherini 	}
32961ba5a32SStefano Ceccherini }
330c7338938SStefano Ceccherini 
331c7338938SStefano Ceccherini 
332c7338938SStefano Ceccherini bool
333c7338938SStefano Ceccherini BMenuWindow::CheckForScrolling(BPoint cursor)
334c7338938SStefano Ceccherini {
335059ca4bdSStefano Ceccherini 	if (!fMenuFrame || !fUpperScroller || !fLowerScroller)
336c7338938SStefano Ceccherini 		return false;
337c7338938SStefano Ceccherini 
3383616859aSStefano Ceccherini 	return _Scroll(cursor);
3393616859aSStefano Ceccherini }
3403616859aSStefano Ceccherini 
3413616859aSStefano Ceccherini 
3423616859aSStefano Ceccherini bool
3433616859aSStefano Ceccherini BMenuWindow::_Scroll(BPoint cursor)
3443616859aSStefano Ceccherini {
345059ca4bdSStefano Ceccherini 	ASSERT((fLowerScroller != NULL));
346059ca4bdSStefano Ceccherini 	ASSERT((fUpperScroller != NULL));
347059ca4bdSStefano Ceccherini 
3483616859aSStefano Ceccherini 	ConvertFromScreen(&cursor);
3493616859aSStefano Ceccherini 
350059ca4bdSStefano Ceccherini 	BRect lowerFrame = fLowerScroller->Frame();
351059ca4bdSStefano Ceccherini 	BRect upperFrame = fUpperScroller->Frame();
3523616859aSStefano Ceccherini 
353059ca4bdSStefano Ceccherini 	if (fLowerScroller->IsEnabled() && lowerFrame.Contains(cursor)) {
3543616859aSStefano Ceccherini 		if (fValue == 0) {
3553616859aSStefano Ceccherini 			fUpperScroller->SetEnabled(true);
3563616859aSStefano Ceccherini 			fUpperScroller->Invalidate();
3573616859aSStefano Ceccherini 		}
3583616859aSStefano Ceccherini 
3593616859aSStefano Ceccherini 		if (fValue + kScrollStep >= fLimit) {
3603616859aSStefano Ceccherini 			// If we reached the limit, we don't want to scroll a whole
3613616859aSStefano Ceccherini 			// 'step' if not needed.
3623616859aSStefano Ceccherini 			fMenu->ScrollBy(0, fLimit - fValue);
3633616859aSStefano Ceccherini 			fValue = fLimit;
3643616859aSStefano Ceccherini 			fLowerScroller->SetEnabled(false);
3653616859aSStefano Ceccherini 			fLowerScroller->Invalidate();
3663616859aSStefano Ceccherini 
3673616859aSStefano Ceccherini 		} else {
3683616859aSStefano Ceccherini 			fMenu->ScrollBy(0, kScrollStep);
3693616859aSStefano Ceccherini 			fValue += kScrollStep;
3703616859aSStefano Ceccherini 		}
371059ca4bdSStefano Ceccherini 	} else if (fUpperScroller->IsEnabled() && upperFrame.Contains(cursor)) {
3723616859aSStefano Ceccherini 		if (fValue == fLimit) {
3733616859aSStefano Ceccherini 			fLowerScroller->SetEnabled(true);
3743616859aSStefano Ceccherini 			fLowerScroller->Invalidate();
3753616859aSStefano Ceccherini 		}
3763616859aSStefano Ceccherini 
3773616859aSStefano Ceccherini 		if (fValue - kScrollStep <= 0) {
3783616859aSStefano Ceccherini 			fMenu->ScrollBy(0, -fValue);
3793616859aSStefano Ceccherini 			fValue = 0;
3803616859aSStefano Ceccherini 			fUpperScroller->SetEnabled(false);
3813616859aSStefano Ceccherini 			fUpperScroller->Invalidate();
3823616859aSStefano Ceccherini 
3833616859aSStefano Ceccherini 		} else {
3843616859aSStefano Ceccherini 			fMenu->ScrollBy(0, -kScrollStep);
3853616859aSStefano Ceccherini 			fValue -= kScrollStep;
3863616859aSStefano Ceccherini 		}
387059ca4bdSStefano Ceccherini 	} else
3883616859aSStefano Ceccherini 		return false;
3893616859aSStefano Ceccherini 
3903616859aSStefano Ceccherini 	snooze(10000);
3913616859aSStefano Ceccherini 
3923616859aSStefano Ceccherini 	return true;
393c7338938SStefano Ceccherini }
394c7338938SStefano Ceccherini 
395