Menus don't flicker anymore, extended some ToDos, small cleanups. Implemented BMenu::IsItemVisible() as I think I'll need it soon, extended Bmenu::OverSubmenu() to be recursive, it's not used at the moment but should be.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12899 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
60d5a3fc59
commit
26ad9841a2
@ -31,6 +31,7 @@
|
|||||||
#include <MenuItem.h>
|
#include <MenuItem.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <PropertyInfo.h>
|
#include <PropertyInfo.h>
|
||||||
|
#include <Screen.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
#include <MenuWindow.h>
|
#include <MenuWindow.h>
|
||||||
@ -356,17 +357,16 @@ bool
|
|||||||
BMenu::AddList(BList *list, int32 index)
|
BMenu::AddList(BList *list, int32 index)
|
||||||
{
|
{
|
||||||
// TODO: test this function, it's not documented in the bebook.
|
// TODO: test this function, it's not documented in the bebook.
|
||||||
int32 numItems = 0;
|
if (list == NULL)
|
||||||
if (list != NULL)
|
return false;
|
||||||
numItems = list->CountItems();
|
|
||||||
|
|
||||||
|
int32 numItems = list->CountItems();
|
||||||
for (int32 i = 0; i < numItems; i++) {
|
for (int32 i = 0; i < numItems; i++) {
|
||||||
BMenuItem *item = static_cast<BMenuItem *>(list->ItemAt(i));
|
BMenuItem *item = static_cast<BMenuItem *>(list->ItemAt(i));
|
||||||
if (item != NULL)
|
if (item != NULL)
|
||||||
_AddItem(item, index + i);
|
_AddItem(item, index + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: return false if needed
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,7 +406,7 @@ BMenu::RemoveItems(int32 index, int32 count, bool del)
|
|||||||
bool
|
bool
|
||||||
BMenu::RemoveItem(BMenu *submenu)
|
BMenu::RemoveItem(BMenu *submenu)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fItems.CountItems(); i++)
|
for (int32 i = 0; i < fItems.CountItems(); i++)
|
||||||
if (static_cast<BMenuItem *>(fItems.ItemAt(i))->Submenu() == submenu)
|
if (static_cast<BMenuItem *>(fItems.ItemAt(i))->Submenu() == submenu)
|
||||||
return RemoveItems(i, 1, NULL, false);
|
return RemoveItems(i, 1, NULL, false);
|
||||||
|
|
||||||
@ -501,22 +501,32 @@ BMenu::FindItem(uint32 command) const
|
|||||||
status_t
|
status_t
|
||||||
BMenu::SetTargetForItems(BHandler *handler)
|
BMenu::SetTargetForItems(BHandler *handler)
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < fItems.CountItems(); i++)
|
// TODO: Test what beos returns here in
|
||||||
if (ItemAt(i)->SetTarget(handler) < B_OK)
|
// case there are no items
|
||||||
return B_ERROR;
|
status_t status = B_OK;
|
||||||
|
for (int32 i = 0; i < fItems.CountItems(); i++) {
|
||||||
return B_OK;
|
status = ItemAt(i)->SetTarget(handler);
|
||||||
|
if (status < B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMenu::SetTargetForItems(BMessenger messenger)
|
BMenu::SetTargetForItems(BMessenger messenger)
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < fItems.CountItems(); i++)
|
// TODO: Test what beos returns here in
|
||||||
if (ItemAt(i)->SetTarget(messenger) < B_OK)
|
// case there are no items
|
||||||
return B_ERROR;
|
status_t status = B_OK;
|
||||||
|
for (int32 i = 0; i < fItems.CountItems(); i++) {
|
||||||
|
status = ItemAt(i)->SetTarget(messenger);
|
||||||
|
if (status < B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -603,11 +613,14 @@ BMenu::MaxContentWidth() const
|
|||||||
BMenuItem *
|
BMenuItem *
|
||||||
BMenu::FindMarked()
|
BMenu::FindMarked()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fItems.CountItems(); i++)
|
BMenuItem *item = NULL;
|
||||||
if (((BMenuItem*)fItems.ItemAt(i))->IsMarked())
|
for (int32 i = 0; i < fItems.CountItems(); i++) {
|
||||||
return (BMenuItem*)fItems.ItemAt(i);
|
item = ItemAt(i);
|
||||||
|
if (item->IsMarked())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1102,14 +1115,9 @@ BMenu::_track(int *action, long start)
|
|||||||
|
|
||||||
item = HitTestItems(location, B_ORIGIN);
|
item = HitTestItems(location, B_ORIGIN);
|
||||||
|
|
||||||
// TODO: Sometimes the menu flickers a bit.
|
|
||||||
// try to be smarter and suggest an update area,
|
|
||||||
// instead of invalidating the whole view.
|
|
||||||
if (item != NULL) {
|
if (item != NULL) {
|
||||||
if (item != fSelected) {
|
if (item != fSelected)
|
||||||
SelectItem(item);
|
SelectItem(item);
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
int submenuAction = 0;
|
int submenuAction = 0;
|
||||||
BMenuItem *submenuItem = NULL;
|
BMenuItem *submenuItem = NULL;
|
||||||
@ -1381,8 +1389,9 @@ void
|
|||||||
BMenu::DrawItems(BRect updateRect)
|
BMenu::DrawItems(BRect updateRect)
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < fItems.CountItems(); i++) {
|
for (int32 i = 0; i < fItems.CountItems(); i++) {
|
||||||
if (ItemAt(i)->Frame().Intersects(updateRect))
|
BMenuItem *item = ItemAt(i);
|
||||||
ItemAt(i)->Draw();
|
if (item->Frame().Intersects(updateRect))
|
||||||
|
item->Draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1421,11 +1430,18 @@ BMenu::OverSuper(BPoint location)
|
|||||||
bool
|
bool
|
||||||
BMenu::OverSubmenu(BMenuItem *item, BPoint loc)
|
BMenu::OverSubmenu(BMenuItem *item, BPoint loc)
|
||||||
{
|
{
|
||||||
// TODO: we assume that loc is in screen coords
|
// we assume that loc is in screen coords
|
||||||
if (!item->Submenu())
|
BMenu *subMenu = item->Submenu();
|
||||||
|
if (subMenu == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return item->Submenu()->Window()->Frame().Contains(loc);
|
if (subMenu->Window()->Frame().Contains(loc))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (subMenu->fSelected == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return subMenu->OverSubmenu(subMenu->fSelected, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1554,7 +1570,12 @@ BMenu::NextItem(BMenuItem *item, bool forward) const
|
|||||||
bool
|
bool
|
||||||
BMenu::IsItemVisible(BMenuItem *item) const
|
BMenu::IsItemVisible(BMenuItem *item) const
|
||||||
{
|
{
|
||||||
return false;
|
BRect itemFrame = item->Frame();
|
||||||
|
ConvertToScreen(&itemFrame);
|
||||||
|
|
||||||
|
BRect visibilityFrame = Window()->Frame() & BScreen(Window()).Frame();
|
||||||
|
|
||||||
|
return visibilityFrame.Intersects(itemFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -395,13 +395,14 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
|||||||
{
|
{
|
||||||
// TODO: This function is very incomplete and just partially working:
|
// TODO: This function is very incomplete and just partially working:
|
||||||
// For example, it doesn't respect the "sticky mode" setting.
|
// For example, it doesn't respect the "sticky mode" setting.
|
||||||
// Cleanup
|
// Cleanup: We shouldn't use two nested loops. This simplifies the code
|
||||||
|
// but doesn't work well
|
||||||
BMenuItem *resultItem = NULL;
|
BMenuItem *resultItem = NULL;
|
||||||
BWindow *window = Window();
|
BWindow *window = Window();
|
||||||
int localAction;
|
int localAction;
|
||||||
bool exitLoop = false;
|
bool exitLoop = false;
|
||||||
do {
|
do {
|
||||||
if (window->LockLooperWithTimeout(200000) < B_OK)
|
if (window->LockWithTimeout(200000) < B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
BPoint where;
|
BPoint where;
|
||||||
@ -432,7 +433,7 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
|||||||
|
|
||||||
resultItem = menu->_track(&localAction, startIndex);
|
resultItem = menu->_track(&localAction, startIndex);
|
||||||
|
|
||||||
if (window->LockLooperWithTimeout(200000) < B_OK)
|
if (window->LockWithTimeout(200000) < B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// the returned action is "5" when the BMenu is closed.
|
// the returned action is "5" when the BMenu is closed.
|
||||||
@ -487,12 +488,10 @@ BMenuBar::RestoreFocus()
|
|||||||
if (BPrivate::gDefaultTokens.GetToken(fPrevFocusToken, B_HANDLER_TOKEN,
|
if (BPrivate::gDefaultTokens.GetToken(fPrevFocusToken, B_HANDLER_TOKEN,
|
||||||
(void **)&handler, NULL) == B_OK) {
|
(void **)&handler, NULL) == B_OK) {
|
||||||
BView *view = dynamic_cast<BView *>(handler);
|
BView *view = dynamic_cast<BView *>(handler);
|
||||||
// TODO: Are there other things to do in case the BHandler
|
|
||||||
// is not a BView ?
|
|
||||||
if (view != NULL)
|
if (view != NULL)
|
||||||
view->MakeFocus();
|
view->MakeFocus();
|
||||||
}
|
}
|
||||||
fPrevFocusToken = NULL;
|
fPrevFocusToken = -1;
|
||||||
window->Unlock();
|
window->Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user