Rewrote BAlert button layout routine. Made it much simpler, and it's now
also font sensitive (really, it wasn't before). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17861 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
60d1530802
commit
9a3c8b14fd
@ -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 <BeBuild.h>
|
||||
#include <Window.h>
|
||||
|
||||
// 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 $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -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 <string.h>
|
||||
//! BAlert displays a modal alert window.
|
||||
|
||||
// System Includes -------------------------------------------------------------
|
||||
#include <Alert.h>
|
||||
#include <Autolock.h>
|
||||
#include <Beep.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Button.h>
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Invoker.h>
|
||||
#include <Looper.h>
|
||||
#include <Message.h>
|
||||
#include <MessageFilter.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Button.h>
|
||||
#include <Path.h>
|
||||
#include <Resources.h>
|
||||
#include <Screen.h>
|
||||
#include <TextView.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <Resources.h>
|
||||
#include <Beep.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//#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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user