Make ScrollMenu not rely on Menu.cpp

Rename ScrollMenu.cpp to MenuScrollView.cpp

Half step towards making this class work as part of Deskbar without
extending any other classes. Scrolling works both with mouse and
scroll wheel. Redraws on scroll, need to make that work better.
Also need to move classes out of the Interface Kit and into Deskbar.
This commit is contained in:
John Scipione 2012-07-20 01:13:14 -04:00
parent cb55ef9fb5
commit 49ff476d13
10 changed files with 123 additions and 107 deletions

View File

@ -7,8 +7,8 @@
* Stefano Ceccherini (stefano.ceccherini@gmail.com)
* John Scipione (jscipione@gmail.com)
*/
#ifndef SCROLL_MENU_H
#define SCROLL_MENU_H
#ifndef MENU_SCROLL_VIEW_H
#define MENU_SCROLL_VIEW_H
#include <View.h>
@ -18,10 +18,10 @@ class BMenu;
class BMenuScroller;
class BScrollMenu : public BView {
class BMenuScrollView : public BView {
public:
BScrollMenu(BMenu* menu);
virtual ~BScrollMenu();
BMenuScrollView(BMenu* menu);
virtual ~BMenuScrollView();
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
@ -52,4 +52,4 @@ private:
};
#endif // SCROLL_MENU_H
#endif // MENU_SCROLL_VIEW_H

View File

@ -48,7 +48,7 @@ All rights reserved.
#include <NodeInfo.h>
#include <Roster.h>
#include <Screen.h>
#include <ScrollMenu.h>
#include <MenuScrollView.h>
#include <String.h>
#include "icons.h"
@ -131,7 +131,7 @@ BarViewMessageFilter::Filter(BMessage* message, BHandler** target)
TBarView::TBarView(BRect frame, bool vertical, bool left, bool top,
uint32 state, float)
: BView(frame, "BarView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
fBarScrollMenu(NULL),
fMenuScrollView(NULL),
fBarMenuBar(NULL),
fExpando(NULL),
fTrayLocation(1),
@ -443,11 +443,11 @@ TBarView::PlaceTray(bool vertSwap, bool leftSwap)
void
TBarView::PlaceApplicationBar()
{
if (fBarScrollMenu != NULL) {
fBarScrollMenu->RemoveSelf();
delete fBarScrollMenu;
if (fMenuScrollView != NULL) {
fMenuScrollView->RemoveSelf();
delete fMenuScrollView;
// Also deletes fExpando
fBarScrollMenu = NULL;
fMenuScrollView = NULL;
fExpando = NULL;
} else if (fExpando != NULL) {
fExpando->RemoveSelf();
@ -488,12 +488,9 @@ TBarView::PlaceApplicationBar()
fExpando = new TExpandoMenuBar(this, expandoFrame, "ExpandoMenuBar",
fVertical, !hideLabels && fState != kFullState);
if (fVertical) {
fBarScrollMenu = new BScrollMenu(fExpando);
AddChild(fBarScrollMenu);
//printf("fExpando bottom: %f, fBarScrollMenu bottom: %f\n", fExpando->Frame().bottom, fBarScrollMenu->Frame().bottom);
} else
AddChild(fExpando);
fMenuScrollView = new BMenuScrollView(fExpando);
AddChild(fMenuScrollView);
//printf("fExpando bottom: %f, fMenuScrollView bottom: %f\n", fExpando->Frame().bottom, fMenuScrollView->Frame().bottom);
if (fVertical)
ExpandItems();
@ -530,7 +527,7 @@ TBarView::GetPreferredWindowSize(BRect screenFrame, float* width, float* height)
} else if (fState == kExpandoState) {
if (fVertical) {
// top left or right
windowHeight = fBarScrollMenu->Frame().bottom;
windowHeight = fMenuScrollView->Frame().bottom;
} else {
// top or bottom, full
fExpando->CheckItemSizes(0);
@ -557,8 +554,14 @@ TBarView::SizeWindow(BRect screenFrame)
float windowWidth, windowHeight;
GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight);
Window()->ResizeTo(windowWidth, windowHeight);
if (fExpando)
if (fExpando != NULL) {
if (fMenuScrollView != NULL) {
fMenuScrollView->ResizeTo(fExpando->Bounds().Width(),
fExpando->Bounds().Height());
}
fExpando->CheckForSizeOverrun();
}
}
@ -687,7 +690,7 @@ TBarView::ExpandItems()
// Clean up the expanded items list
RemoveExpandedItems();
fExpando->SizeWindow();
fExpando->SizeWindow(1);
}

View File

@ -65,7 +65,7 @@ const float kStatusHeight = 22.0f;
const float kHiddenDimension = 1.0f;
const float kMaxPreventHidingDist = 80.0f;
class BScrollMenu;
class BMenuScrollView;
class BShelf;
class TBarMenuBar;
class TExpandoMenuBar;
@ -168,7 +168,7 @@ class TBarView : public BView {
void ExpandItems();
void _ChangeState(BMessage* message);
BScrollMenu* fBarScrollMenu;
BMenuScrollView* fMenuScrollView;
TBarMenuBar* fBarMenuBar;
TExpandoMenuBar* fExpando;

View File

@ -45,7 +45,7 @@ All rights reserved.
#include <NodeInfo.h>
#include <Roster.h>
#include <Screen.h>
#include <ScrollMenu.h>
#include <MenuScrollView.h>
#include "icons.h"
@ -194,6 +194,10 @@ TExpandoMenuBar::AttachedToWindow()
ResizeTo(itemWidth, 0);
}
BMenuScrollView* scrollMenu = dynamic_cast<BMenuScrollView*>(Parent());
if (scrollMenu != NULL)
scrollMenu->ResizeTo(Bounds().Width(), Bounds().Height());
if (fVertical) {
sDoMonitor = true;
sMonThread = spawn_thread(monitor_team_windows,
@ -263,6 +267,32 @@ TExpandoMenuBar::MessageReceived(BMessage* message)
break;
}
case B_MOUSE_WHEEL_CHANGED:
{
float deltaY = 0;
message->FindFloat("be:wheel_delta_y", &deltaY);
if (deltaY == 0)
return;
BMenuScrollView* scrollMenu
= dynamic_cast<BMenuScrollView*>(Parent());
if (scrollMenu == NULL)
return;
float largeStep;
float smallStep;
scrollMenu->GetSteps(&smallStep, &largeStep);
// pressing the option/command/control key scrolls faster
if (modifiers() & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY))
deltaY *= largeStep;
else
deltaY *= smallStep;
scrollMenu->TryScrollBy(deltaY);
break;
}
case kAddTeam:
AddTeam(message->FindInt32("team"), message->FindString("sig"));
break;
@ -397,6 +427,14 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
// force a cleanup
_FinishedDrag();
// check for scrolling menu
BMenuScrollView* scrollMenu = dynamic_cast<BMenuScrollView*>(Parent());
if (scrollMenu != NULL) {
BPoint screenLocation = ConvertToScreen(where);
while(scrollMenu->CheckForScrolling(screenLocation))
TExpandoMenuBar::MouseMoved(where, code, message);
}
switch (code) {
case B_ENTERED_VIEW:
case B_INSIDE_VIEW:
@ -611,10 +649,9 @@ TExpandoMenuBar::AddTeam(BList* team, BBitmap* icon, char* name,
if (fVertical) {
if (item && fShowTeamExpander && fExpandNewTeams)
item->ToggleExpandState(false);
}
fBarView->SizeWindow(BScreen(Window()).Frame());
} else
CheckItemSizes(1);
SizeWindow(1);
Window()->UpdateIfNeeded();
}
@ -656,14 +693,7 @@ TExpandoMenuBar::RemoveTeam(team_id team, bool partial)
RemoveItem(i);
if (fVertical) {
// instead of resizing the window here and there in the
// code the resize method will be centered in one place
// thus, the same behavior (good or bad) will be used
// whereever window sizing is done
fBarView->SizeWindow(BScreen(Window()).Frame());
} else
CheckItemSizes(-1);
SizeWindow(-1);
Window()->UpdateIfNeeded();
@ -803,7 +833,7 @@ TExpandoMenuBar::CheckForSizeOverrun()
return;
}
BScrollMenu* scrollMenu = dynamic_cast<BScrollMenu*>(Parent());
BMenuScrollView* scrollMenu = dynamic_cast<BMenuScrollView*>(Parent());
if (scrollMenu == NULL)
return;
@ -818,12 +848,20 @@ TExpandoMenuBar::CheckForSizeOverrun()
void
TExpandoMenuBar::SizeWindow()
TExpandoMenuBar::SizeWindow(int32 delta)
{
BMenuScrollView* scrollMenu = dynamic_cast<BMenuScrollView*>(Parent());
if (scrollMenu != NULL)
scrollMenu->ResizeTo(Bounds().Width(), Bounds().Height());
// instead of resizing the window here and there in the
// code the resize method will be centered in one place
// thus, the same behavior (good or bad) will be used
// wherever window sizing is done
if (fVertical)
fBarView->SizeWindow(BScreen(Window()).Frame());
else
CheckItemSizes(1);
CheckItemSizes(delta);
}
@ -928,7 +966,7 @@ TExpandoMenuBar::monitor_team_windows(void* arg)
if (itemModified || resize) {
teamMenu->Invalidate();
if (resize)
teamMenu->SizeWindow();
teamMenu->SizeWindow(1);
}
teamMenu->Window()->Unlock();

View File

@ -82,7 +82,7 @@ class TExpandoMenuBar : public BMenuBar {
menu_layout MenuLayout() const;
void SizeWindow();
void SizeWindow(int32 delta);
void CheckForSizeOverrun();
private:

View File

@ -479,7 +479,8 @@ TTeamMenuItem::DrawContentLabel()
if (Submenu() && fVertical)
cachedWidth += 18;
BString label(Label());
const char* label = Label();
char* truncLabel = NULL;
float max = 0;
if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando)
@ -491,23 +492,30 @@ TTeamMenuItem::DrawContentLabel()
BPoint penloc = menu->PenLocation();
BRect frame = Frame();
float offset = penloc.x - frame.left;
if (cachedWidth + offset > max)
menu->TruncateString(&label, B_TRUNCATE_MIDDLE, max - offset);
if (cachedWidth + offset > max) {
truncLabel = (char*)malloc(strlen(label) + 4);
if (!truncLabel)
return;
TruncateLabel(max-offset, truncLabel);
label = truncLabel;
}
}
if (!label)
label = BString(Label());
label = Label();
TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
bool canHandle = !barView->Dragging()
|| barView->AppCanHandleTypes(Signature());
TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
bool canHandle = !barview->Dragging()
|| barview->AppCanHandleTypes(Signature());
if (_IsSelected() && IsEnabled() && canHandle)
menu->SetLowColor(tint_color(menu->LowColor(),
B_HIGHLIGHT_BACKGROUND_TINT));
else
menu->SetLowColor(menu->LowColor());
menu->DrawString(label.String());
menu->DrawString(label);
free(truncLabel);
}
@ -551,7 +559,7 @@ TTeamMenuItem::ToggleExpandState(bool resizeWindow)
sub->SetExpanded(true, myindex + childIndex);
if (resizeWindow)
parent->SizeWindow();
parent->SizeWindow(1);
}
}
} else {
@ -573,7 +581,7 @@ TTeamMenuItem::ToggleExpandState(bool resizeWindow)
sub->SetExpanded(false, 0);
if (resizeWindow)
parent->SizeWindow();
parent->SizeWindow(1);
}
}
}

