You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
414 lines
11 KiB
414 lines
11 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include <vgui/ISurface.h> |
|
#include <KeyValues.h> |
|
#include <vgui/IInput.h> |
|
|
|
#include <vgui_controls/Button.h> |
|
#include <vgui_controls/Controls.h> |
|
#include <vgui_controls/Label.h> |
|
#include <vgui_controls/MessageBox.h> |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
using namespace vgui; |
|
|
|
#ifndef max |
|
#define max(a,b) (((a) > (b)) ? (a) : (b)) |
|
#endif |
|
|
|
vgui::Panel *MessageBox_Factory() |
|
{ |
|
return new MessageBox("MessageBox", "MessageBoxText"); |
|
} |
|
|
|
DECLARE_BUILD_FACTORY_CUSTOM( MessageBox, MessageBox_Factory ); |
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
MessageBox::MessageBox(const char *title, const char *text, Panel *parent) : Frame(parent, NULL, false) |
|
{ |
|
SetTitle(title, true); |
|
m_pMessageLabel = new Label(this, NULL, text); |
|
|
|
Init(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
MessageBox::MessageBox(const wchar_t *wszTitle, const wchar_t *wszText, Panel *parent) : Frame(parent, NULL, false) |
|
{ |
|
SetTitle(wszTitle, true); |
|
m_pMessageLabel = new Label(this, NULL, wszText); |
|
|
|
Init(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor Helper |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::Init() |
|
{ |
|
SetDeleteSelfOnClose(true); |
|
m_pFrameOver = NULL; |
|
m_bShowMessageBoxOverCursor = false; |
|
|
|
SetMenuButtonResponsive(false); |
|
SetMinimizeButtonVisible(false); |
|
SetCloseButtonVisible(false); |
|
SetSizeable(false); |
|
|
|
m_pOkButton = new Button(this, NULL, "#MessageBox_OK"); |
|
m_pOkButton->SetCommand( "OnOk" ); |
|
m_pOkButton->AddActionSignalTarget(this); |
|
|
|
m_pCancelButton = new Button(this, NULL, "#MessageBox_Cancel"); |
|
m_pCancelButton->SetCommand( "OnCancel" ); |
|
m_pCancelButton->AddActionSignalTarget(this); |
|
m_pCancelButton->SetVisible( false ); |
|
|
|
m_OkCommand = m_CancelCommand = NULL; |
|
m_bNoAutoClose = false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Destructor |
|
//----------------------------------------------------------------------------- |
|
MessageBox::~MessageBox() |
|
{ |
|
if ( m_OkCommand ) |
|
{ |
|
m_OkCommand->deleteThis(); |
|
} |
|
if ( m_CancelCommand ) |
|
{ |
|
m_CancelCommand->deleteThis(); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Shows the message box over the cursor |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::ShowMessageBoxOverCursor( bool bEnable ) |
|
{ |
|
m_bShowMessageBoxOverCursor = bEnable; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: size the message label properly |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::OnCommand( const char *pCommand ) |
|
{ |
|
if ( vgui::input()->GetAppModalSurface() == GetVPanel() ) |
|
{ |
|
vgui::input()->ReleaseAppModalSurface(); |
|
} |
|
|
|
if ( !Q_stricmp( pCommand, "OnOk" ) ) |
|
{ |
|
if ( m_OkCommand ) |
|
{ |
|
PostActionSignal(m_OkCommand->MakeCopy()); |
|
} |
|
} |
|
else if ( !Q_stricmp( pCommand, "OnCancel" ) ) |
|
{ |
|
if ( m_CancelCommand ) |
|
{ |
|
PostActionSignal(m_CancelCommand->MakeCopy()); |
|
} |
|
} |
|
|
|
if ( !m_bNoAutoClose ) |
|
{ |
|
OnShutdownRequest(); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: size the message label properly |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::ApplySchemeSettings(IScheme *pScheme) |
|
{ |
|
BaseClass::ApplySchemeSettings(pScheme); |
|
|
|
int wide, tall; |
|
m_pMessageLabel->GetContentSize(wide, tall); |
|
m_pMessageLabel->SetSize(wide, tall); |
|
|
|
int indent = 100; |
|
if (IsProportional()) |
|
{ |
|
indent = scheme()->GetProportionalScaledValueEx(GetScheme(), 100); |
|
} |
|
|
|
wide += indent; |
|
tall += indent; |
|
SetSize(wide, tall); |
|
|
|
if ( m_bShowMessageBoxOverCursor ) |
|
{ |
|
PlaceUnderCursor(); |
|
return; |
|
} |
|
|
|
// move to the middle of the screen |
|
if ( m_pFrameOver ) |
|
{ |
|
int frameX, frameY; |
|
int frameWide, frameTall; |
|
m_pFrameOver->GetPos(frameX, frameY); |
|
m_pFrameOver->GetSize(frameWide, frameTall); |
|
|
|
SetPos((frameWide - wide) / 2 + frameX, (frameTall - tall) / 2 + frameY); |
|
} |
|
else |
|
{ |
|
int swide, stall; |
|
surface()->GetScreenSize(swide, stall); |
|
// put the dialog in the middle of the screen |
|
SetPos((swide - wide) / 2, (stall - tall) / 2); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Put the message box into a modal state |
|
// Does not suspend execution - use addActionSignal to get return value |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::DoModal(Frame* pFrameOver) |
|
{ |
|
ShowWindow(pFrameOver); |
|
/* |
|
// move to the middle of the screen |
|
// get the screen size |
|
int wide, tall; |
|
// get our dialog size |
|
GetSize(wide, tall); |
|
|
|
if (pFrameOver) |
|
{ |
|
int frameX, frameY; |
|
int frameWide, frameTall; |
|
pFrameOver->GetPos(frameX, frameY); |
|
pFrameOver->GetSize(frameWide, frameTall); |
|
|
|
SetPos((frameWide - wide) / 2 + frameX, (frameTall - tall) / 2 + frameY); |
|
} |
|
else |
|
{ |
|
int swide, stall; |
|
surface()->GetScreenSize(swide, stall); |
|
// put the dialog in the middle of the screen |
|
SetPos((swide - wide) / 2, (stall - tall) / 2); |
|
} |
|
|
|
SetVisible( true ); |
|
SetEnabled( true ); |
|
MoveToFront(); |
|
|
|
if (m_pOkButton->IsVisible()) |
|
m_pOkButton->RequestFocus(); |
|
else // handle message boxes with no button |
|
RequestFocus(); |
|
*/ |
|
input()->SetAppModalSurface(GetVPanel()); |
|
} |
|
|
|
void MessageBox::ShowWindow(Frame *pFrameOver) |
|
{ |
|
m_pFrameOver = pFrameOver; |
|
|
|
SetVisible( true ); |
|
SetEnabled( true ); |
|
MoveToFront(); |
|
|
|
if ( m_pOkButton->IsVisible() ) |
|
{ |
|
m_pOkButton->RequestFocus(); |
|
} |
|
else // handle message boxes with no button |
|
{ |
|
RequestFocus(); |
|
} |
|
|
|
InvalidateLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Put the text and OK buttons in correct place |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::PerformLayout() |
|
{ |
|
int x, y, wide, tall; |
|
GetClientArea(x, y, wide, tall); |
|
wide += x; |
|
tall += y; |
|
|
|
int boxWidth, boxTall; |
|
GetSize(boxWidth, boxTall); |
|
|
|
int oldWide, oldTall; |
|
m_pOkButton->GetSize(oldWide, oldTall); |
|
|
|
// calc proportionality scale |
|
float scale = 1; |
|
if (IsProportional()) |
|
{ |
|
int screenW, screenH; |
|
surface()->GetScreenSize(screenW, screenH); |
|
|
|
int proW, proH; |
|
surface()->GetProportionalBase(proW, proH); |
|
|
|
scale = ((float)(screenH) / (float)(proH)); |
|
} |
|
|
|
int btnWide, btnTall; |
|
m_pOkButton->GetContentSize(btnWide, btnTall); |
|
btnWide = max(oldWide, btnWide + 10 * scale); |
|
btnTall = max(oldTall, btnTall + 10 * scale); |
|
m_pOkButton->SetSize(btnWide, btnTall); |
|
|
|
int btnWide2 = 0, btnTall2 = 0; |
|
if ( m_pCancelButton->IsVisible() ) |
|
{ |
|
m_pCancelButton->GetSize(oldWide, oldTall); |
|
|
|
m_pCancelButton->GetContentSize(btnWide2, btnTall2); |
|
btnWide2 = max(oldWide, btnWide2 + 10 * scale); |
|
btnTall2 = max(oldTall, btnTall2 + 10 * scale); |
|
m_pCancelButton->SetSize(btnWide2, boxTall); |
|
} |
|
|
|
boxWidth = max(boxWidth, m_pMessageLabel->GetWide() + 100 * scale); |
|
boxWidth = max(boxWidth, (btnWide + btnWide2) * 2 + 30 * scale); |
|
SetSize(boxWidth, boxTall); |
|
|
|
GetSize(boxWidth, boxTall); |
|
|
|
m_pMessageLabel->SetPos((wide/2)-(m_pMessageLabel->GetWide()/2) + x, y + 5 * scale); |
|
if ( !m_pCancelButton->IsVisible() ) |
|
{ |
|
m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15 * scale); |
|
} |
|
else |
|
{ |
|
m_pOkButton->SetPos((wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15 * scale); |
|
m_pCancelButton->SetPos((3*wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15 * scale); |
|
} |
|
|
|
BaseClass::PerformLayout(); |
|
GetSize(boxWidth, boxTall); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set a string command to be sent when the OK button is pressed. |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::SetCommand(const char *command) |
|
{ |
|
if (m_OkCommand) |
|
{ |
|
m_OkCommand->deleteThis(); |
|
} |
|
m_OkCommand = new KeyValues("Command", "command", command); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sets the command |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::SetCommand(KeyValues *command) |
|
{ |
|
if (m_OkCommand) |
|
{ |
|
m_OkCommand->deleteThis(); |
|
} |
|
m_OkCommand = command; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::OnShutdownRequest() |
|
{ |
|
// Shutdown the dialog |
|
PostMessage(this, new KeyValues("Close")); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the visibility of the OK button. |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::SetOKButtonVisible(bool state) |
|
{ |
|
m_pOkButton->SetVisible(state); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sets the Text on the OK button |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::SetOKButtonText(const char *buttonText) |
|
{ |
|
m_pOkButton->SetText(buttonText); |
|
InvalidateLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sets the Text on the OK button |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::SetOKButtonText(const wchar_t *wszButtonText) |
|
{ |
|
m_pOkButton->SetText(wszButtonText); |
|
InvalidateLayout(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Cancel button (off by default) |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::SetCancelButtonVisible(bool state) |
|
{ |
|
m_pCancelButton->SetVisible(state); |
|
InvalidateLayout(); |
|
} |
|
|
|
void MessageBox::SetCancelButtonText(const char *buttonText) |
|
{ |
|
m_pCancelButton->SetText(buttonText); |
|
InvalidateLayout(); |
|
} |
|
|
|
void MessageBox::SetCancelButtonText(const wchar_t *wszButtonText) |
|
{ |
|
m_pCancelButton->SetText(wszButtonText); |
|
InvalidateLayout(); |
|
} |
|
|
|
void MessageBox::SetCancelCommand( KeyValues *command ) |
|
{ |
|
if (m_CancelCommand) |
|
{ |
|
m_CancelCommand->deleteThis(); |
|
} |
|
m_CancelCommand = command; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Toggles visibility of the close box. |
|
//----------------------------------------------------------------------------- |
|
void MessageBox::DisableCloseButton(bool state) |
|
{ |
|
BaseClass::SetCloseButtonVisible(state); |
|
m_bNoAutoClose = true; |
|
}
|
|
|