* BMenu now scrolls when you press page up/down, if possible.
* BMenuWindow no longer uses a fixed scroll step - instead, the menu sets it to the height of its first item. * Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31389 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9515252e02
commit
4e23bc0383
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* Copyright 2001-2006, Haiku, Inc.
|
||||
* Copyright 2001-2009, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Marc Flerackers (mflerackers@androme.be)
|
||||
* Stefano Ceccherini (burton666@libero.it)
|
||||
*/
|
||||
#ifndef __MENUWINDOW_H
|
||||
#define __MENUWINDOW_H
|
||||
#ifndef MENU_WINDOW_H
|
||||
#define MENU_WINDOW_H
|
||||
|
||||
|
||||
#include <Window.h>
|
||||
|
@ -22,34 +22,39 @@ class BMenuScroller;
|
|||
|
||||
|
||||
class BMenuWindow : public BWindow {
|
||||
public:
|
||||
BMenuWindow(const char *name);
|
||||
virtual ~BMenuWindow();
|
||||
public:
|
||||
BMenuWindow(const char* name);
|
||||
virtual ~BMenuWindow();
|
||||
|
||||
virtual void DispatchMessage(BMessage *message, BHandler *handler);
|
||||
virtual void DispatchMessage(BMessage* message,
|
||||
BHandler* handler);
|
||||
|
||||
void AttachMenu(BMenu *menu);
|
||||
void DetachMenu();
|
||||
void AttachMenu(BMenu* menu);
|
||||
void DetachMenu();
|
||||
|
||||
void AttachScrollers();
|
||||
void DetachScrollers();
|
||||
void AttachScrollers();
|
||||
void DetachScrollers();
|
||||
|
||||
bool CheckForScrolling(const BPoint &cursor);
|
||||
bool TryScrollBy(const float &step);
|
||||
void SetSmallStep(float step);
|
||||
void GetSteps(float* _smallStep, float* _largeStep);
|
||||
bool HasScrollers() const;
|
||||
bool CheckForScrolling(const BPoint& cursor);
|
||||
bool TryScrollBy(const float& step);
|
||||
|
||||
private:
|
||||
BMenu *fMenu;
|
||||
BMenuFrame *fMenuFrame;
|
||||
BMenuScroller *fUpperScroller;
|
||||
BMenuScroller *fLowerScroller;
|
||||
private:
|
||||
bool _Scroll(const BPoint& cursor);
|
||||
void _ScrollBy(const float& step);
|
||||
|
||||
float fValue;
|
||||
float fLimit;
|
||||
BMenu* fMenu;
|
||||
BMenuFrame* fMenuFrame;
|
||||
BMenuScroller* fUpperScroller;
|
||||
BMenuScroller* fLowerScroller;
|
||||
|
||||
bool _Scroll(const BPoint &cursor);
|
||||
void _ScrollBy(const float &step);
|
||||
float fScrollStep;
|
||||
float fValue;
|
||||
float fLimit;
|
||||
};
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
#endif // __MENUWINDOW_H
|
||||
#endif // MENU_WINDOW_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2008, Haiku, Inc.
|
||||
* Copyright 2001-2009, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
|
@ -8,6 +8,8 @@
|
|||
* Rene Gollent (anevilyak@gmail.com)
|
||||
*/
|
||||
|
||||
#include <Menu.h>
|
||||
|
||||
#include <new>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
@ -18,13 +20,13 @@
|
|||
#include <FindDirectory.h>
|
||||
#include <Layout.h>
|
||||
#include <LayoutUtils.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuBar.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Messenger.h>
|
||||
#include <Path.h>
|
||||
#include <PropertyInfo.h>
|
||||
#include <Screen.h>
|
||||
#include <ScrollBar.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <AppServerLink.h>
|
||||
|
@ -819,9 +821,7 @@ BMenu::MessageReceived(BMessage *msg)
|
|||
switch (msg->what) {
|
||||
case B_MOUSE_WHEEL_CHANGED:
|
||||
{
|
||||
//float deltaX = 0
|
||||
float deltaY = 0;
|
||||
//msg->FindFloat("be:wheel_delta_x", &deltaX);
|
||||
msg->FindFloat("be:wheel_delta_y", &deltaY);
|
||||
if (deltaY == 0)
|
||||
return;
|
||||
|
@ -830,7 +830,9 @@ BMenu::MessageReceived(BMessage *msg)
|
|||
if (window == NULL)
|
||||
return;
|
||||
|
||||
window->TryScrollBy(deltaY);
|
||||
float smallStep;
|
||||
window->GetSteps(&smallStep, NULL);
|
||||
window->TryScrollBy(deltaY * smallStep);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -890,6 +892,21 @@ BMenu::KeyDown(const char *bytes, int32 numBytes)
|
|||
}
|
||||
break;
|
||||
|
||||
case B_PAGE_UP:
|
||||
case B_PAGE_DOWN:
|
||||
{
|
||||
BMenuWindow *window = dynamic_cast<BMenuWindow *>(Window());
|
||||
if (window == NULL || !window->HasScrollers())
|
||||
break;
|
||||
|
||||
int32 deltaY = bytes[0] == B_PAGE_UP ? -1 : 1;
|
||||
|
||||
float largeStep;
|
||||
window->GetSteps(NULL, &largeStep);
|
||||
window->TryScrollBy(deltaY * largeStep);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_ENTER:
|
||||
case B_SPACE:
|
||||
if (fSelected) {
|
||||
|
@ -1426,6 +1443,13 @@ BMenu::_Show(bool selectFirstItem)
|
|||
fAttachAborted = false;
|
||||
window->AttachMenu(this);
|
||||
|
||||
if (ItemAt(0) != NULL) {
|
||||
float width, height;
|
||||
ItemAt(0)->GetContentSize(&width, &height);
|
||||
|
||||
window->SetSmallStep(ceilf(height));
|
||||
}
|
||||
|
||||
// Menu didn't have the time to add its items: aborting...
|
||||
if (fAttachAborted) {
|
||||
window->DetachMenu();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2001-2007, Haiku, Inc.
|
||||
* Copyright 2001-2009, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
|
@ -14,6 +14,8 @@
|
|||
#include <ControlLook.h>
|
||||
#include <Debug.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuItem.h>
|
||||
|
||||
#include <MenuPrivate.h>
|
||||
#include <WindowPrivate.h>
|
||||
|
||||
|
@ -67,7 +69,6 @@ using namespace BPrivate;
|
|||
|
||||
|
||||
const int kScrollerHeight = 10;
|
||||
const int kScrollStep = 19;
|
||||
|
||||
|
||||
BMenuScroller::BMenuScroller(BRect frame)
|
||||
|
@ -243,7 +244,8 @@ BMenuWindow::BMenuWindow(const char *name)
|
|||
fMenu(NULL),
|
||||
fMenuFrame(NULL),
|
||||
fUpperScroller(NULL),
|
||||
fLowerScroller(NULL)
|
||||
fLowerScroller(NULL),
|
||||
fScrollStep(19)
|
||||
{
|
||||
SetSizeLimits(2, 10000, 2, 10000);
|
||||
}
|
||||
|
@ -347,6 +349,35 @@ BMenuWindow::DetachScrollers()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
BMenuWindow::SetSmallStep(float step)
|
||||
{
|
||||
fScrollStep = step;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BMenuWindow::GetSteps(float* _smallStep, float* _largeStep)
|
||||
{
|
||||
if (_smallStep != NULL)
|
||||
*_smallStep = fScrollStep;
|
||||
if (_largeStep != NULL) {
|
||||
if (fMenuFrame != NULL)
|
||||
*_largeStep = fMenuFrame->Bounds().Height() - fScrollStep;
|
||||
else
|
||||
*_largeStep = fScrollStep * 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BMenuWindow::HasScrollers() const
|
||||
{
|
||||
return fMenuFrame != NULL && fUpperScroller != NULL
|
||||
&& fLowerScroller != NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BMenuWindow::CheckForScrolling(const BPoint &cursor)
|
||||
{
|
||||
|
@ -358,19 +389,18 @@ BMenuWindow::CheckForScrolling(const BPoint &cursor)
|
|||
|
||||
|
||||
bool
|
||||
BMenuWindow::TryScrollBy(const float &step)
|
||||
BMenuWindow::TryScrollBy(const float& step)
|
||||
{
|
||||
if (!fMenuFrame || !fUpperScroller || !fLowerScroller)
|
||||
return false;
|
||||
|
||||
_ScrollBy(step);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BMenuWindow::_Scroll(const BPoint &where)
|
||||
BMenuWindow::_Scroll(const BPoint& where)
|
||||
{
|
||||
ASSERT((fLowerScroller != NULL));
|
||||
ASSERT((fUpperScroller != NULL));
|
||||
|
@ -380,11 +410,11 @@ BMenuWindow::_Scroll(const BPoint &where)
|
|||
BRect lowerFrame = fLowerScroller->Frame();
|
||||
BRect upperFrame = fUpperScroller->Frame();
|
||||
|
||||
if (fLowerScroller->IsEnabled() && lowerFrame.Contains(cursor)) {
|
||||
if (fLowerScroller->IsEnabled() && lowerFrame.Contains(cursor))
|
||||
_ScrollBy(1);
|
||||
} else if (fUpperScroller->IsEnabled() && upperFrame.Contains(cursor)) {
|
||||
else if (fUpperScroller->IsEnabled() && upperFrame.Contains(cursor))
|
||||
_ScrollBy(-1);
|
||||
} else
|
||||
else
|
||||
return false;
|
||||
|
||||
snooze(5000);
|
||||
|
@ -394,7 +424,7 @@ BMenuWindow::_Scroll(const BPoint &where)
|
|||
|
||||
|
||||
void
|
||||
BMenuWindow::_ScrollBy(const float &step)
|
||||
BMenuWindow::_ScrollBy(const float& step)
|
||||
{
|
||||
if (step > 0) {
|
||||
if (fValue == 0) {
|
||||
|
@ -402,17 +432,15 @@ BMenuWindow::_ScrollBy(const float &step)
|
|||
fUpperScroller->Invalidate();
|
||||
}
|
||||
|
||||
if (fValue + kScrollStep >= fLimit) {
|
||||
// If we reached the limit, we don't want to scroll a whole
|
||||
// 'step' if not needed.
|
||||
if (fValue + step >= fLimit) {
|
||||
// If we reached the limit, only scroll to the end
|
||||
fMenu->ScrollBy(0, fLimit - fValue);
|
||||
fValue = fLimit;
|
||||
fLowerScroller->SetEnabled(false);
|
||||
fLowerScroller->Invalidate();
|
||||
|
||||
} else {
|
||||
fMenu->ScrollBy(0, kScrollStep);
|
||||
fValue += kScrollStep;
|
||||
fMenu->ScrollBy(0, step);
|
||||
fValue += step;
|
||||
}
|
||||
} else if (step < 0) {
|
||||
if (fValue == fLimit) {
|
||||
|
@ -420,15 +448,14 @@ BMenuWindow::_ScrollBy(const float &step)
|
|||
fLowerScroller->Invalidate();
|
||||
}
|
||||
|
||||
if (fValue - kScrollStep <= 0) {
|
||||
if (fValue + step <= 0) {
|
||||
fMenu->ScrollBy(0, -fValue);
|
||||
fValue = 0;
|
||||
fUpperScroller->SetEnabled(false);
|
||||
fUpperScroller->Invalidate();
|
||||
|
||||
} else {
|
||||
fMenu->ScrollBy(0, -kScrollStep);
|
||||
fValue -= kScrollStep;
|
||||
fMenu->ScrollBy(0, step);
|
||||
fValue += step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue