Now items are removed correctly. All RemoveItem() call pass now through the private RemoveItems() method. ComputeLayout now uses a switch block, and prints a warning if B_ITEMS_IN_MATRIX is used, since it's not supported yet. Some cleanups.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10555 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+100
-53
@@ -126,7 +126,7 @@ BMenu::BMenu(const char *name, menu_layout layout)
|
|||||||
|
|
||||||
BMenu::BMenu(const char *name, float width, float height)
|
BMenu::BMenu(const char *name, float width, float height)
|
||||||
: BView(BRect(0.0f, width, 0.0f, height), name,
|
: BView(BRect(0.0f, width, 0.0f, height), name,
|
||||||
B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE),
|
B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE),
|
||||||
fChosenItem(NULL),
|
fChosenItem(NULL),
|
||||||
fSelected(NULL),
|
fSelected(NULL),
|
||||||
fCachedMenuWindow(NULL),
|
fCachedMenuWindow(NULL),
|
||||||
@@ -354,21 +354,24 @@ BMenu::AddSeparatorItem()
|
|||||||
bool
|
bool
|
||||||
BMenu::RemoveItem(BMenuItem *item)
|
BMenu::RemoveItem(BMenuItem *item)
|
||||||
{
|
{
|
||||||
return fItems.RemoveItem(item);
|
// TODO: Check if item is also deleted
|
||||||
|
return RemoveItems(0, 0, item, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BMenuItem *
|
BMenuItem *
|
||||||
BMenu::RemoveItem(int32 index)
|
BMenu::RemoveItem(int32 index)
|
||||||
{
|
{
|
||||||
return static_cast<BMenuItem *>(fItems.RemoveItem(index));
|
BMenuItem *item = ItemAt(index);
|
||||||
|
RemoveItems(index, 1, NULL, false);
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BMenu::RemoveItems(int32 index, int32 count, bool del)
|
BMenu::RemoveItems(int32 index, int32 count, bool del)
|
||||||
{
|
{
|
||||||
return false;
|
return RemoveItems(index, count, NULL, del);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -377,7 +380,7 @@ BMenu::RemoveItem(BMenu *submenu)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < fItems.CountItems(); i++)
|
for (int 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 fItems.RemoveItem(fItems.ItemAt(i));
|
return RemoveItems(i, 1, NULL, false);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -722,8 +725,7 @@ BMenu::ResolveSpecifier(BMessage *msg, int32 index,
|
|||||||
BPropertyInfo propInfo(sPropList);
|
BPropertyInfo propInfo(sPropList);
|
||||||
BHandler *target = NULL;
|
BHandler *target = NULL;
|
||||||
|
|
||||||
switch (propInfo.FindMatch(msg, 0, specifier, form, property))
|
switch (propInfo.FindMatch(msg, 0, specifier, form, property)) {
|
||||||
{
|
|
||||||
case B_ERROR:
|
case B_ERROR:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -880,13 +882,13 @@ void
|
|||||||
BMenu::GetItemMargins(float *left, float *top, float *right,
|
BMenu::GetItemMargins(float *left, float *top, float *right,
|
||||||
float *bottom) const
|
float *bottom) const
|
||||||
{
|
{
|
||||||
if (left)
|
if (left != NULL)
|
||||||
*left = fPad.left;
|
*left = fPad.left;
|
||||||
if (top)
|
if (top != NULL)
|
||||||
*top = fPad.top;
|
*top = fPad.top;
|
||||||
if (right)
|
if (right != NULL)
|
||||||
*right = fPad.right;
|
*right = fPad.right;
|
||||||
if (bottom)
|
if (bottom != NULL)
|
||||||
*bottom = fPad.bottom;
|
*bottom = fPad.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1086,9 +1088,40 @@ BMenu::_AddItem(BMenuItem *item, int32 index)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BMenu::RemoveItems(int32 index, int32 count, BMenuItem *item, bool del)
|
BMenu::RemoveItems(int32 index, int32 count, BMenuItem *_item, bool del)
|
||||||
{
|
{
|
||||||
return false;
|
bool result = false;
|
||||||
|
|
||||||
|
// The plan is simple: If we're given a BMenuItem directly, we use it
|
||||||
|
// and ignore index and count. Otherwise, we use them instead.
|
||||||
|
if (_item != NULL) {
|
||||||
|
// TODO: Check if this is enough.
|
||||||
|
fItems.RemoveItem(_item);
|
||||||
|
_item->Uninstall();
|
||||||
|
if (del)
|
||||||
|
delete _item;
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
BMenuItem *item = NULL;
|
||||||
|
// We iterate backwards because it's simpler
|
||||||
|
// TODO: We should check if index and count are in bounds.
|
||||||
|
for (int32 i = index + count - 1; i >= index; i--) {
|
||||||
|
item = static_cast<BMenuItem *>(fItems.ItemAt(index));
|
||||||
|
if (item != NULL) {
|
||||||
|
// TODO: Check if this is enough.
|
||||||
|
fItems.RemoveItem(item);
|
||||||
|
item->Uninstall();
|
||||||
|
if (del)
|
||||||
|
delete item;
|
||||||
|
if (!result)
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutItems(0);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1114,57 +1147,71 @@ BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems,
|
|||||||
float iWidth, iHeight;
|
float iWidth, iHeight;
|
||||||
BMenuItem *item;
|
BMenuItem *item;
|
||||||
|
|
||||||
if (fLayout == B_ITEMS_IN_COLUMN) {
|
switch (fLayout) {
|
||||||
frame = BRect(0.0f, 0.0f, 0.0f, 2.0f);
|
case B_ITEMS_IN_COLUMN:
|
||||||
|
{
|
||||||
|
frame = BRect(0.0f, 0.0f, 0.0f, 2.0f);
|
||||||
|
|
||||||
for (int i = 0; i < fItems.CountItems(); i++) {
|
for (int32 i = 0; i < fItems.CountItems(); i++) {
|
||||||
item = static_cast<BMenuItem *>(fItems.ItemAt(i));
|
item = static_cast<BMenuItem *>(fItems.ItemAt(i));
|
||||||
|
item->GetContentSize(&iWidth, &iHeight);
|
||||||
item->GetContentSize(&iWidth, &iHeight);
|
|
||||||
|
|
||||||
if (item->fModifiers && item->fShortcutChar)
|
if (item->fModifiers && item->fShortcutChar)
|
||||||
iWidth += 25.0f;
|
iWidth += 25.0f;
|
||||||
|
|
||||||
|
item->fBounds.left = 2.0f;
|
||||||
|
item->fBounds.top = frame.bottom;
|
||||||
|
item->fBounds.bottom = item->fBounds.top + iHeight + fPad.top + fPad.bottom;
|
||||||
|
|
||||||
item->fBounds.left = 2.0f;
|
frame.right = max_c(frame.right, iWidth + fPad.left + fPad.right);
|
||||||
item->fBounds.top = frame.bottom;
|
frame.bottom = item->fBounds.bottom + 1.0f;
|
||||||
item->fBounds.bottom = item->fBounds.top + iHeight + fPad.top + fPad.bottom;
|
}
|
||||||
|
|
||||||
frame.right = max_c(frame.right, iWidth + fPad.left + fPad.right);
|
for (int32 i = 0; i < fItems.CountItems(); i++)
|
||||||
frame.bottom = item->fBounds.bottom + 1.0f;
|
ItemAt(i)->fBounds.right = frame.right;
|
||||||
|
|
||||||
|
frame.right = (float)ceil(frame.right) + 2.0f;
|
||||||
|
frame.bottom += 1.0f;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < fItems.CountItems(); i++)
|
|
||||||
ItemAt(i)->fBounds.right = frame.right;
|
|
||||||
|
|
||||||
frame.right = (float)ceil(frame.right) + 2.0f;
|
|
||||||
frame.bottom += 1.0f;
|
|
||||||
|
|
||||||
} else if (fLayout == B_ITEMS_IN_ROW) {
|
case B_ITEMS_IN_ROW:
|
||||||
font_height fh;
|
{
|
||||||
GetFontHeight(&fh);
|
font_height fh;
|
||||||
frame = BRect(0.0f, 0.0f, 0.0f,
|
GetFontHeight(&fh);
|
||||||
(float)ceil(fh.ascent) + (float)ceil(fh.descent) + fPad.top + fPad.bottom);
|
frame = BRect(0.0f, 0.0f, 0.0f,
|
||||||
|
(float)ceil(fh.ascent) + (float)ceil(fh.descent) + fPad.top + fPad.bottom);
|
||||||
|
|
||||||
for (int i = 0; i < fItems.CountItems(); i++) {
|
for (int32 i = 0; i < fItems.CountItems(); i++) {
|
||||||
item = static_cast<BMenuItem *>(fItems.ItemAt(i));
|
item = static_cast<BMenuItem *>(fItems.ItemAt(i));
|
||||||
|
item->GetContentSize(&iWidth, &iHeight);
|
||||||
item->GetContentSize(&iWidth, &iHeight);
|
|
||||||
|
|
||||||
item->fBounds.left = frame.right;
|
item->fBounds.left = frame.right;
|
||||||
item->fBounds.top = 0.0f;
|
item->fBounds.top = 0.0f;
|
||||||
item->fBounds.right = item->fBounds.left + iWidth + fPad.left + fPad.right;
|
item->fBounds.right = item->fBounds.left + iWidth + fPad.left + fPad.right;
|
||||||
|
|
||||||
frame.right = item->fBounds.right + 1.0f;
|
frame.right = item->fBounds.right + 1.0f;
|
||||||
frame.bottom = max_c(frame.bottom, iHeight + fPad.top + fPad.bottom);
|
frame.bottom = max_c(frame.bottom, iHeight + fPad.top + fPad.bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < fItems.CountItems(); i++)
|
||||||
|
ItemAt(i)->fBounds.bottom = frame.bottom;
|
||||||
|
|
||||||
|
frame.right = (float)ceil(frame.right) + 8.0f;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < fItems.CountItems(); i++)
|
case B_ITEMS_IN_MATRIX:
|
||||||
ItemAt(i)->fBounds.bottom = frame.bottom;
|
{
|
||||||
|
printf("BMenu: B_ITEMS_IN_MATRIX not yet implemented\n");
|
||||||
frame.right = (float)ceil(frame.right) + 8.0f;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ResizingMode() & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT) {
|
if ((ResizingMode() & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT) {
|
||||||
if (Parent())
|
if (Parent())
|
||||||
*width = Parent()->Frame().Width() + 1.0f;
|
*width = Parent()->Frame().Width() + 1.0f;
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user