Draw truncated menu label in BMCPrivate, fixes #9735
...instead of in BMenuItem and remove the truncation code from BMenuItem. The label truncation code cannot work in BMenuItem because the super menu helpfully resizes itself to fit the menu item. So, instead we do the label truncation in BMCPrivate making sure that BMenuItem there can't expand the BMCMenuBar because we set the width to fMenuField->_MenuBarWidth() explicity. Note that this only truncates the label in BMCMenuField, i.e. the label inside the menufield, it does nothing to the labels of the menu items in the attached BMenu or BPopUpMenu which is exactly what we want.
This commit is contained in:
parent
1afff67178
commit
c333966291
@ -62,6 +62,8 @@ private:
|
||||
|
||||
void _Init(bool setMaxContentWidth);
|
||||
|
||||
void _DrawItems(BRect updateRect);
|
||||
|
||||
BMenuField* fMenuField;
|
||||
bool fFixedSize;
|
||||
BMessageRunner* fRunner;
|
||||
|
@ -12,16 +12,21 @@
|
||||
#include <BMCPrivate.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ControlLook.h>
|
||||
#include <Font.h>
|
||||
#include <LayoutUtils.h>
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Message.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <Region.h>
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <MenuPrivate.h>
|
||||
|
||||
|
||||
static const float kPopUpIndicatorWidth = 10.0f;
|
||||
static const float kMarginWidth = 3.0f;
|
||||
@ -59,6 +64,7 @@ _BMCFilter_::Filter(BMessage* message, BHandler** handler)
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
using BPrivate::MenuPrivate;
|
||||
|
||||
_BMCMenuBar_::_BMCMenuBar_(BRect frame, bool fixedSize, BMenuField* menuField)
|
||||
:
|
||||
@ -331,3 +337,56 @@ _BMCMenuBar_::_Init(bool setMaxContentWidth)
|
||||
SetMaxContentWidth(fPreviousWidth - (left + right));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_BMCMenuBar_::_DrawItems(BRect updateRect)
|
||||
{
|
||||
MenuPrivate menuPrivate(this);
|
||||
menuPrivate.CacheFontInfo();
|
||||
const BRect& padding = menuPrivate.Padding();
|
||||
float frameWidth = fMenuField->_MenuBarWidth()
|
||||
- (padding.left + padding.right);
|
||||
int32 itemCount = CountItems();
|
||||
|
||||
for (int32 i = 0; i < itemCount; i++) {
|
||||
BMenuItem* item = ItemAt(i);
|
||||
if (item == NULL)
|
||||
continue;
|
||||
|
||||
if (!item->Frame().Intersects(updateRect))
|
||||
continue;
|
||||
|
||||
const char* label = item->Label();
|
||||
if (label == NULL)
|
||||
continue;
|
||||
|
||||
BPoint contentLocation(item->Frame().left + padding.left,
|
||||
item->Frame().top + padding.top);
|
||||
MovePenTo(contentLocation);
|
||||
MovePenBy(0, menuPrivate.Ascent());
|
||||
|
||||
if (item->IsEnabled())
|
||||
SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
|
||||
else
|
||||
SetHighColor(tint_color(LowColor(), B_DISABLED_LABEL_TINT));
|
||||
|
||||
SetDrawingMode(B_OP_OVER);
|
||||
|
||||
if (frameWidth >= StringWidth(label))
|
||||
DrawString(label);
|
||||
else {
|
||||
// truncate label to fit
|
||||
char* truncatedLabel = new char[strlen(label) + 4];
|
||||
BFont font;
|
||||
GetFont(&font);
|
||||
BString labelString(label);
|
||||
font.TruncateString(&labelString, B_TRUNCATE_MIDDLE, frameWidth);
|
||||
labelString.CopyInto(truncatedLabel, 0, labelString.Length());
|
||||
truncatedLabel[labelString.Length()] = '\0';
|
||||
DrawString(truncatedLabel);
|
||||
delete[] truncatedLabel;
|
||||
}
|
||||
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
}
|
||||
}
|
||||
|
@ -399,28 +399,9 @@ BMenuItem::DrawContent()
|
||||
fSuper->MovePenBy(0, menuPrivate.Ascent());
|
||||
BPoint lineStart = fSuper->PenLocation();
|
||||
|
||||
float labelWidth, labelHeight;
|
||||
GetContentSize(&labelWidth, &labelHeight);
|
||||
|
||||
fSuper->SetDrawingMode(B_OP_OVER);
|
||||
|
||||
float frameWidth = fBounds.Width();
|
||||
if (menuPrivate.State() == MENU_STATE_CLOSED) {
|
||||
float leftMargin;
|
||||
float rightMargin;
|
||||
menuPrivate.GetItemMargins(&leftMargin, NULL, &rightMargin, NULL);
|
||||
frameWidth = fSuper->Frame().Width() - rightMargin + leftMargin;
|
||||
}
|
||||
|
||||
if (frameWidth >= labelWidth)
|
||||
fSuper->DrawString(fLabel);
|
||||
else {
|
||||
// truncate the label to fit
|
||||
char* truncatedLabel = new char[strlen(fLabel) + 4];
|
||||
TruncateLabel(frameWidth, truncatedLabel);
|
||||
fSuper->DrawString(truncatedLabel);
|
||||
delete[] truncatedLabel;
|
||||
}
|
||||
fSuper->DrawString(fLabel);
|
||||
|
||||
if (fSuper->AreTriggersEnabled() && fTriggerIndex != -1) {
|
||||
float escapements[fTriggerIndex + 1];
|
||||
|
Loading…
Reference in New Issue
Block a user