Fixed button size and placement issues with the B_WIDTH_FROM_WIDEST mode, refactored code using OpenTracker style.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11137 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+150
-187
@@ -449,198 +449,161 @@ void BAlert::_ReservedAlert3()
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void BAlert::InitObject(const char* text, const char* button0,
|
float width_from_label(BButton *button)
|
||||||
const char* button1, const char* button2,
|
{
|
||||||
button_width width, button_spacing spacing,
|
// BButton::GetPreferredSize() does not return the minimum width
|
||||||
alert_type type)
|
// required to fit the label. Thus, the width is computed here.
|
||||||
|
return button->StringWidth(button->Label()) + 20.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
BAlert::InitObject(const char* text, const char* button0, const char* button1,
|
||||||
|
const char* button2, button_width width, button_spacing spacing,
|
||||||
|
alert_type type)
|
||||||
{
|
{
|
||||||
BAutolock Autolock(this);
|
BAutolock Autolock(this);
|
||||||
if (Autolock.IsLocked())
|
if (!Autolock.IsLocked())
|
||||||
{
|
// Bail out if a lock can't be acquired
|
||||||
fInvoker = NULL;
|
return;
|
||||||
fAlertSem = -1;
|
|
||||||
fAlertVal = -1;
|
|
||||||
fButtons[0] = fButtons[1] = fButtons[2] = NULL;
|
|
||||||
fTextView = NULL;
|
|
||||||
fKeys[0] = fKeys[1] = fKeys[2] = 0;
|
|
||||||
fMsgType = type;
|
|
||||||
fButtonWidth = width;
|
|
||||||
|
|
||||||
// Set up the "_master_" view
|
|
||||||
TAlertView* MasterView = new TAlertView(Bounds());
|
|
||||||
AddChild(MasterView);
|
|
||||||
MasterView->SetBitmap(InitIcon());
|
|
||||||
|
|
||||||
// Set up the buttons
|
|
||||||
int buttonCount = 0;
|
|
||||||
|
|
||||||
// Have to have at least one button
|
|
||||||
if (button0 == NULL)
|
|
||||||
{
|
|
||||||
debugger("BAlert's must have at least one button.");
|
|
||||||
button0 = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
BMessage ProtoMsg(kAlertButtonMsg);
|
|
||||||
ProtoMsg.AddInt32("which", 0);
|
|
||||||
fButtons[0] = new BButton(BRect(0, 0, 0, 0), "_b0_", button0,
|
|
||||||
new BMessage(ProtoMsg),
|
|
||||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
|
||||||
++buttonCount;
|
|
||||||
|
|
||||||
if (button1)
|
|
||||||
{
|
|
||||||
ProtoMsg.ReplaceInt32("which", 1);
|
|
||||||
fButtons[buttonCount] = new BButton(BRect(0, 0, 0, 0), "_b1_", button1,
|
|
||||||
new BMessage(ProtoMsg),
|
|
||||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
|
||||||
++buttonCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button2)
|
|
||||||
{
|
|
||||||
ProtoMsg.ReplaceInt32("which", 2);
|
|
||||||
fButtons[buttonCount] = new BButton(BRect(0, 0, 0, 0), "_b2_", button2,
|
|
||||||
new BMessage(ProtoMsg),
|
|
||||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
|
||||||
++buttonCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetDefaultButton(fButtons[buttonCount - 1]);
|
|
||||||
|
|
||||||
float buttonWidth = 0;
|
|
||||||
float buttonHeight = 0;
|
|
||||||
for (int i = 0; i < buttonCount; ++i)
|
|
||||||
{
|
|
||||||
float temp;
|
|
||||||
fButtons[i]->GetPreferredSize(&temp, &buttonHeight);
|
|
||||||
buttonWidth = max(buttonWidth, temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add first, because the buttons will ResizeToPreferred()
|
|
||||||
// in AttachedToWindow()
|
|
||||||
for (int i = 0; i < buttonCount; ++i)
|
|
||||||
{
|
|
||||||
MasterView->AddChild(fButtons[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = buttonCount - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
switch (fButtonWidth)
|
|
||||||
{
|
|
||||||
case B_WIDTH_FROM_WIDEST:
|
|
||||||
fButtons[i]->ResizeTo(buttonWidth, buttonHeight);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_WIDTH_FROM_LABEL:
|
|
||||||
fButtons[i]->GetPreferredSize(&buttonWidth, &buttonHeight);
|
|
||||||
// GetPreferredSize() does not return the minimum width required to
|
|
||||||
// fit the label. Thus, the width is computed here.
|
|
||||||
buttonWidth = fButtons[i]->StringWidth(fButtons[i]->Label()) + 20.0f;
|
|
||||||
fButtons[i]->ResizeTo(buttonWidth, buttonHeight);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: // B_WIDTH_AS_USUAL
|
|
||||||
fButtons[i]->GetPreferredSize(&buttonWidth, &buttonHeight);
|
|
||||||
buttonWidth = max(buttonWidth, kButtonUsualWidth);
|
|
||||||
fButtons[i]->ResizeTo(buttonWidth, buttonHeight);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
float buttonX;
|
|
||||||
float buttonY;
|
|
||||||
float temp;
|
|
||||||
|
|
||||||
fButtons[i]->GetPreferredSize(&temp, &buttonHeight);
|
|
||||||
buttonY = Bounds().bottom - buttonHeight;
|
|
||||||
|
|
||||||
if (i == buttonCount - 1) // the right-most button
|
|
||||||
{
|
|
||||||
buttonX = Bounds().right - fButtons[i]->Frame().Width() -
|
|
||||||
kButtonRightOffset;
|
|
||||||
buttonY -= kDefButtonBottomOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buttonX = fButtons[i + 1]->Frame().left -
|
|
||||||
fButtons[i]->Frame().Width() -
|
|
||||||
kButtonSpaceOffset;
|
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
if (spacing == B_OFFSET_SPACING)
|
|
||||||
{
|
|
||||||
buttonX -= kButtonOffsetSpaceOffset;
|
|
||||||
}
|
|
||||||
else if (buttonCount == 3)
|
|
||||||
{
|
|
||||||
buttonX -= 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buttonY -= kButtonBottomOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
fButtons[i]->MoveTo(buttonX, buttonY);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Resize the window, if necessary
|
|
||||||
float totalWidth = kButtonRightOffset;
|
|
||||||
totalWidth += fButtons[buttonCount - 1]->Frame().right -
|
|
||||||
fButtons[0]->Frame().left;
|
|
||||||
if (MasterView->Bitmap())
|
|
||||||
{
|
|
||||||
totalWidth += kIconStripeWidth + kWindowIconOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
totalWidth += kWindowMinOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spacing == B_OFFSET_SPACING)
|
|
||||||
{
|
|
||||||
totalWidth = max(kWindowOffsetMinWidth, totalWidth);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
totalWidth += 5;
|
|
||||||
totalWidth = max(kWindowMinWidth, totalWidth);
|
|
||||||
}
|
|
||||||
ResizeTo(totalWidth, Bounds().Height());
|
|
||||||
|
|
||||||
// Set up the text view
|
|
||||||
BRect TextViewRect(kTextLeftOffset, kTextTopOffset,
|
|
||||||
Bounds().right - kTextRightOffset,
|
|
||||||
Bounds().bottom - kTextBottomOffset);
|
|
||||||
if (MasterView->Bitmap())
|
|
||||||
{
|
|
||||||
TextViewRect.left = kTextIconOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
fTextView = new BTextView(TextViewRect, "_tv_",
|
|
||||||
TextViewRect,
|
|
||||||
B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
|
|
||||||
MasterView->AddChild(fTextView);
|
|
||||||
|
|
||||||
fTextView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
fInvoker = NULL;
|
||||||
fTextView->SetText(text, strlen(text));
|
fAlertSem = -1;
|
||||||
fTextView->MakeEditable(false);
|
fAlertVal = -1;
|
||||||
fTextView->MakeSelectable(false);
|
fButtons[0] = fButtons[1] = fButtons[2] = NULL;
|
||||||
fTextView->SetWordWrap(true);
|
fTextView = NULL;
|
||||||
|
fKeys[0] = fKeys[1] = fKeys[2] = 0;
|
||||||
// Now resize the window vertically so that all the text is visible
|
fMsgType = type;
|
||||||
float textHeight = fTextView->TextHeight(0, fTextView->CountLines());
|
fButtonWidth = width;
|
||||||
TextViewRect.OffsetTo(0, 0);
|
|
||||||
textHeight -= TextViewRect.Height();
|
|
||||||
ResizeBy(0, textHeight);
|
|
||||||
fTextView->ResizeBy(0, textHeight);
|
|
||||||
TextViewRect.bottom += textHeight;
|
|
||||||
fTextView->SetTextRect(TextViewRect);
|
|
||||||
|
|
||||||
AddCommonFilter(new _BAlertFilter_(this));
|
|
||||||
|
|
||||||
MoveTo(AlertPosition(Frame().Width(), Frame().Height()));
|
// Set up the "_master_" view
|
||||||
|
TAlertView* MasterView = new TAlertView(Bounds());
|
||||||
|
AddChild(MasterView);
|
||||||
|
MasterView->SetBitmap(InitIcon());
|
||||||
|
|
||||||
|
// Must have at least one button
|
||||||
|
if (button0 == NULL) {
|
||||||
|
debugger("BAlert's must have at least one button.");
|
||||||
|
button0 = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BMessage ProtoMsg(kAlertButtonMsg);
|
||||||
|
ProtoMsg.AddInt32("which", 0);
|
||||||
|
// Set up the buttons
|
||||||
|
int buttonCount = 0;
|
||||||
|
fButtons[buttonCount] = new BButton(BRect(0, 0, 0, 0), "_b0_", button0,
|
||||||
|
new BMessage(ProtoMsg), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||||
|
MasterView->AddChild(fButtons[buttonCount]);
|
||||||
|
++buttonCount;
|
||||||
|
|
||||||
|
if (button1) {
|
||||||
|
ProtoMsg.ReplaceInt32("which", 1);
|
||||||
|
fButtons[buttonCount] = new BButton(BRect(0, 0, 0, 0), "_b1_", button1,
|
||||||
|
new BMessage(ProtoMsg), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||||
|
|
||||||
|
MasterView->AddChild(fButtons[buttonCount]);
|
||||||
|
++buttonCount;
|
||||||
|
}
|
||||||
|
if (button2) {
|
||||||
|
ProtoMsg.ReplaceInt32("which", 2);
|
||||||
|
fButtons[buttonCount] = new BButton(BRect(0, 0, 0, 0), "_b2_", button2,
|
||||||
|
new BMessage(ProtoMsg), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||||
|
|
||||||
|
MasterView->AddChild(fButtons[buttonCount]);
|
||||||
|
++buttonCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDefaultButton(fButtons[buttonCount - 1]);
|
||||||
|
|
||||||
|
// Find the widest button only if the widest value needs to be known.
|
||||||
|
float maxWidth = 0;
|
||||||
|
if (fButtonWidth == B_WIDTH_FROM_WIDEST) {
|
||||||
|
for (int i = 0; i < buttonCount; ++i) {
|
||||||
|
float temp = width_from_label(fButtons[i]);
|
||||||
|
maxWidth = max(maxWidth, temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = buttonCount - 1; i >= 0; --i) {
|
||||||
|
// Determine the button's size
|
||||||
|
float buttonWidth = 0, buttonHeight = 0;
|
||||||
|
fButtons[i]->GetPreferredSize(&buttonWidth, &buttonHeight);
|
||||||
|
if (fButtonWidth == B_WIDTH_FROM_WIDEST)
|
||||||
|
buttonWidth = maxWidth;
|
||||||
|
else if (fButtonWidth == B_WIDTH_FROM_LABEL)
|
||||||
|
buttonWidth = width_from_label(fButtons[i]);
|
||||||
|
else // B_WIDTH_AS_USUAL
|
||||||
|
buttonWidth = max(buttonWidth, kButtonUsualWidth);
|
||||||
|
fButtons[i]->ResizeTo(buttonWidth, buttonHeight);
|
||||||
|
|
||||||
|
// Determine the button's placement
|
||||||
|
float buttonX, buttonY;
|
||||||
|
buttonY = Bounds().bottom - buttonHeight;
|
||||||
|
if (i == buttonCount - 1) {
|
||||||
|
// The right-most button
|
||||||
|
buttonX = Bounds().right - fButtons[i]->Frame().Width() -
|
||||||
|
kButtonRightOffset;
|
||||||
|
buttonY -= kDefButtonBottomOffset;
|
||||||
|
} else {
|
||||||
|
buttonX = fButtons[i + 1]->Frame().left -
|
||||||
|
fButtons[i]->Frame().Width() - kButtonSpaceOffset;
|
||||||
|
buttonY -= kButtonBottomOffset;
|
||||||
|
if (i == 0) {
|
||||||
|
if (spacing == B_OFFSET_SPACING)
|
||||||
|
buttonX -= kButtonOffsetSpaceOffset;
|
||||||
|
else if (buttonCount == 3)
|
||||||
|
buttonX -= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fButtons[i]->MoveTo(buttonX, buttonY);
|
||||||
|
} // for (int i = buttonCount - 1; i >= 0; --i)
|
||||||
|
|
||||||
|
// Adjust the window's width, if necessary
|
||||||
|
float totalWidth = kButtonRightOffset;
|
||||||
|
totalWidth += fButtons[buttonCount - 1]->Frame().right -
|
||||||
|
fButtons[0]->Frame().left;
|
||||||
|
if (MasterView->Bitmap())
|
||||||
|
totalWidth += kIconStripeWidth + kWindowIconOffset;
|
||||||
|
else
|
||||||
|
totalWidth += kWindowMinOffset;
|
||||||
|
|
||||||
|
if (spacing == B_OFFSET_SPACING)
|
||||||
|
totalWidth = max(kWindowOffsetMinWidth, totalWidth);
|
||||||
|
else {
|
||||||
|
totalWidth += 5;
|
||||||
|
totalWidth = max(kWindowMinWidth, totalWidth);
|
||||||
|
}
|
||||||
|
ResizeTo(totalWidth, Bounds().Height());
|
||||||
|
|
||||||
|
// Set up the text view
|
||||||
|
BRect TextViewRect(kTextLeftOffset, kTextTopOffset,
|
||||||
|
Bounds().right - kTextRightOffset,
|
||||||
|
Bounds().bottom - kTextBottomOffset);
|
||||||
|
if (MasterView->Bitmap())
|
||||||
|
TextViewRect.left = kTextIconOffset;
|
||||||
|
|
||||||
|
fTextView = new BTextView(TextViewRect, "_tv_", TextViewRect,
|
||||||
|
B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW);
|
||||||
|
MasterView->AddChild(fTextView);
|
||||||
|
|
||||||
|
fTextView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
fTextView->SetText(text, strlen(text));
|
||||||
|
fTextView->MakeEditable(false);
|
||||||
|
fTextView->MakeSelectable(false);
|
||||||
|
fTextView->SetWordWrap(true);
|
||||||
|
|
||||||
|
// Now resize the window vertically so that all the text is visible
|
||||||
|
float textHeight = fTextView->TextHeight(0, fTextView->CountLines());
|
||||||
|
TextViewRect.OffsetTo(0, 0);
|
||||||
|
textHeight -= TextViewRect.Height();
|
||||||
|
ResizeBy(0, textHeight);
|
||||||
|
fTextView->ResizeBy(0, textHeight);
|
||||||
|
TextViewRect.bottom += textHeight;
|
||||||
|
fTextView->SetTextRect(TextViewRect);
|
||||||
|
|
||||||
|
AddCommonFilter(new _BAlertFilter_(this));
|
||||||
|
|
||||||
|
MoveTo(AlertPosition(Frame().Width(), Frame().Height()));
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
BBitmap* BAlert::InitIcon()
|
BBitmap* BAlert::InitIcon()
|
||||||
|
|||||||
Reference in New Issue
Block a user