View File

@ -82,6 +82,7 @@ MergeObject <libbe>interface_kit.o :
MenuField.cpp
MenuItem.cpp
MenuPrivate.cpp
MenuScrollView.cpp
MenuWindow.cpp
OptionControl.cpp
OptionPopUp.cpp
@ -101,7 +102,6 @@ MergeObject <libbe>interface_kit.o :
RegionSupport.cpp
Screen.cpp
ScrollBar.cpp
ScrollMenu.cpp
ScrollView.cpp
SeparatorItem.cpp
SeparatorView.cpp

View File

@ -2812,13 +2812,8 @@ BMenu::_ChooseTrigger(const char* title, int32& index, uint32& trigger,
void
BMenu::_UpdateWindowViewSize(const bool &move)
{
if (dynamic_cast<BMenuBar*>(this) != NULL) {
BScrollMenu* scrollMenu = dynamic_cast<BScrollMenu*>(Parent());
if (scrollMenu != NULL)
scrollMenu->ResizeTo(Bounds().Width(), Bounds().Height());
if (dynamic_cast<BMenuBar*>(this) != NULL)
return;
}
BMenuWindow* window = static_cast<BMenuWindow*>(Window());
if (window == NULL)

View File

@ -18,7 +18,7 @@
#include <ControlLook.h>
#include <LayoutUtils.h>
#include <MenuItem.h>
#include <ScrollMenu.h>
#include <MenuScrollView.h>
#include <Window.h>
#include <AppMisc.h>
@ -329,36 +329,7 @@ BMenuBar::Draw(BRect updateRect)
void
BMenuBar::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case B_MOUSE_WHEEL_CHANGED:
{
float deltaY = 0;
msg->FindFloat("be:wheel_delta_y", &deltaY);
if (deltaY == 0)
return;
BScrollMenu* scrollMenu = dynamic_cast<BScrollMenu*>(Parent());
if (scrollMenu == NULL)
return;
float largeStep;
float smallStep;
scrollMenu->GetSteps(&smallStep, &largeStep);
// pressing the option/command/control key scrolls faster
if (modifiers() & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY))
deltaY *= largeStep;
else
deltaY *= smallStep;
scrollMenu->TryScrollBy(deltaY);
break;
}
default:
BMenu::MessageReceived(msg);
break;
}
BMenu::MessageReceived(msg);
}

