Greatly improved scrolling, and simplified the code too. Now scrolling

is done from inside the BMenu::_track() function, and not inside Pulse() 
anymore. Patch by Lucasz Zemczak


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19653 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini 2006-12-29 07:01:08 +00:00
parent 191732a41c
commit c733893846
3 changed files with 40 additions and 18 deletions

View File

@ -32,6 +32,8 @@ class BMenuWindow : public BWindow {
void AttachScrollers(); void AttachScrollers();
void DetachScrollers(); void DetachScrollers();
bool CheckForScrolling(BPoint cursor);
private: private:
BMenuScroller *fScroller; BMenuScroller *fScroller;
BMenuFrame *fMenuFrame; BMenuFrame *fMenuFrame;

View File

@ -1270,11 +1270,17 @@ BMenu::_track(int *action, bigtime_t trackTime, long start)
BPoint location; BPoint location;
ulong buttons; ulong buttons;
GetMouse(&location, &buttons, true); GetMouse(&location, &buttons, true);
BMenuWindow *window(static_cast<BMenuWindow *>(Window()));
BPoint screenLocation = ConvertToScreen(location); BPoint screenLocation = ConvertToScreen(location);
item = HitTestItems(location, B_ORIGIN); if (window->CheckForScrolling(screenLocation)) {
if (item != NULL) item = NULL;
_UpdateStateOpenSelect(item, openTime, closeTime); } else {
item = HitTestItems(location, B_ORIGIN);
if (item != NULL)
_UpdateStateOpenSelect(item, openTime, closeTime);
}
// Track the submenu // Track the submenu
if (OverSubmenu(fSelected, screenLocation)) { if (OverSubmenu(fSelected, screenLocation)) {

View File

@ -23,8 +23,8 @@ class BMenuScroller : public BView {
BMenuScroller(BRect frame, BMenu *menu); BMenuScroller(BRect frame, BMenu *menu);
virtual ~BMenuScroller(); virtual ~BMenuScroller();
virtual void Pulse();
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
bool Scroll(BPoint cursor);
private: private:
BMenu *fMenu; BMenu *fMenu;
@ -62,12 +62,11 @@ using namespace BPrivate;
const int kScrollerHeight = 10; const int kScrollerHeight = 10;
const int kScrollStep = 16; const int kScrollStep = 19;
BMenuScroller::BMenuScroller(BRect frame, BMenu *menu) BMenuScroller::BMenuScroller(BRect frame, BMenu *menu)
: BView(frame, "menu scroller", 0, : BView(frame, "menu scroller", 0, B_WILL_DRAW | B_FRAME_EVENTS),
B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED),
fMenu(menu), fMenu(menu),
fUpperButton(0, 0, frame.right, kScrollerHeight), fUpperButton(0, 0, frame.right, kScrollerHeight),
fLowerButton(0, frame.bottom - kScrollerHeight, frame.right, frame.bottom), fLowerButton(0, frame.bottom - kScrollerHeight, frame.right, frame.bottom),
@ -88,18 +87,15 @@ BMenuScroller::~BMenuScroller()
} }
void bool
BMenuScroller::Pulse() BMenuScroller::Scroll(BPoint cursor)
{ {
// To reduce the overhead even a little, fButton and fPosition were ConvertFromScreen(&cursor);
// made private variables.
// We track the mouse and move the scrollers depending on its position. if (fLowerEnabled && fLowerButton.Contains(cursor)) {
GetMouse(&fPosition, &fButton);
if (fLowerButton.Contains(fPosition) && fLowerEnabled) {
if (fValue == 0) { if (fValue == 0) {
fUpperEnabled = true; fUpperEnabled = true;
Invalidate(fUpperButton); Invalidate(fUpperButton);
} }
@ -110,11 +106,12 @@ BMenuScroller::Pulse()
fValue = fLimit; fValue = fLimit;
fLowerEnabled = false; fLowerEnabled = false;
Invalidate(fLowerButton); Invalidate(fLowerButton);
} else { } else {
fMenu->ScrollBy(0, kScrollStep); fMenu->ScrollBy(0, kScrollStep);
fValue += kScrollStep; fValue += kScrollStep;
} }
} else if (fUpperButton.Contains(fPosition) && fUpperEnabled) { } else if (fUpperEnabled && fUpperButton.Contains(cursor)) {
if (fValue == fLimit) { if (fValue == fLimit) {
fLowerEnabled = true; fLowerEnabled = true;
Invalidate(fLowerButton); Invalidate(fLowerButton);
@ -125,11 +122,18 @@ BMenuScroller::Pulse()
fValue = 0; fValue = 0;
fUpperEnabled = false; fUpperEnabled = false;
Invalidate(fUpperButton); Invalidate(fUpperButton);
} else { } else {
fMenu->ScrollBy(0, -kScrollStep); fMenu->ScrollBy(0, -kScrollStep);
fValue -= kScrollStep; fValue -= kScrollStep;
} }
} else {
return false;
} }
snooze(10000);
return true;
} }
@ -252,7 +256,6 @@ BMenuWindow::BMenuWindow(const char *name)
fScroller(NULL), fScroller(NULL),
fMenuFrame(NULL) fMenuFrame(NULL)
{ {
SetPulseRate(200000);
} }
@ -325,3 +328,14 @@ BMenuWindow::DetachScrollers()
delete fScroller; delete fScroller;
fScroller = NULL; fScroller = NULL;
} }
bool
BMenuWindow::CheckForScrolling(BPoint cursor)
{
if (!fScroller)
return false;
return fScroller->Scroll(cursor);
}