xref: /haiku/src/kits/interface/MenuWindow.cpp (revision cf5948ae6c7ae4898eb2c9048a29a02ecad69c98)
1c7023acdSAxel Dörfler /*
2c7023acdSAxel Dörfler  * Copyright 2001-2006, 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)
7c7023acdSAxel Dörfler  *		Stefano Ceccherini (burton666@libero.it)
8c7023acdSAxel Dörfler  */
9c7023acdSAxel Dörfler 
10c7023acdSAxel Dörfler //!	BMenuWindow is a custom BWindow for BMenus.
11c7023acdSAxel Dörfler 
12446b8c19SStefano Ceccherini #include <Menu.h>
13446b8c19SStefano Ceccherini 
142c11ec31SStefano Ceccherini #include <MenuPrivate.h>
152c11ec31SStefano Ceccherini #include <MenuWindow.h>
16c7023acdSAxel Dörfler #include <WindowPrivate.h>
17c7023acdSAxel Dörfler 
18e411c658SStefano Ceccherini 
192628e60cSAxel Dörfler namespace BPrivate {
202628e60cSAxel Dörfler 
212628e60cSAxel Dörfler class BMenuScroller : public BView {
222628e60cSAxel Dörfler 	public:
233616859aSStefano Ceccherini 		BMenuScroller(BRect frame);
242628e60cSAxel Dörfler 
253616859aSStefano Ceccherini 		bool IsEnabled() const;
263616859aSStefano Ceccherini 		void SetEnabled(const bool &enabled);
272628e60cSAxel Dörfler 	private:
283616859aSStefano Ceccherini 		bool fEnabled;
292628e60cSAxel Dörfler };
302628e60cSAxel Dörfler 
313616859aSStefano Ceccherini 
322628e60cSAxel Dörfler class BMenuFrame : public BView {
332628e60cSAxel Dörfler 	public:
342628e60cSAxel Dörfler 		BMenuFrame(BMenu *menu);
352628e60cSAxel Dörfler 
362628e60cSAxel Dörfler 		virtual void AttachedToWindow();
372628e60cSAxel Dörfler 		virtual void DetachedFromWindow();
382628e60cSAxel Dörfler 		virtual void Draw(BRect updateRect);
392628e60cSAxel Dörfler 
402628e60cSAxel Dörfler 	private:
412628e60cSAxel Dörfler 		friend class BMenuWindow;
422628e60cSAxel Dörfler 
432628e60cSAxel Dörfler 		BMenu *fMenu;
442628e60cSAxel Dörfler };
452628e60cSAxel Dörfler 
463616859aSStefano Ceccherini 
473616859aSStefano Ceccherini class UpperScroller : public BMenuScroller {
483616859aSStefano Ceccherini public:
493616859aSStefano Ceccherini 	UpperScroller(BRect frame);
503616859aSStefano Ceccherini 	virtual void Draw(BRect updateRect);
513616859aSStefano Ceccherini };
523616859aSStefano Ceccherini 
533616859aSStefano Ceccherini class LowerScroller : public BMenuScroller {
543616859aSStefano Ceccherini public:
553616859aSStefano Ceccherini 	LowerScroller(BRect frame);
563616859aSStefano Ceccherini 	virtual void Draw(BRect updateRect);
573616859aSStefano Ceccherini };
583616859aSStefano Ceccherini 
592628e60cSAxel Dörfler }	// namespace BPrivate
602628e60cSAxel Dörfler 
613616859aSStefano Ceccherini 
622628e60cSAxel Dörfler using namespace BPrivate;
632628e60cSAxel Dörfler 
642628e60cSAxel Dörfler 
6527cc2508SStefano Ceccherini const int kScrollerHeight = 10;
66c7338938SStefano Ceccherini const int kScrollStep = 19;
675b752875SStefano Ceccherini 
682628e60cSAxel Dörfler 
693616859aSStefano Ceccherini BMenuScroller::BMenuScroller(BRect frame)
70c7338938SStefano Ceccherini 	: BView(frame, "menu scroller", 0, B_WILL_DRAW | B_FRAME_EVENTS),
713616859aSStefano Ceccherini 	fEnabled(false)
7227cc2508SStefano Ceccherini {
7327cc2508SStefano Ceccherini 	SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR));
7427cc2508SStefano Ceccherini }
7527cc2508SStefano Ceccherini 
7627cc2508SStefano Ceccherini 
77c7338938SStefano Ceccherini bool
783616859aSStefano Ceccherini BMenuScroller::IsEnabled() const
7927cc2508SStefano Ceccherini {
803616859aSStefano Ceccherini 	return fEnabled;
8127cc2508SStefano Ceccherini }
8227cc2508SStefano Ceccherini 
8327cc2508SStefano Ceccherini 
8427cc2508SStefano Ceccherini void
853616859aSStefano Ceccherini BMenuScroller::SetEnabled(const bool &enabled)
863616859aSStefano Ceccherini {
873616859aSStefano Ceccherini 	fEnabled = enabled;
883616859aSStefano Ceccherini }
893616859aSStefano Ceccherini 
903616859aSStefano Ceccherini 
913616859aSStefano Ceccherini //	#pragma mark -
923616859aSStefano Ceccherini 
933616859aSStefano Ceccherini 
943616859aSStefano Ceccherini UpperScroller::UpperScroller(BRect frame)
953616859aSStefano Ceccherini 	:
963616859aSStefano Ceccherini 	BMenuScroller(frame)
973616859aSStefano Ceccherini {
983616859aSStefano Ceccherini }
993616859aSStefano Ceccherini 
1003616859aSStefano Ceccherini 
1013616859aSStefano Ceccherini void
1023616859aSStefano Ceccherini UpperScroller::Draw(BRect updateRect)
10327cc2508SStefano Ceccherini {
10427cc2508SStefano Ceccherini 	SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT));
10527cc2508SStefano Ceccherini 	float middle = Bounds().right / 2;
10627cc2508SStefano Ceccherini 
10727cc2508SStefano Ceccherini 	// Draw the upper arrow.
1083616859aSStefano Ceccherini 	if (IsEnabled())
10927cc2508SStefano Ceccherini 		SetHighColor(0, 0, 0);
11027cc2508SStefano Ceccherini 	else
11127cc2508SStefano Ceccherini 		SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
11227cc2508SStefano Ceccherini 					B_DARKEN_2_TINT));
11327cc2508SStefano Ceccherini 
1143616859aSStefano Ceccherini 	FillRect(Bounds(), B_SOLID_LOW);
11527cc2508SStefano Ceccherini 
11627cc2508SStefano Ceccherini 	FillTriangle(BPoint(middle, (kScrollerHeight / 2) - 3),
11727cc2508SStefano Ceccherini 			BPoint(middle + 5, (kScrollerHeight / 2) + 2),
11827cc2508SStefano Ceccherini 			BPoint(middle - 5, (kScrollerHeight / 2) + 2));
11927cc2508SStefano Ceccherini }
12027cc2508SStefano Ceccherini 
1213616859aSStefano Ceccherini 
1223616859aSStefano Ceccherini //	#pragma mark -
1233616859aSStefano Ceccherini 
1243616859aSStefano Ceccherini 
1253616859aSStefano Ceccherini LowerScroller::LowerScroller(BRect frame)
1263616859aSStefano Ceccherini 	:
1273616859aSStefano Ceccherini 	BMenuScroller(frame)
1283616859aSStefano Ceccherini {
1293616859aSStefano Ceccherini }
1303616859aSStefano Ceccherini 
1313616859aSStefano Ceccherini 
1323616859aSStefano Ceccherini void
1333616859aSStefano Ceccherini LowerScroller::Draw(BRect updateRect)
1343616859aSStefano Ceccherini {
1353616859aSStefano Ceccherini 	SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT));
1363616859aSStefano Ceccherini 
1373616859aSStefano Ceccherini 	BRect frame = Bounds();
13827cc2508SStefano Ceccherini 	// Draw the lower arrow.
1393616859aSStefano Ceccherini 	if (IsEnabled())
14027cc2508SStefano Ceccherini 		SetHighColor(0, 0, 0);
14127cc2508SStefano Ceccherini 	else
14227cc2508SStefano Ceccherini 		SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
14327cc2508SStefano Ceccherini 			B_DARKEN_2_TINT));
14427cc2508SStefano Ceccherini 
1453616859aSStefano Ceccherini 	FillRect(Bounds(), B_SOLID_LOW);
14627cc2508SStefano Ceccherini 
1473616859aSStefano Ceccherini 	float middle = Bounds().right / 2;
1483616859aSStefano Ceccherini 
1493616859aSStefano Ceccherini 	FillTriangle(BPoint(middle, frame.bottom - (kScrollerHeight / 2) + 3),
1503616859aSStefano Ceccherini 			BPoint(middle + 5, frame.bottom - (kScrollerHeight / 2) - 2),
1513616859aSStefano Ceccherini 			BPoint(middle - 5, frame.bottom - (kScrollerHeight / 2) - 2));
15227cc2508SStefano Ceccherini }
15327cc2508SStefano Ceccherini 
15427cc2508SStefano Ceccherini 
15527cc2508SStefano Ceccherini //	#pragma mark -
1565b752875SStefano Ceccherini 
1575b752875SStefano Ceccherini 
1582628e60cSAxel Dörfler BMenuFrame::BMenuFrame(BMenu *menu)
1592628e60cSAxel Dörfler 	: BView(BRect(0, 0, 1, 1), "menu frame", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
1602628e60cSAxel Dörfler 	fMenu(menu)
1612628e60cSAxel Dörfler {
1622628e60cSAxel Dörfler }
1632628e60cSAxel Dörfler 
1642628e60cSAxel Dörfler 
1652628e60cSAxel Dörfler void
1662628e60cSAxel Dörfler BMenuFrame::AttachedToWindow()
1672628e60cSAxel Dörfler {
1682628e60cSAxel Dörfler 	BView::AttachedToWindow();
1692628e60cSAxel Dörfler 
1702628e60cSAxel Dörfler 	if (fMenu != NULL)
1712628e60cSAxel Dörfler 		AddChild(fMenu);
1722628e60cSAxel Dörfler 
1732628e60cSAxel Dörfler 	ResizeTo(Window()->Bounds().Width(), Window()->Bounds().Height());
1742628e60cSAxel Dörfler 	if (fMenu != NULL) {
1752628e60cSAxel Dörfler 		BFont font;
1762628e60cSAxel Dörfler 		fMenu->GetFont(&font);
1772628e60cSAxel Dörfler 		SetFont(&font);
1782628e60cSAxel Dörfler 	}
1792628e60cSAxel Dörfler }
1802628e60cSAxel Dörfler 
1812628e60cSAxel Dörfler 
1822628e60cSAxel Dörfler void
1832628e60cSAxel Dörfler BMenuFrame::DetachedFromWindow()
1842628e60cSAxel Dörfler {
1852628e60cSAxel Dörfler 	if (fMenu != NULL)
1862628e60cSAxel Dörfler 		RemoveChild(fMenu);
1872628e60cSAxel Dörfler }
1882628e60cSAxel Dörfler 
1892628e60cSAxel Dörfler 
1902628e60cSAxel Dörfler void
1912628e60cSAxel Dörfler BMenuFrame::Draw(BRect updateRect)
1922628e60cSAxel Dörfler {
1932628e60cSAxel Dörfler 	if (fMenu != NULL && fMenu->CountItems() == 0) {
1942628e60cSAxel Dörfler 		// TODO: Review this as it's a bit hacky.
1952628e60cSAxel Dörfler 		// Menu has a size of 0, 0, since there are no items in it.
1962628e60cSAxel Dörfler 		// So the BMenuFrame class has to fake it and draw an empty item.
1972628e60cSAxel Dörfler 		// Note that we can't add a real "empty" item because then we couldn't
1982628e60cSAxel Dörfler 		// tell if the item was added by us or not.
1992628e60cSAxel Dörfler 		// See also BMenu::UpdateWindowViewSize()
2002628e60cSAxel Dörfler 		SetHighColor(ui_color(B_MENU_BACKGROUND_COLOR));
2012628e60cSAxel Dörfler 		SetLowColor(HighColor());
2022628e60cSAxel Dörfler 		FillRect(updateRect);
2032628e60cSAxel Dörfler 
2042628e60cSAxel Dörfler 		font_height height;
2052628e60cSAxel Dörfler 		GetFontHeight(&height);
2062628e60cSAxel Dörfler 		SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT));
2072628e60cSAxel Dörfler 		BPoint where((Bounds().Width() - fMenu->StringWidth(kEmptyMenuLabel)) / 2, ceilf(height.ascent + 1));
2082628e60cSAxel Dörfler 		DrawString(kEmptyMenuLabel, where);
2092628e60cSAxel Dörfler 	}
2102628e60cSAxel Dörfler 
2112628e60cSAxel Dörfler 	SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT));
2122628e60cSAxel Dörfler 	BRect bounds(Bounds());
2132628e60cSAxel Dörfler 
2142628e60cSAxel Dörfler 	StrokeLine(BPoint(bounds.right, bounds.top),
2152628e60cSAxel Dörfler 		BPoint(bounds.right, bounds.bottom - 1));
2162628e60cSAxel Dörfler 	StrokeLine(BPoint(bounds.left + 1, bounds.bottom),
2172628e60cSAxel Dörfler 		BPoint(bounds.right, bounds.bottom));
2182628e60cSAxel Dörfler }
2192628e60cSAxel Dörfler 
2202628e60cSAxel Dörfler 
2213616859aSStefano Ceccherini 
2222628e60cSAxel Dörfler //	#pragma mark -
2232628e60cSAxel Dörfler 
2242628e60cSAxel Dörfler 
2254185bd8bSStefano Ceccherini BMenuWindow::BMenuWindow(const char *name)
2261664b981SStefano Ceccherini 	// The window will be resized by BMenu, so just pass a dummy rect
227c7023acdSAxel Dörfler 	: BWindow(BRect(0, 0, 0, 0), name, B_BORDERED_WINDOW_LOOK, kMenuWindowFeel,
228c7023acdSAxel Dörfler 			B_NOT_ZOOMABLE | B_AVOID_FOCUS),
2293616859aSStefano Ceccherini 	fMenu(NULL),
2303616859aSStefano Ceccherini 	fMenuFrame(NULL),
2313616859aSStefano Ceccherini 	fUpperScroller(NULL),
2323616859aSStefano Ceccherini 	fLowerScroller(NULL)
233446b8c19SStefano Ceccherini {
234446b8c19SStefano Ceccherini }
235446b8c19SStefano Ceccherini 
236446b8c19SStefano Ceccherini 
237446b8c19SStefano Ceccherini BMenuWindow::~BMenuWindow()
238446b8c19SStefano Ceccherini {
239446b8c19SStefano Ceccherini }
2405aa032f1SStefano Ceccherini 
2415aa032f1SStefano Ceccherini 
24261ba5a32SStefano Ceccherini void
2434185bd8bSStefano Ceccherini BMenuWindow::AttachMenu(BMenu *menu)
2444185bd8bSStefano Ceccherini {
24527cc2508SStefano Ceccherini 	if (fMenuFrame)
24627cc2508SStefano Ceccherini 		debugger("BMenuWindow: a menu is already attached!");
2474185bd8bSStefano Ceccherini 	if (menu != NULL) {
24827cc2508SStefano Ceccherini 		fMenuFrame = new BMenuFrame(menu);
24927cc2508SStefano Ceccherini 		AddChild(fMenuFrame);
25007dc2c69SAxel Dörfler 		menu->MakeFocus(true);
2513616859aSStefano Ceccherini 		fMenu = menu;
2524185bd8bSStefano Ceccherini 	}
2534185bd8bSStefano Ceccherini }
2544185bd8bSStefano Ceccherini 
2554185bd8bSStefano Ceccherini 
2564185bd8bSStefano Ceccherini void
2574185bd8bSStefano Ceccherini BMenuWindow::DetachMenu()
25861ba5a32SStefano Ceccherini {
25927cc2508SStefano Ceccherini 	DetachScrollers();
2603616859aSStefano Ceccherini 	if (fMenuFrame) {
26127cc2508SStefano Ceccherini 		RemoveChild(fMenuFrame);
26227cc2508SStefano Ceccherini 		delete fMenuFrame;
26327cc2508SStefano Ceccherini 		fMenuFrame = NULL;
2643616859aSStefano Ceccherini 		fMenu = NULL;
26527cc2508SStefano Ceccherini 	}
26627cc2508SStefano Ceccherini }
26727cc2508SStefano Ceccherini 
26827cc2508SStefano Ceccherini 
26927cc2508SStefano Ceccherini void
27027cc2508SStefano Ceccherini BMenuWindow::AttachScrollers()
27127cc2508SStefano Ceccherini {
27227cc2508SStefano Ceccherini 	// We want to attach a scroller only if there's a menu frame already
27327cc2508SStefano Ceccherini 	// existing.
2743616859aSStefano Ceccherini 	if (!fMenu || !fMenuFrame)
27527cc2508SStefano Ceccherini 		return;
27627cc2508SStefano Ceccherini 
2773616859aSStefano Ceccherini 	fMenu->MakeFocus(true);
27827cc2508SStefano Ceccherini 
2793616859aSStefano Ceccherini 	BRect frame = Bounds();
2803616859aSStefano Ceccherini 	fUpperScroller = new UpperScroller(BRect(0, 0, frame.right, kScrollerHeight));
2813616859aSStefano Ceccherini 	AddChild(fUpperScroller);
2823616859aSStefano Ceccherini 	fLowerScroller = new LowerScroller(BRect(0, frame.bottom - kScrollerHeight, frame.right, frame.bottom));
2833616859aSStefano Ceccherini 	AddChild(fLowerScroller);
2843616859aSStefano Ceccherini 
2853616859aSStefano Ceccherini 	fUpperScroller->SetEnabled(false);
2863616859aSStefano Ceccherini 	fLowerScroller->SetEnabled(true);
28727cc2508SStefano Ceccherini 
288*cf5948aeSStefano Ceccherini 	fMenuFrame->ResizeBy(0, -2 * kScrollerHeight - 1);
28927cc2508SStefano Ceccherini 	fMenuFrame->MoveBy(0, kScrollerHeight);
2903616859aSStefano Ceccherini 
2913616859aSStefano Ceccherini 	fValue = 0;
2923616859aSStefano Ceccherini 	fLimit = fMenu->Bounds().Height() - (frame.Height() - 2 * kScrollerHeight);
29327cc2508SStefano Ceccherini }
29427cc2508SStefano Ceccherini 
29527cc2508SStefano Ceccherini 
29627cc2508SStefano Ceccherini void
29727cc2508SStefano Ceccherini BMenuWindow::DetachScrollers()
29827cc2508SStefano Ceccherini {
29927cc2508SStefano Ceccherini 	// BeOS doesn't remember the position where the last scrolling ended,
30027cc2508SStefano Ceccherini 	// so we just scroll back to the beginning.
3013616859aSStefano Ceccherini 	fMenu->ScrollTo(0, 0);
30227cc2508SStefano Ceccherini 
3033616859aSStefano Ceccherini 	if (fLowerScroller) {
3043616859aSStefano Ceccherini 		RemoveChild(fLowerScroller);
3053616859aSStefano Ceccherini 		delete fLowerScroller;
3063616859aSStefano Ceccherini 		fLowerScroller = NULL;
3073616859aSStefano Ceccherini 	}
30827cc2508SStefano Ceccherini 
3093616859aSStefano Ceccherini 	if (fUpperScroller) {
3103616859aSStefano Ceccherini 		RemoveChild(fUpperScroller);
3113616859aSStefano Ceccherini 		delete fUpperScroller;
3123616859aSStefano Ceccherini 		fUpperScroller = NULL;
3133616859aSStefano Ceccherini 	}
31461ba5a32SStefano Ceccherini }
315c7338938SStefano Ceccherini 
316c7338938SStefano Ceccherini 
317c7338938SStefano Ceccherini bool
318c7338938SStefano Ceccherini BMenuWindow::CheckForScrolling(BPoint cursor)
319c7338938SStefano Ceccherini {
3203616859aSStefano Ceccherini 	if (!fMenuFrame)
321c7338938SStefano Ceccherini 		return false;
322c7338938SStefano Ceccherini 
3233616859aSStefano Ceccherini 	return _Scroll(cursor);
3243616859aSStefano Ceccherini }
3253616859aSStefano Ceccherini 
3263616859aSStefano Ceccherini 
3273616859aSStefano Ceccherini bool
3283616859aSStefano Ceccherini BMenuWindow::_Scroll(BPoint cursor)
3293616859aSStefano Ceccherini {
3303616859aSStefano Ceccherini 	ConvertFromScreen(&cursor);
3313616859aSStefano Ceccherini 
3323616859aSStefano Ceccherini 	BRect lowerFrame;
3333616859aSStefano Ceccherini 	BRect upperFrame;
3343616859aSStefano Ceccherini 	if (fLowerScroller)
3353616859aSStefano Ceccherini 		lowerFrame = fLowerScroller->Frame();
3363616859aSStefano Ceccherini 	if (fUpperScroller)
3373616859aSStefano Ceccherini 		upperFrame = fUpperScroller->Frame();
3383616859aSStefano Ceccherini 
3393616859aSStefano Ceccherini 	if (fLowerScroller && fLowerScroller->IsEnabled() && lowerFrame.Contains(cursor)) {
3403616859aSStefano Ceccherini 		if (fValue == 0) {
3413616859aSStefano Ceccherini 			fUpperScroller->SetEnabled(true);
3423616859aSStefano Ceccherini 			fUpperScroller->Invalidate();
3433616859aSStefano Ceccherini 		}
3443616859aSStefano Ceccherini 
3453616859aSStefano Ceccherini 		if (fValue + kScrollStep >= fLimit) {
3463616859aSStefano Ceccherini 			// If we reached the limit, we don't want to scroll a whole
3473616859aSStefano Ceccherini 			// 'step' if not needed.
3483616859aSStefano Ceccherini 			fMenu->ScrollBy(0, fLimit - fValue);
3493616859aSStefano Ceccherini 			fValue = fLimit;
3503616859aSStefano Ceccherini 			fLowerScroller->SetEnabled(false);
3513616859aSStefano Ceccherini 			fLowerScroller->Invalidate();
3523616859aSStefano Ceccherini 
3533616859aSStefano Ceccherini 		} else {
3543616859aSStefano Ceccherini 			fMenu->ScrollBy(0, kScrollStep);
3553616859aSStefano Ceccherini 			fValue += kScrollStep;
3563616859aSStefano Ceccherini 		}
3573616859aSStefano Ceccherini 	} else if (fUpperScroller && fUpperScroller->IsEnabled() && upperFrame.Contains(cursor)) {
3583616859aSStefano Ceccherini 		if (fValue == fLimit) {
3593616859aSStefano Ceccherini 			fLowerScroller->SetEnabled(true);
3603616859aSStefano Ceccherini 			fLowerScroller->Invalidate();
3613616859aSStefano Ceccherini 		}
3623616859aSStefano Ceccherini 
3633616859aSStefano Ceccherini 		if (fValue - kScrollStep <= 0) {
3643616859aSStefano Ceccherini 			fMenu->ScrollBy(0, -fValue);
3653616859aSStefano Ceccherini 			fValue = 0;
3663616859aSStefano Ceccherini 			fUpperScroller->SetEnabled(false);
3673616859aSStefano Ceccherini 			fUpperScroller->Invalidate();
3683616859aSStefano Ceccherini 
3693616859aSStefano Ceccherini 		} else {
3703616859aSStefano Ceccherini 			fMenu->ScrollBy(0, -kScrollStep);
3713616859aSStefano Ceccherini 			fValue -= kScrollStep;
3723616859aSStefano Ceccherini 		}
3733616859aSStefano Ceccherini 	} else {
3743616859aSStefano Ceccherini 		return false;
3753616859aSStefano Ceccherini 	}
3763616859aSStefano Ceccherini 
3773616859aSStefano Ceccherini 	snooze(10000);
3783616859aSStefano Ceccherini 
3793616859aSStefano Ceccherini 	return true;
380c7338938SStefano Ceccherini }
381c7338938SStefano Ceccherini 
382