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.
396 lines
10 KiB
396 lines
10 KiB
![]()
4 years ago
|
//========= 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);
|
||
|
|
||
|
wide += 100;
|
||
|
tall += 100;
|
||
|
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);
|
||
|
|
||
|
int btnWide, btnTall;
|
||
|
m_pOkButton->GetContentSize(btnWide, btnTall);
|
||
|
btnWide = max(oldWide, btnWide + 10);
|
||
|
btnTall = max(oldTall, btnTall + 10);
|
||
|
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);
|
||
|
btnTall2 = max(oldTall, btnTall2 + 10);
|
||
|
m_pCancelButton->SetSize(btnWide2, btnTall2);
|
||
|
}
|
||
|
|
||
|
boxWidth = max(boxWidth, m_pMessageLabel->GetWide() + 100);
|
||
|
boxWidth = max(boxWidth, (btnWide + btnWide2) * 2 + 30);
|
||
|
SetSize(boxWidth, boxTall);
|
||
|
|
||
|
GetSize(boxWidth, boxTall);
|
||
|
|
||
|
m_pMessageLabel->SetPos((wide/2)-(m_pMessageLabel->GetWide()/2) + x, y + 5 );
|
||
|
if ( !m_pCancelButton->IsVisible() )
|
||
|
{
|
||
|
m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pOkButton->SetPos((wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
|
||
|
m_pCancelButton->SetPos((3*wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|