diff --git a/headers/os/interface/Alert.h b/headers/os/interface/Alert.h index 13758a6f07..b27873df58 100644 --- a/headers/os/interface/Alert.h +++ b/headers/os/interface/Alert.h @@ -1,52 +1,24 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Alert.h -// Author: Erik Jaesler (erik@cgsoftware.com) -// Description: BAlert displays a modal alert window. -//------------------------------------------------------------------------------ - +/* + * Copyright 2001-2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Erik Jaesler (erik@cgsoftware.com) + */ #ifndef _ALERT_H #define _ALERT_H -// Standard Includes ----------------------------------------------------------- -// System Includes ------------------------------------------------------------- #include #include -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- class BBitmap; class BButton; class BInvoker; class BTextView; -// enum for flavors of alert --------------------------------------------------- +// enum for flavors of alert enum alert_type { B_EMPTY_ALERT = 0, B_INFO_ALERT, @@ -55,101 +27,81 @@ enum alert_type { B_STOP_ALERT }; - enum button_spacing { B_EVEN_SPACING = 0, B_OFFSET_SPACING }; -// BAlert class ---------------------------------------------------------------- -class BAlert : public BWindow -{ -public: - BAlert( const char *title, - const char *text, - const char *button1, - const char *button2 = NULL, - const char *button3 = NULL, - button_width width = B_WIDTH_AS_USUAL, - alert_type type = B_INFO_ALERT); - BAlert( const char *title, - const char *text, - const char *button1, - const char *button2, - const char *button3, - button_width width, - button_spacing spacing, - alert_type type = B_INFO_ALERT); -virtual ~BAlert(); - -// Archiving - BAlert(BMessage *data); -static BArchivable *Instantiate(BMessage *data); -virtual status_t Archive(BMessage *data, bool deep = true) const; - -// BAlert guts - void SetShortcut(int32 button_index, char key); - char Shortcut(int32 button_index) const; +class BAlert : public BWindow { + public: + BAlert(const char* title, const char* text, + const char* button1, const char* button2 = NULL, + const char* button3 = NULL, + button_width width = B_WIDTH_AS_USUAL, + alert_type type = B_INFO_ALERT); + BAlert(const char *title, const char *text, + const char *button1, const char *button2, + const char *button3, button_width width, + button_spacing spacing, + alert_type type = B_INFO_ALERT); + virtual ~BAlert(); - int32 Go(); - status_t Go(BInvoker *invoker); + // Archiving + BAlert(BMessage *data); + static BArchivable *Instantiate(BMessage *data); + virtual status_t Archive(BMessage *data, bool deep = true) const; -virtual void MessageReceived(BMessage *an_event); -virtual void FrameResized(float new_width, float new_height); - BButton *ButtonAt(int32 index) const; - BTextView *TextView() const; + // BAlert guts + void SetShortcut(int32 button_index, char key); + char Shortcut(int32 button_index) const; -virtual BHandler *ResolveSpecifier(BMessage *msg, - int32 index, - BMessage *specifier, - int32 form, - const char *property); -virtual status_t GetSupportedSuites(BMessage *data); + int32 Go(); + status_t Go(BInvoker *invoker); -virtual void DispatchMessage(BMessage *msg, BHandler *handler); -virtual void Quit(); -virtual bool QuitRequested(); + virtual void MessageReceived(BMessage *an_event); + virtual void FrameResized(float new_width, float new_height); + BButton* ButtonAt(int32 index) const; + BTextView* TextView() const; -static BPoint AlertPosition(float width, float height); + virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, + BMessage* specifier, int32 form, + const char* property); + virtual status_t GetSupportedSuites(BMessage *data); -// Private or reserved --------------------------------------------------------- -virtual status_t Perform(perform_code d, void *arg); + virtual void DispatchMessage(BMessage* message, BHandler* handler); + virtual void Quit(); + virtual bool QuitRequested(); -private: -friend class _BAlertFilter_; + static BPoint AlertPosition(float width, float height); -virtual void _ReservedAlert1(); -virtual void _ReservedAlert2(); -virtual void _ReservedAlert3(); + virtual status_t Perform(perform_code d, void *arg); - void InitObject(const char *text, - const char *button1, - const char *button2 = NULL, - const char *button3 = NULL, - button_width width = B_WIDTH_AS_USUAL, - button_spacing spacing = B_EVEN_SPACING, - alert_type type = B_INFO_ALERT); - BBitmap *InitIcon(); + private: + friend class _BAlertFilter_; - sem_id fAlertSem; - int32 fAlertVal; - BButton *fButtons[3]; - BTextView *fTextView; - char fKeys[3]; - alert_type fMsgType; - button_width fButtonWidth; - BInvoker *fInvoker; - uint32 _reserved[4]; + virtual void _ReservedAlert1(); + virtual void _ReservedAlert2(); + virtual void _ReservedAlert3(); + + void _InitObject(const char* text, const char* button1, + const char* button2 = NULL, + const char* button3 = NULL, + button_width width = B_WIDTH_AS_USUAL, + button_spacing spacing = B_EVEN_SPACING, + alert_type type = B_INFO_ALERT); + BBitmap* _InitIcon(); + BButton* _CreateButton(int32 which, const char* label); + + sem_id fAlertSem; + int32 fAlertValue; + BButton* fButtons[3]; + BTextView* fTextView; + char fKeys[3]; + alert_type fMsgType; + button_width fButtonWidth; + BInvoker* fInvoker; + uint32 _reserved[4]; }; -//------------------------------------------------------------------------------ #endif // _ALERT_H - -/* - * $Log $ - * - * $Id $ - * - */ - diff --git a/src/kits/interface/Alert.cpp b/src/kits/interface/Alert.cpp index d8fbe2badf..5a954f9db3 100644 --- a/src/kits/interface/Alert.cpp +++ b/src/kits/interface/Alert.cpp @@ -1,91 +1,69 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Alert.cpp -// Author: Erik Jaesler (erik@cgsoftware.com) -// Description: BAlert displays a modal alert window. -//------------------------------------------------------------------------------ +/* + * Copyright 2001-2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Erik Jaesler (erik@cgsoftware.com) + * Axel Dörfler, axeld@pinc-software.de + */ -// Standard Includes ----------------------------------------------------------- -#include +//! BAlert displays a modal alert window. -// System Includes ------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include #include #include #include #include - -#include -#include -#include +#include +#include #include #include #include -#include -#include -#include -#include -#include - -#include +#include +#include +#include //#define DEBUG_ALERT #ifdef DEBUG_ALERT -#define FTRACE(x) fprintf(x) +# define FTRACE(x) fprintf(x) #else -#define FTRACE(x) /* nothing */ +# define FTRACE(x) /* nothing */ #endif // Default size of the Alert window. #define DEFAULT_RECT BRect(0, 0, 310, 75) #define max(LHS, RHS) ((LHS) > (RHS) ? (LHS) : (RHS)) -// Globals --------------------------------------------------------------------- static const unsigned int kAlertButtonMsg = 'ALTB'; static const int kSemTimeOut = 50000; -static const int kButtonBottomOffset = 9; -static const int kDefButtonBottomOffset = 6; -static const int kButtonRightOffset = 6; -static const int kButtonSpaceOffset = 6; -static const int kButtonOffsetSpaceOffset = 26; -static const int kButtonMinOffsetSpaceOffset = kButtonOffsetSpaceOffset / 2; -static const int kButtonLeftOffset = 62; +static const int kLeftOffset = 10; +static const int kTopOffset = 6; +static const int kBottomOffset = 8; +static const int kRightOffset = 8; + +static const int kButtonSpacing = 6; +static const int kButtonOffsetSpacing = 62; static const int kButtonUsualWidth = 75; static const int kWindowIconOffset = 27; -static const int kWindowMinWidth = 310; static const int kWindowMinOffset = 12; +static const int kWindowMinWidth = 310; static const int kWindowOffsetMinWidth = 335; static const int kIconStripeWidth = 30; -static const int kTextLeftOffset = 10; static const int kTextIconOffset = kWindowIconOffset + kIconStripeWidth - 2; -static const int kTextTopOffset = 6; -static const int kTextRightOffset = 10; -static const int kTextBottomOffset = 45; +static const int kTextButtonOffset = 10; + -//------------------------------------------------------------------------------ class TAlertView : public BView { public: TAlertView(BRect frame); @@ -108,11 +86,6 @@ class TAlertView : public BView { BBitmap* fIconBitmap; }; -//------------------------------------------------------------------------------ -// I'm making a guess based on the name and TextEntryAlert's implementation that -// this is a BMessageFilter. I'm not sure, but I think I actually prefer how -// TextEntryAlert does it, but there are clearly no message filtering functions -// on BAlert so here we go. class _BAlertFilter_ : public BMessageFilter { public: _BAlertFilter_(BAlert* Alert); @@ -125,35 +98,26 @@ class _BAlertFilter_ : public BMessageFilter { }; -static float -width_from_label(BButton *button) -{ - // BButton::GetPreferredSize() does not return the minimum width - // required to fit the label. Thus, the width is computed here. - return button->StringWidth(button->Label()) + 20.0f; -} - - // #pragma mark - BAlert BAlert::BAlert(const char *title, const char *text, const char *button1, - const char *button2, const char *button3, button_width width, - alert_type type) + const char *button2, const char *button3, button_width width, + alert_type type) : BWindow(DEFAULT_RECT, title, B_MODAL_WINDOW, B_NOT_CLOSABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS) { - InitObject(text, button1, button2, button3, width, B_EVEN_SPACING, type); + _InitObject(text, button1, button2, button3, width, B_EVEN_SPACING, type); } BAlert::BAlert(const char *title, const char *text, const char *button1, - const char *button2, const char *button3, button_width width, - button_spacing spacing, alert_type type) + const char *button2, const char *button3, button_width width, + button_spacing spacing, alert_type type) : BWindow(DEFAULT_RECT, title, B_MODAL_WINDOW, B_NOT_CLOSABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS) { - InitObject(text, button1, button2, button3, width, spacing, type); + _InitObject(text, button1, button2, button3, width, spacing, type); } @@ -170,7 +134,7 @@ BAlert::BAlert(BMessage* data) { fInvoker = NULL; fAlertSem = -1; - fAlertVal = -1; + fAlertValue = -1; fTextView = (BTextView*)FindView("_tv_"); @@ -185,9 +149,9 @@ BAlert::BAlert(BMessage* data) else if (fButtons[0]) SetDefaultButton(fButtons[0]); - TAlertView* master = (TAlertView*)FindView("_master_"); - if (master) - master->SetBitmap(InitIcon()); + TAlertView* view = (TAlertView*)FindView("_master_"); + if (view) + view->SetBitmap(_InitIcon()); // Get keys char key; @@ -309,7 +273,7 @@ BAlert::Go() } // Have to cache the value since we delete on Quit() - int32 value = fAlertVal; + int32 value = fAlertValue; if (Lock()) Quit(); @@ -345,7 +309,7 @@ BAlert::MessageReceived(BMessage* msg) PostMessage(B_QUIT_REQUESTED); } else { // Created semaphore means were running synchronously - fAlertVal = which; + fAlertValue = which; // TextAlertVar does release_sem() below, and then sets the // member var. That doesn't make much sense to me, since we @@ -455,23 +419,23 @@ void BAlert::_ReservedAlert3() {} void -BAlert::InitObject(const char* text, const char* button0, const char* button1, - const char* button2, button_width width, button_spacing spacing, +BAlert::_InitObject(const char* text, const char* button0, const char* button1, + const char* button2, button_width buttonWidth, button_spacing spacing, alert_type type) { fInvoker = NULL; fAlertSem = -1; - fAlertVal = -1; + fAlertValue = -1; fButtons[0] = fButtons[1] = fButtons[2] = NULL; fTextView = NULL; fKeys[0] = fKeys[1] = fKeys[2] = 0; fMsgType = type; - fButtonWidth = width; + fButtonWidth = buttonWidth; // Set up the "_master_" view - TAlertView* masterView = new TAlertView(Bounds()); - AddChild(masterView); - masterView->SetBitmap(InitIcon()); + TAlertView* view = new TAlertView(Bounds()); + AddChild(view); + view->SetBitmap(_InitIcon()); // Must have at least one button if (button0 == NULL) { @@ -479,132 +443,89 @@ BAlert::InitObject(const char* text, const char* button0, const char* button1, 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); + int32 buttonCount = 1; + view->AddChild(fButtons[0] = _CreateButton(0, button0)); - 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; + if (button1 != NULL) { + view->AddChild(fButtons[1] = _CreateButton(1, button1)); + buttonCount++; } - SetDefaultButton(fButtons[buttonCount - 1]); + if (button2 != NULL) { + view->AddChild(fButtons[2] = _CreateButton(2, button2)); + buttonCount++; + } // 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); + float maxWidth = 0; + for (int i = 0; i < buttonCount; i++) { + float width = fButtons[i]->Bounds().Width(); + if (width > maxWidth) + maxWidth = width; + } + + // resize buttons + for (int i = 0; i < buttonCount; i++) { + fButtons[i]->ResizeTo(maxWidth, fButtons[i]->Bounds().Height()); } } - 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); + float defaultButtonFrameWidth = -fButtons[buttonCount - 1]->Bounds().Width() / 2.0f; + SetDefaultButton(fButtons[buttonCount - 1]); + defaultButtonFrameWidth += fButtons[buttonCount - 1]->Bounds().Width() / 2.0f; - // 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) { - if (buttonCount == 3) - buttonX -= kButtonOffsetSpaceOffset; - else { - // If there are two buttons, the left wall of - // button0 needs to line up with the left wall - // of the TextView. - buttonX = (masterView->Bitmap()) ? - kTextIconOffset : kTextLeftOffset; - if (fButtons[i + 1]->Frame().left - - (buttonX + fButtons[i]->Frame().Width()) < - kButtonMinOffsetSpaceOffset) { - // Recompute buttonX using min offset space - // if using the current buttonX would not - // provide enough space or cause an overlap. - buttonX = fButtons[i + 1]->Frame().left - - fButtons[i]->Frame().Width() - - kButtonMinOffsetSpaceOffset; - } - } - } else if (buttonCount == 3) - buttonX -= 3; - } - } - fButtons[i]->MoveTo(buttonX, buttonY); - } // for (int i = buttonCount - 1; i >= 0; --i) + // Layout buttons + + float fontFactor = be_plain_font->Size() / 11.0f; + + for (int i = buttonCount - 1; i >= 0; --i) { + float x = -fButtons[i]->Bounds().Width(); + if (i + 1 == buttonCount) + x += Bounds().right - kRightOffset + defaultButtonFrameWidth; + else + x += fButtons[i + 1]->Frame().left - kButtonSpacing; + + if (buttonCount > 1 && i == 0 && spacing == B_OFFSET_SPACING) + x -= kButtonOffsetSpacing * fontFactor; + + fButtons[i]->MoveTo(x, fButtons[i]->Frame().top); + } // Adjust the window's width, if necessary - float totalWidth = kButtonRightOffset; - totalWidth += fButtons[buttonCount - 1]->Frame().right - - fButtons[0]->Frame().left; - if (masterView->Bitmap()) + + float totalWidth = kRightOffset + fButtons[buttonCount - 1]->Frame().right + - defaultButtonFrameWidth - fButtons[0]->Frame().left; + if (view->Bitmap()) totalWidth += kIconStripeWidth + kWindowIconOffset; else totalWidth += kWindowMinOffset; - if (spacing == B_OFFSET_SPACING) { - totalWidth -= 2; - if (buttonCount == 3) - totalWidth = max(kWindowOffsetMinWidth, totalWidth); - else - totalWidth = max(kWindowMinWidth, totalWidth); - } else { - totalWidth += 5; - totalWidth = max(kWindowMinWidth, totalWidth); - } - ResizeTo(totalWidth, Bounds().Height()); + float width = (spacing == B_OFFSET_SPACING + ? kWindowOffsetMinWidth : kWindowMinWidth) * fontFactor; + + ResizeTo(max_c(totalWidth, width), Bounds().Height()); // Set up the text view - BRect textViewRect(kTextLeftOffset, kTextTopOffset, - Bounds().right - kTextRightOffset, - Bounds().bottom - kTextBottomOffset); - if (masterView->Bitmap()) + + BRect textViewRect(kLeftOffset, kTopOffset, + Bounds().right - kRightOffset, + fButtons[0]->Frame().top - kTextButtonOffset); + if (view->Bitmap()) textViewRect.left = kTextIconOffset; - fTextView = new BTextView(textViewRect, "_tv_", textViewRect, + fTextView = new BTextView(textViewRect, "_tv_", + textViewRect.OffsetByCopy(B_ORIGIN), 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); + view->AddChild(fTextView); // Now resize the TextView vertically so that all the text is visible float textHeight = fTextView->TextHeight(0, fTextView->CountLines()); @@ -622,7 +543,7 @@ BAlert::InitObject(const char* text, const char* button0, const char* button1, BBitmap* -BAlert::InitIcon() +BAlert::_InitIcon() { // After a bit of a search, I found the icons in app_server. =P BBitmap* icon = NULL; @@ -665,8 +586,9 @@ BAlert::InitIcon() if (rawIcon) { // Now build the bitmap - icon = new BBitmap(BRect(0, 0, 31, 31), 0, B_CMAP8); - icon->SetBits(rawIcon, size, 0, B_CMAP8); + icon = new (std::nothrow) BBitmap(BRect(0, 0, 31, 31), 0, B_CMAP8); + if (icon != NULL) + icon->SetBits(rawIcon, size, 0, B_CMAP8); } else { FTRACE((stderr, "BAlert::InitIcon() - Icon resource not found\n")); } @@ -680,7 +602,7 @@ BAlert::InitIcon() FTRACE((stderr, "BAlert::InitIcon() - find_directory failed: %s\n", strerror(status))); } - if (!icon) { + if (icon == NULL) { // If there's no icon, it's an empty alert indeed. fMsgType = B_EMPTY_ALERT; } @@ -689,7 +611,41 @@ BAlert::InitIcon() } -//------------------------------------------------------------------------------ +BButton* +BAlert::_CreateButton(int32 which, const char* label) +{ + BMessage* message = new BMessage(kAlertButtonMsg); + if (message == NULL) + return NULL; + + message->AddInt32("which", which); + + BRect rect; + rect.top = Bounds().bottom - kBottomOffset; + rect.bottom = rect.top; + + char name[32]; + snprintf(name, sizeof(name), "_b%ld_", which); + + BButton* button = new (std::nothrow) BButton(rect, name, label, message, + B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); + if (button == NULL) + return NULL; + + float width, height; + button->GetPreferredSize(&width, &height); + + if (fButtonWidth == B_WIDTH_AS_USUAL) { + float fontFactor = be_plain_font->Size() / 11.0f; + width = max_c(width, kButtonUsualWidth * fontFactor); + } + + button->ResizeTo(width, height); + button->MoveBy(0.0f, -height); + return button; +} + + // #pragma mark - TAlertView