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 122f86ba45SStephan Aßmus #include <MenuWindow.h> 132f86ba45SStephan Aßmus 142f86ba45SStephan Aßmus #include <ControlLook.h> 15059ca4bdSStefano Ceccherini #include <Debug.h> 16446b8c19SStefano Ceccherini #include <Menu.h> 172c11ec31SStefano Ceccherini #include <MenuPrivate.h> 18c7023acdSAxel Dörfler #include <WindowPrivate.h> 19c7023acdSAxel Dörfler 20e411c658SStefano Ceccherini 212628e60cSAxel Dörfler namespace BPrivate { 222628e60cSAxel Dörfler 232628e60cSAxel Dörfler class BMenuScroller : public BView { 242628e60cSAxel Dörfler public: 253616859aSStefano Ceccherini BMenuScroller(BRect frame); 262628e60cSAxel Dörfler 273616859aSStefano Ceccherini bool IsEnabled() const; 283616859aSStefano Ceccherini void SetEnabled(const bool &enabled); 292628e60cSAxel Dörfler private: 303616859aSStefano Ceccherini bool fEnabled; 312628e60cSAxel Dörfler }; 322628e60cSAxel Dörfler 333616859aSStefano Ceccherini 342628e60cSAxel Dörfler class BMenuFrame : public BView { 352628e60cSAxel Dörfler public: 362628e60cSAxel Dörfler BMenuFrame(BMenu *menu); 372628e60cSAxel Dörfler 382628e60cSAxel Dörfler virtual void AttachedToWindow(); 392628e60cSAxel Dörfler virtual void DetachedFromWindow(); 402628e60cSAxel Dörfler virtual void Draw(BRect updateRect); 412628e60cSAxel Dörfler 422628e60cSAxel Dörfler private: 432628e60cSAxel Dörfler friend class BMenuWindow; 442628e60cSAxel Dörfler 452628e60cSAxel Dörfler BMenu *fMenu; 462628e60cSAxel Dörfler }; 472628e60cSAxel Dörfler 483616859aSStefano Ceccherini 493616859aSStefano Ceccherini class UpperScroller : public BMenuScroller { 503616859aSStefano Ceccherini public: 513616859aSStefano Ceccherini UpperScroller(BRect frame); 523616859aSStefano Ceccherini virtual void Draw(BRect updateRect); 533616859aSStefano Ceccherini }; 543616859aSStefano Ceccherini 55059ca4bdSStefano Ceccherini 563616859aSStefano Ceccherini class LowerScroller : public BMenuScroller { 573616859aSStefano Ceccherini public: 583616859aSStefano Ceccherini LowerScroller(BRect frame); 593616859aSStefano Ceccherini virtual void Draw(BRect updateRect); 603616859aSStefano Ceccherini }; 613616859aSStefano Ceccherini 62059ca4bdSStefano Ceccherini 632628e60cSAxel Dörfler } // namespace BPrivate 642628e60cSAxel Dörfler 653616859aSStefano Ceccherini 662628e60cSAxel Dörfler using namespace BPrivate; 672628e60cSAxel Dörfler 682628e60cSAxel Dörfler 6927cc2508SStefano Ceccherini const int kScrollerHeight = 10; 70c7338938SStefano Ceccherini const int kScrollStep = 19; 715b752875SStefano Ceccherini 722628e60cSAxel Dörfler 733616859aSStefano Ceccherini BMenuScroller::BMenuScroller(BRect frame) 74c7338938SStefano Ceccherini : BView(frame, "menu scroller", 0, B_WILL_DRAW | B_FRAME_EVENTS), 753616859aSStefano Ceccherini fEnabled(false) 7627cc2508SStefano Ceccherini { 7727cc2508SStefano Ceccherini SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); 7827cc2508SStefano Ceccherini } 7927cc2508SStefano Ceccherini 8027cc2508SStefano Ceccherini 81c7338938SStefano Ceccherini bool 823616859aSStefano Ceccherini BMenuScroller::IsEnabled() const 8327cc2508SStefano Ceccherini { 843616859aSStefano Ceccherini return fEnabled; 8527cc2508SStefano Ceccherini } 8627cc2508SStefano Ceccherini 8727cc2508SStefano Ceccherini 8827cc2508SStefano Ceccherini void 893616859aSStefano Ceccherini BMenuScroller::SetEnabled(const bool &enabled) 903616859aSStefano Ceccherini { 913616859aSStefano Ceccherini fEnabled = enabled; 923616859aSStefano Ceccherini } 933616859aSStefano Ceccherini 943616859aSStefano Ceccherini 953616859aSStefano Ceccherini // #pragma mark - 963616859aSStefano Ceccherini 973616859aSStefano Ceccherini 983616859aSStefano Ceccherini UpperScroller::UpperScroller(BRect frame) 993616859aSStefano Ceccherini : 1003616859aSStefano Ceccherini BMenuScroller(frame) 1013616859aSStefano Ceccherini { 1023616859aSStefano Ceccherini } 1033616859aSStefano Ceccherini 1043616859aSStefano Ceccherini 1053616859aSStefano Ceccherini void 1063616859aSStefano Ceccherini UpperScroller::Draw(BRect updateRect) 10727cc2508SStefano Ceccherini { 10827cc2508SStefano Ceccherini SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT)); 10927cc2508SStefano Ceccherini float middle = Bounds().right / 2; 11027cc2508SStefano Ceccherini 11127cc2508SStefano Ceccherini // Draw the upper arrow. 1123616859aSStefano Ceccherini if (IsEnabled()) 11327cc2508SStefano Ceccherini SetHighColor(0, 0, 0); 11427cc2508SStefano Ceccherini else 11527cc2508SStefano Ceccherini SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), 11627cc2508SStefano Ceccherini B_DARKEN_2_TINT)); 11727cc2508SStefano Ceccherini 1183616859aSStefano Ceccherini FillRect(Bounds(), B_SOLID_LOW); 11927cc2508SStefano Ceccherini 12027cc2508SStefano Ceccherini FillTriangle(BPoint(middle, (kScrollerHeight / 2) - 3), 12127cc2508SStefano Ceccherini BPoint(middle + 5, (kScrollerHeight / 2) + 2), 12227cc2508SStefano Ceccherini BPoint(middle - 5, (kScrollerHeight / 2) + 2)); 12327cc2508SStefano Ceccherini } 12427cc2508SStefano Ceccherini 1253616859aSStefano Ceccherini 1263616859aSStefano Ceccherini // #pragma mark - 1273616859aSStefano Ceccherini 1283616859aSStefano Ceccherini 1293616859aSStefano Ceccherini LowerScroller::LowerScroller(BRect frame) 1303616859aSStefano Ceccherini : 1313616859aSStefano Ceccherini BMenuScroller(frame) 1323616859aSStefano Ceccherini { 1333616859aSStefano Ceccherini } 1343616859aSStefano Ceccherini 1353616859aSStefano Ceccherini 1363616859aSStefano Ceccherini void 1373616859aSStefano Ceccherini LowerScroller::Draw(BRect updateRect) 1383616859aSStefano Ceccherini { 1393616859aSStefano Ceccherini SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT)); 1403616859aSStefano Ceccherini 1413616859aSStefano Ceccherini BRect frame = Bounds(); 14227cc2508SStefano Ceccherini // Draw the lower arrow. 1433616859aSStefano Ceccherini if (IsEnabled()) 14427cc2508SStefano Ceccherini SetHighColor(0, 0, 0); 14527cc2508SStefano Ceccherini else 14627cc2508SStefano Ceccherini SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), 14727cc2508SStefano Ceccherini B_DARKEN_2_TINT)); 14827cc2508SStefano Ceccherini 149059ca4bdSStefano Ceccherini FillRect(frame, B_SOLID_LOW); 15027cc2508SStefano Ceccherini 1513616859aSStefano Ceccherini float middle = Bounds().right / 2; 1523616859aSStefano Ceccherini 1533616859aSStefano Ceccherini FillTriangle(BPoint(middle, frame.bottom - (kScrollerHeight / 2) + 3), 1543616859aSStefano Ceccherini BPoint(middle + 5, frame.bottom - (kScrollerHeight / 2) - 2), 1553616859aSStefano Ceccherini BPoint(middle - 5, frame.bottom - (kScrollerHeight / 2) - 2)); 15627cc2508SStefano Ceccherini } 15727cc2508SStefano Ceccherini 15827cc2508SStefano Ceccherini 15927cc2508SStefano Ceccherini // #pragma mark - 1605b752875SStefano Ceccherini 1615b752875SStefano Ceccherini 1622628e60cSAxel Dörfler BMenuFrame::BMenuFrame(BMenu *menu) 1632628e60cSAxel Dörfler : BView(BRect(0, 0, 1, 1), "menu frame", B_FOLLOW_ALL_SIDES, B_WILL_DRAW), 1642628e60cSAxel Dörfler fMenu(menu) 1652628e60cSAxel Dörfler { 1662628e60cSAxel Dörfler } 1672628e60cSAxel Dörfler 1682628e60cSAxel Dörfler 1692628e60cSAxel Dörfler void 1702628e60cSAxel Dörfler BMenuFrame::AttachedToWindow() 1712628e60cSAxel Dörfler { 1722628e60cSAxel Dörfler BView::AttachedToWindow(); 1732628e60cSAxel Dörfler 1742628e60cSAxel Dörfler if (fMenu != NULL) 1752628e60cSAxel Dörfler AddChild(fMenu); 1762628e60cSAxel Dörfler 1772628e60cSAxel Dörfler ResizeTo(Window()->Bounds().Width(), Window()->Bounds().Height()); 1782628e60cSAxel Dörfler if (fMenu != NULL) { 1792628e60cSAxel Dörfler BFont font; 1802628e60cSAxel Dörfler fMenu->GetFont(&font); 1812628e60cSAxel Dörfler SetFont(&font); 1822628e60cSAxel Dörfler } 1832628e60cSAxel Dörfler } 1842628e60cSAxel Dörfler 1852628e60cSAxel Dörfler 1862628e60cSAxel Dörfler void 1872628e60cSAxel Dörfler BMenuFrame::DetachedFromWindow() 1882628e60cSAxel Dörfler { 1892628e60cSAxel Dörfler if (fMenu != NULL) 1902628e60cSAxel Dörfler RemoveChild(fMenu); 1912628e60cSAxel Dörfler } 1922628e60cSAxel Dörfler 1932628e60cSAxel Dörfler 1942628e60cSAxel Dörfler void 1952628e60cSAxel Dörfler BMenuFrame::Draw(BRect updateRect) 1962628e60cSAxel Dörfler { 1972628e60cSAxel Dörfler if (fMenu != NULL && fMenu->CountItems() == 0) { 1982f86ba45SStephan Aßmus if (be_control_look != NULL) { 1992f86ba45SStephan Aßmus BRect rect(Bounds()); 2002f86ba45SStephan Aßmus be_control_look->DrawMenuBackground(this, rect, updateRect, 2012f86ba45SStephan Aßmus ui_color(B_MENU_BACKGROUND_COLOR)); 2022f86ba45SStephan Aßmus SetDrawingMode(B_OP_OVER); 2032f86ba45SStephan Aßmus } else { 2042628e60cSAxel Dörfler // TODO: Review this as it's a bit hacky. 2052628e60cSAxel Dörfler // Menu has a size of 0, 0, since there are no items in it. 2062628e60cSAxel Dörfler // So the BMenuFrame class has to fake it and draw an empty item. 2072628e60cSAxel Dörfler // Note that we can't add a real "empty" item because then we couldn't 2082628e60cSAxel Dörfler // tell if the item was added by us or not. 2092628e60cSAxel Dörfler // See also BMenu::UpdateWindowViewSize() 2102628e60cSAxel Dörfler SetHighColor(ui_color(B_MENU_BACKGROUND_COLOR)); 2112628e60cSAxel Dörfler SetLowColor(HighColor()); 2122628e60cSAxel Dörfler FillRect(updateRect); 2132f86ba45SStephan Aßmus } 2142628e60cSAxel Dörfler 2152628e60cSAxel Dörfler font_height height; 2162628e60cSAxel Dörfler GetFontHeight(&height); 2172628e60cSAxel Dörfler SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT)); 2182628e60cSAxel Dörfler BPoint where((Bounds().Width() - fMenu->StringWidth(kEmptyMenuLabel)) / 2, ceilf(height.ascent + 1)); 2192628e60cSAxel Dörfler DrawString(kEmptyMenuLabel, where); 2202628e60cSAxel Dörfler } 2212628e60cSAxel Dörfler 2222f86ba45SStephan Aßmus if (be_control_look != NULL) 2232f86ba45SStephan Aßmus return; 2242f86ba45SStephan Aßmus 2252628e60cSAxel Dörfler SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); 2262628e60cSAxel Dörfler BRect bounds(Bounds()); 2272628e60cSAxel Dörfler 2282628e60cSAxel Dörfler StrokeLine(BPoint(bounds.right, bounds.top), 2292628e60cSAxel Dörfler BPoint(bounds.right, bounds.bottom - 1)); 2302628e60cSAxel Dörfler StrokeLine(BPoint(bounds.left + 1, bounds.bottom), 2312628e60cSAxel Dörfler BPoint(bounds.right, bounds.bottom)); 2322628e60cSAxel Dörfler } 2332628e60cSAxel Dörfler 2342628e60cSAxel Dörfler 2353616859aSStefano Ceccherini 2362628e60cSAxel Dörfler // #pragma mark - 2372628e60cSAxel Dörfler 2382628e60cSAxel Dörfler 2394185bd8bSStefano Ceccherini BMenuWindow::BMenuWindow(const char *name) 2401664b981SStefano Ceccherini // The window will be resized by BMenu, so just pass a dummy rect 241c7023acdSAxel Dörfler : BWindow(BRect(0, 0, 0, 0), name, B_BORDERED_WINDOW_LOOK, kMenuWindowFeel, 242c7023acdSAxel Dörfler B_NOT_ZOOMABLE | B_AVOID_FOCUS), 2433616859aSStefano Ceccherini fMenu(NULL), 2443616859aSStefano Ceccherini fMenuFrame(NULL), 2453616859aSStefano Ceccherini fUpperScroller(NULL), 2463616859aSStefano Ceccherini fLowerScroller(NULL) 247446b8c19SStefano Ceccherini { 2482f86ba45SStephan Aßmus SetSizeLimits(2, 10000, 2, 10000); 249446b8c19SStefano Ceccherini } 250446b8c19SStefano Ceccherini 251446b8c19SStefano Ceccherini 252446b8c19SStefano Ceccherini BMenuWindow::~BMenuWindow() 253446b8c19SStefano Ceccherini { 254059ca4bdSStefano Ceccherini DetachMenu(); 255446b8c19SStefano Ceccherini } 2565aa032f1SStefano Ceccherini 2575aa032f1SStefano Ceccherini 25861ba5a32SStefano Ceccherini void 2599e64a7edSStefano Ceccherini BMenuWindow::DispatchMessage(BMessage *message, BHandler *handler) 2609e64a7edSStefano Ceccherini { 2619e64a7edSStefano Ceccherini BWindow::DispatchMessage(message, handler); 2629e64a7edSStefano Ceccherini } 2639e64a7edSStefano Ceccherini 2649e64a7edSStefano Ceccherini 2659e64a7edSStefano Ceccherini void 2664185bd8bSStefano Ceccherini BMenuWindow::AttachMenu(BMenu *menu) 2674185bd8bSStefano Ceccherini { 26827cc2508SStefano Ceccherini if (fMenuFrame) 26927cc2508SStefano Ceccherini debugger("BMenuWindow: a menu is already attached!"); 2704185bd8bSStefano Ceccherini if (menu != NULL) { 27127cc2508SStefano Ceccherini fMenuFrame = new BMenuFrame(menu); 27227cc2508SStefano Ceccherini AddChild(fMenuFrame); 27307dc2c69SAxel Dörfler menu->MakeFocus(true); 2743616859aSStefano Ceccherini fMenu = menu; 2754185bd8bSStefano Ceccherini } 2764185bd8bSStefano Ceccherini } 2774185bd8bSStefano Ceccherini 2784185bd8bSStefano Ceccherini 2794185bd8bSStefano Ceccherini void 2804185bd8bSStefano Ceccherini BMenuWindow::DetachMenu() 28161ba5a32SStefano Ceccherini { 28227cc2508SStefano Ceccherini DetachScrollers(); 2833616859aSStefano Ceccherini if (fMenuFrame) { 28427cc2508SStefano Ceccherini RemoveChild(fMenuFrame); 28527cc2508SStefano Ceccherini delete fMenuFrame; 28627cc2508SStefano Ceccherini fMenuFrame = NULL; 2873616859aSStefano Ceccherini fMenu = NULL; 28827cc2508SStefano Ceccherini } 28927cc2508SStefano Ceccherini } 29027cc2508SStefano Ceccherini 29127cc2508SStefano Ceccherini 29227cc2508SStefano Ceccherini void 29327cc2508SStefano Ceccherini BMenuWindow::AttachScrollers() 29427cc2508SStefano Ceccherini { 29560e1cfbfSStefano Ceccherini // We want to attach a scroller only if there's a 29660e1cfbfSStefano Ceccherini // menu frame already existing. 2973616859aSStefano Ceccherini if (!fMenu || !fMenuFrame) 29827cc2508SStefano Ceccherini return; 29927cc2508SStefano Ceccherini 3003616859aSStefano Ceccherini fMenu->MakeFocus(true); 30127cc2508SStefano Ceccherini 3023616859aSStefano Ceccherini BRect frame = Bounds(); 30360e1cfbfSStefano Ceccherini 30460e1cfbfSStefano Ceccherini if (fUpperScroller == NULL) { 30560e1cfbfSStefano Ceccherini fUpperScroller = new UpperScroller( 306*c7bb90f8SStephan Aßmus BRect(0, 0, frame.right, kScrollerHeight - 1)); 3073616859aSStefano Ceccherini AddChild(fUpperScroller); 30860e1cfbfSStefano Ceccherini } 30960e1cfbfSStefano Ceccherini 31060e1cfbfSStefano Ceccherini if (fLowerScroller == NULL) { 31160e1cfbfSStefano Ceccherini fLowerScroller = new LowerScroller( 312*c7bb90f8SStephan Aßmus BRect(0, frame.bottom - kScrollerHeight + 1, frame.right, 313*c7bb90f8SStephan Aßmus frame.bottom)); 3143616859aSStefano Ceccherini AddChild(fLowerScroller); 31560e1cfbfSStefano Ceccherini } 3163616859aSStefano Ceccherini 3173616859aSStefano Ceccherini fUpperScroller->SetEnabled(false); 3183616859aSStefano Ceccherini fLowerScroller->SetEnabled(true); 31927cc2508SStefano Ceccherini 320*c7bb90f8SStephan Aßmus fMenuFrame->ResizeBy(0, -2 * kScrollerHeight); 32127cc2508SStefano Ceccherini fMenuFrame->MoveBy(0, kScrollerHeight); 3223616859aSStefano Ceccherini 3233616859aSStefano Ceccherini fValue = 0; 3243616859aSStefano Ceccherini fLimit = fMenu->Bounds().Height() - (frame.Height() - 2 * kScrollerHeight); 32527cc2508SStefano Ceccherini } 32627cc2508SStefano Ceccherini 32727cc2508SStefano Ceccherini 32827cc2508SStefano Ceccherini void 32927cc2508SStefano Ceccherini BMenuWindow::DetachScrollers() 33027cc2508SStefano Ceccherini { 33127cc2508SStefano Ceccherini // BeOS doesn't remember the position where the last scrolling ended, 33227cc2508SStefano Ceccherini // so we just scroll back to the beginning. 333059ca4bdSStefano Ceccherini if (fMenu) 3343616859aSStefano Ceccherini fMenu->ScrollTo(0, 0); 33527cc2508SStefano Ceccherini 3363616859aSStefano Ceccherini if (fLowerScroller) { 3373616859aSStefano Ceccherini RemoveChild(fLowerScroller); 3383616859aSStefano Ceccherini delete fLowerScroller; 3393616859aSStefano Ceccherini fLowerScroller = NULL; 3403616859aSStefano Ceccherini } 34127cc2508SStefano Ceccherini 3423616859aSStefano Ceccherini if (fUpperScroller) { 3433616859aSStefano Ceccherini RemoveChild(fUpperScroller); 3443616859aSStefano Ceccherini delete fUpperScroller; 3453616859aSStefano Ceccherini fUpperScroller = NULL; 3463616859aSStefano Ceccherini } 34761ba5a32SStefano Ceccherini } 348c7338938SStefano Ceccherini 349c7338938SStefano Ceccherini 350c7338938SStefano Ceccherini bool 3514e0c2a79SStefano Ceccherini BMenuWindow::CheckForScrolling(const BPoint &cursor) 352c7338938SStefano Ceccherini { 353059ca4bdSStefano Ceccherini if (!fMenuFrame || !fUpperScroller || !fLowerScroller) 354c7338938SStefano Ceccherini return false; 355c7338938SStefano Ceccherini 3563616859aSStefano Ceccherini return _Scroll(cursor); 3573616859aSStefano Ceccherini } 3583616859aSStefano Ceccherini 3593616859aSStefano Ceccherini 3603616859aSStefano Ceccherini bool 3614e0c2a79SStefano Ceccherini BMenuWindow::TryScrollBy(const float &step) 3624e0c2a79SStefano Ceccherini { 3634e0c2a79SStefano Ceccherini if (!fMenuFrame || !fUpperScroller || !fLowerScroller) 3644e0c2a79SStefano Ceccherini return false; 3654e0c2a79SStefano Ceccherini 3664e0c2a79SStefano Ceccherini _ScrollBy(step); 3674e0c2a79SStefano Ceccherini 3684e0c2a79SStefano Ceccherini return true; 3694e0c2a79SStefano Ceccherini } 3704e0c2a79SStefano Ceccherini 3714e0c2a79SStefano Ceccherini 3724e0c2a79SStefano Ceccherini bool 3734e0c2a79SStefano Ceccherini BMenuWindow::_Scroll(const BPoint &where) 3743616859aSStefano Ceccherini { 375059ca4bdSStefano Ceccherini ASSERT((fLowerScroller != NULL)); 376059ca4bdSStefano Ceccherini ASSERT((fUpperScroller != NULL)); 377059ca4bdSStefano Ceccherini 3784e0c2a79SStefano Ceccherini const BPoint cursor = ConvertFromScreen(where); 3793616859aSStefano Ceccherini 380059ca4bdSStefano Ceccherini BRect lowerFrame = fLowerScroller->Frame(); 381059ca4bdSStefano Ceccherini BRect upperFrame = fUpperScroller->Frame(); 3823616859aSStefano Ceccherini 383059ca4bdSStefano Ceccherini if (fLowerScroller->IsEnabled() && lowerFrame.Contains(cursor)) { 3844e0c2a79SStefano Ceccherini _ScrollBy(1); 3854e0c2a79SStefano Ceccherini } else if (fUpperScroller->IsEnabled() && upperFrame.Contains(cursor)) { 3864e0c2a79SStefano Ceccherini _ScrollBy(-1); 3874e0c2a79SStefano Ceccherini } else 3884e0c2a79SStefano Ceccherini return false; 3894e0c2a79SStefano Ceccherini 3902f86ba45SStephan Aßmus snooze(5000); 3914e0c2a79SStefano Ceccherini 3924e0c2a79SStefano Ceccherini return true; 3934e0c2a79SStefano Ceccherini } 3944e0c2a79SStefano Ceccherini 3954e0c2a79SStefano Ceccherini 3964e0c2a79SStefano Ceccherini void 3974e0c2a79SStefano Ceccherini BMenuWindow::_ScrollBy(const float &step) 3984e0c2a79SStefano Ceccherini { 3994e0c2a79SStefano Ceccherini if (step > 0) { 4003616859aSStefano Ceccherini if (fValue == 0) { 4013616859aSStefano Ceccherini fUpperScroller->SetEnabled(true); 4023616859aSStefano Ceccherini fUpperScroller->Invalidate(); 4033616859aSStefano Ceccherini } 4043616859aSStefano Ceccherini 4053616859aSStefano Ceccherini if (fValue + kScrollStep >= fLimit) { 4063616859aSStefano Ceccherini // If we reached the limit, we don't want to scroll a whole 4073616859aSStefano Ceccherini // 'step' if not needed. 4083616859aSStefano Ceccherini fMenu->ScrollBy(0, fLimit - fValue); 4093616859aSStefano Ceccherini fValue = fLimit; 4103616859aSStefano Ceccherini fLowerScroller->SetEnabled(false); 4113616859aSStefano Ceccherini fLowerScroller->Invalidate(); 4123616859aSStefano Ceccherini 4133616859aSStefano Ceccherini } else { 4143616859aSStefano Ceccherini fMenu->ScrollBy(0, kScrollStep); 4153616859aSStefano Ceccherini fValue += kScrollStep; 4163616859aSStefano Ceccherini } 4174e0c2a79SStefano Ceccherini } else if (step < 0) { 4183616859aSStefano Ceccherini if (fValue == fLimit) { 4193616859aSStefano Ceccherini fLowerScroller->SetEnabled(true); 4203616859aSStefano Ceccherini fLowerScroller->Invalidate(); 4213616859aSStefano Ceccherini } 4223616859aSStefano Ceccherini 4233616859aSStefano Ceccherini if (fValue - kScrollStep <= 0) { 4243616859aSStefano Ceccherini fMenu->ScrollBy(0, -fValue); 4253616859aSStefano Ceccherini fValue = 0; 4263616859aSStefano Ceccherini fUpperScroller->SetEnabled(false); 4273616859aSStefano Ceccherini fUpperScroller->Invalidate(); 4283616859aSStefano Ceccherini 4293616859aSStefano Ceccherini } else { 4303616859aSStefano Ceccherini fMenu->ScrollBy(0, -kScrollStep); 4313616859aSStefano Ceccherini fValue -= kScrollStep; 4323616859aSStefano Ceccherini } 4334e0c2a79SStefano Ceccherini } 434c7338938SStefano Ceccherini } 435c7338938SStefano Ceccherini 436