From 49ff476d139dc28ebaa95d65b7820423b6061d60 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Fri, 20 Jul 2012 01:13:14 -0400 Subject: [PATCH] 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. --- .../{ScrollMenu.h => MenuScrollView.h} | 12 ++-- src/apps/deskbar/BarView.cpp | 33 +++++---- src/apps/deskbar/BarView.h | 4 +- src/apps/deskbar/ExpandoMenuBar.cpp | 70 ++++++++++++++----- src/apps/deskbar/ExpandoMenuBar.h | 2 +- src/apps/deskbar/TeamMenuItem.cpp | 28 +++++--- src/kits/interface/Jamfile | 2 +- src/kits/interface/Menu.cpp | 7 +- src/kits/interface/MenuBar.cpp | 33 +-------- .../{ScrollMenu.cpp => MenuScrollView.cpp} | 39 ++++++----- 10 files changed, 123 insertions(+), 107 deletions(-) rename headers/os/interface/{ScrollMenu.h => MenuScrollView.h} (84%) rename src/kits/interface/{ScrollMenu.cpp => MenuScrollView.cpp} (89%) diff --git a/headers/os/interface/ScrollMenu.h b/headers/os/interface/MenuScrollView.h similarity index 84% rename from headers/os/interface/ScrollMenu.h rename to headers/os/interface/MenuScrollView.h index 4bb14f2981..2a1904e437 100644 --- a/headers/os/interface/ScrollMenu.h +++ b/headers/os/interface/MenuScrollView.h @@ -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 @@ -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 diff --git a/src/apps/deskbar/BarView.cpp b/src/apps/deskbar/BarView.cpp index f874bd1536..d174166929 100644 --- a/src/apps/deskbar/BarView.cpp +++ b/src/apps/deskbar/BarView.cpp @@ -48,7 +48,7 @@ All rights reserved. #include #include #include -#include +#include #include #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); } diff --git a/src/apps/deskbar/BarView.h b/src/apps/deskbar/BarView.h index e8e87ba95b..e118012300 100644 --- a/src/apps/deskbar/BarView.h +++ b/src/apps/deskbar/BarView.h @@ -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; diff --git a/src/apps/deskbar/ExpandoMenuBar.cpp b/src/apps/deskbar/ExpandoMenuBar.cpp index f9cfbb86dc..246d7bfcf2 100644 --- a/src/apps/deskbar/ExpandoMenuBar.cpp +++ b/src/apps/deskbar/ExpandoMenuBar.cpp @@ -45,7 +45,7 @@ All rights reserved. #include #include #include -#include +#include #include "icons.h" @@ -194,6 +194,10 @@ TExpandoMenuBar::AttachedToWindow() ResizeTo(itemWidth, 0); } + BMenuScrollView* scrollMenu = dynamic_cast(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(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(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(Parent()); + BMenuScrollView* scrollMenu = dynamic_cast(Parent()); if (scrollMenu == NULL) return; @@ -818,12 +848,20 @@ TExpandoMenuBar::CheckForSizeOverrun() void -TExpandoMenuBar::SizeWindow() +TExpandoMenuBar::SizeWindow(int32 delta) { + BMenuScrollView* scrollMenu = dynamic_cast(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(); diff --git a/src/apps/deskbar/ExpandoMenuBar.h b/src/apps/deskbar/ExpandoMenuBar.h index 4eabc96d8d..2bd1bd68c5 100644 --- a/src/apps/deskbar/ExpandoMenuBar.h +++ b/src/apps/deskbar/ExpandoMenuBar.h @@ -82,7 +82,7 @@ class TExpandoMenuBar : public BMenuBar { menu_layout MenuLayout() const; - void SizeWindow(); + void SizeWindow(int32 delta); void CheckForSizeOverrun(); private: diff --git a/src/apps/deskbar/TeamMenuItem.cpp b/src/apps/deskbar/TeamMenuItem.cpp index 35ab7ff65c..0f6fa4c4dc 100644 --- a/src/apps/deskbar/TeamMenuItem.cpp +++ b/src/apps/deskbar/TeamMenuItem.cpp @@ -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(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(be_app))->BarView(); - bool canHandle = !barView->Dragging() - || barView->AppCanHandleTypes(Signature()); + TBarView* barview = (static_cast(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); } } } diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile index 4109585a2f..5726843de7 100644 --- a/src/kits/interface/Jamfile +++ b/src/kits/interface/Jamfile @@ -82,6 +82,7 @@ MergeObject interface_kit.o : MenuField.cpp MenuItem.cpp MenuPrivate.cpp + MenuScrollView.cpp MenuWindow.cpp OptionControl.cpp OptionPopUp.cpp @@ -101,7 +102,6 @@ MergeObject interface_kit.o : RegionSupport.cpp Screen.cpp ScrollBar.cpp - ScrollMenu.cpp ScrollView.cpp SeparatorItem.cpp SeparatorView.cpp diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index cde95056fe..2833899973 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -2812,13 +2812,8 @@ BMenu::_ChooseTrigger(const char* title, int32& index, uint32& trigger, void BMenu::_UpdateWindowViewSize(const bool &move) { - if (dynamic_cast(this) != NULL) { - BScrollMenu* scrollMenu = dynamic_cast(Parent()); - if (scrollMenu != NULL) - scrollMenu->ResizeTo(Bounds().Width(), Bounds().Height()); - + if (dynamic_cast(this) != NULL) return; - } BMenuWindow* window = static_cast(Window()); if (window == NULL) diff --git a/src/kits/interface/MenuBar.cpp b/src/kits/interface/MenuBar.cpp index ee2e978b8f..fc47dc7d9c 100644 --- a/src/kits/interface/MenuBar.cpp +++ b/src/kits/interface/MenuBar.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -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(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); } diff --git a/src/kits/interface/ScrollMenu.cpp b/src/kits/interface/MenuScrollView.cpp similarity index 89% rename from src/kits/interface/ScrollMenu.cpp rename to src/kits/interface/MenuScrollView.cpp index 2923f01dc7..e67d3d384d 100644 --- a/src/kits/interface/ScrollMenu.cpp +++ b/src/kits/interface/MenuScrollView.cpp @@ -9,7 +9,7 @@ */ -#include +#include #include #include @@ -22,8 +22,7 @@ #include -const char* kEmptyMenuLabel = ""; -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(); } }