View File

@ -9,7 +9,7 @@
*/
#include <ScrollMenu.h>
#include <MenuScrollView.h>
#include <ControlLook.h>
#include <Debug.h>
@ -22,8 +22,7 @@
#include <MenuPrivate.h>
const char* kEmptyMenuLabel = "<empty>";
const int kDefaultScrollStep = 19;
const int kDefaultScrollStep = 8;
const int kScrollerHeight = 12;
@ -161,7 +160,7 @@ BMenuDownScroller::Draw(BRect updateRect)
// #pragma mark -
BScrollMenu::BScrollMenu(BMenu *menu)
BMenuScrollView::BMenuScrollView(BMenu *menu)
:
BView("menu scroll view", B_WILL_DRAW | B_FRAME_EVENTS),
fMenu(menu),
@ -172,7 +171,7 @@ BScrollMenu::BScrollMenu(BMenu *menu)
}
BScrollMenu::~BScrollMenu()
BMenuScrollView::~BMenuScrollView()
{
if (fMenu != NULL) {
fMenu->RemoveSelf();
@ -195,7 +194,7 @@ BScrollMenu::~BScrollMenu()
void
BScrollMenu::AttachedToWindow()
BMenuScrollView::AttachedToWindow()
{
BView::AttachedToWindow();
@ -204,7 +203,7 @@ BScrollMenu::AttachedToWindow()
AddChild(fMenu);
// Move the scroll menu into the right position
// Move the scroll menu into position
MoveTo(fMenu->Frame().LeftTop());
BFont font;
@ -214,7 +213,7 @@ BScrollMenu::AttachedToWindow()
void
BScrollMenu::DetachedFromWindow()
BMenuScrollView::DetachedFromWindow()
{
BView::DetachedFromWindow();
@ -230,7 +229,7 @@ BScrollMenu::DetachedFromWindow()
void
BScrollMenu::Draw(BRect updateRect)
BMenuScrollView::Draw(BRect updateRect)
{
if (be_control_look != NULL)
return;
@ -246,7 +245,7 @@ BScrollMenu::Draw(BRect updateRect)
void
BScrollMenu::FrameResized(float newWidth, float newHeight)
BMenuScrollView::FrameResized(float newWidth, float newHeight)
{
BView::FrameResized(newWidth, newHeight);
@ -260,7 +259,7 @@ BScrollMenu::FrameResized(float newWidth, float newHeight)
void
BScrollMenu::AttachScrollers()
BMenuScrollView::AttachScrollers()
{
if (fMenu == NULL)
return;
@ -297,7 +296,7 @@ BScrollMenu::AttachScrollers()
void
BScrollMenu::DetachScrollers()
BMenuScrollView::DetachScrollers()
{
if (!HasScrollers())
return;
@ -327,21 +326,21 @@ BScrollMenu::DetachScrollers()
bool
BScrollMenu::HasScrollers() const
BMenuScrollView::HasScrollers() const
{
return fMenu != NULL && fUpperScroller != NULL && fLowerScroller != NULL;
}
void
BScrollMenu::SetSmallStep(float step)
BMenuScrollView::SetSmallStep(float step)
{
fScrollStep = step;
}
void
BScrollMenu::GetSteps(float* _smallStep, float* _largeStep) const
BMenuScrollView::GetSteps(float* _smallStep, float* _largeStep) const
{
if (_smallStep != NULL)
*_smallStep = fScrollStep;
@ -355,7 +354,7 @@ BScrollMenu::GetSteps(float* _smallStep, float* _largeStep) const
bool
BScrollMenu::CheckForScrolling(const BPoint &cursor)
BMenuScrollView::CheckForScrolling(const BPoint &cursor)
{
if (!HasScrollers())
return false;
@ -365,7 +364,7 @@ BScrollMenu::CheckForScrolling(const BPoint &cursor)
bool
BScrollMenu::TryScrollBy(const float& step)
BMenuScrollView::TryScrollBy(const float& step)
{
if (!HasScrollers())
return false;
@ -376,7 +375,7 @@ BScrollMenu::TryScrollBy(const float& step)
bool
BScrollMenu::_Scroll(const BPoint& where)
BMenuScrollView::_Scroll(const BPoint& where)
{
ASSERT((fLowerScroller != NULL));
ASSERT((fUpperScroller != NULL));
@ -405,7 +404,7 @@ BScrollMenu::_Scroll(const BPoint& where)
void
BScrollMenu::_ScrollBy(const float& step)
BMenuScrollView::_ScrollBy(const float& step)
{
if (step > 0) {
if (fValue == 0)
@ -420,6 +419,7 @@ BScrollMenu::_ScrollBy(const float& step)
fMenu->ScrollBy(0, step);
fValue += step;
}
fMenu->Invalidate();
} else if (step < 0) {
if (fValue == fLimit)
fLowerScroller->SetEnabled(true);
@ -432,5 +432,6 @@ BScrollMenu::_ScrollBy(const float& step)
fMenu->ScrollBy(0, step);
fValue += step;
}
fMenu->Invalidate();
}
}