2009-09-08 12:08:10 +00:00
|
|
|
/* PCSX2 - PS2 Emulator for PCs
|
2010-05-03 14:08:02 +00:00
|
|
|
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
2009-09-17 02:12:32 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
2009-07-04 20:53:05 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
2009-07-04 20:53:05 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
2009-07-04 20:53:05 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <wx/cshelp.h>
|
2009-11-18 07:53:02 +00:00
|
|
|
#include <wx/tooltip.h>
|
2010-01-04 11:51:09 +00:00
|
|
|
#include <wx/spinctrl.h>
|
2021-09-01 20:31:46 +00:00
|
|
|
#include "common/General.h"
|
|
|
|
#include "common/wxGuiTools.h"
|
|
|
|
#include "common/pxStaticText.h"
|
|
|
|
#include "common/Threading.h"
|
|
|
|
#include "common/IniInterface.h"
|
2009-07-04 20:53:05 +00:00
|
|
|
|
2009-11-25 15:38:24 +00:00
|
|
|
using namespace pxSizerFlags;
|
|
|
|
|
2010-06-04 19:50:31 +00:00
|
|
|
pxDialogCreationFlags pxDialogFlags()
|
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return pxDialogCreationFlags().CloseBox().Caption().Vertical();
|
2010-06-04 19:50:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-22 15:22:01 +00:00
|
|
|
// --------------------------------------------------------------------------------------
|
2010-04-27 13:12:03 +00:00
|
|
|
// BaseDeletableObject Implementation
|
2010-01-22 15:22:01 +00:00
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// This code probably deserves a better home. It's general purpose non-GUI code (the single
|
|
|
|
// wxApp/Gui dependency is in wxGuiTools.cpp for now).
|
|
|
|
//
|
2010-04-27 13:12:03 +00:00
|
|
|
bool BaseDeletableObject::MarkForDeletion()
|
2010-01-22 15:22:01 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return !m_IsBeingDeleted.exchange(true);
|
2010-01-22 15:22:01 +00:00
|
|
|
}
|
|
|
|
|
2010-04-27 13:12:03 +00:00
|
|
|
void BaseDeletableObject::DeleteSelf()
|
2010-01-22 15:22:01 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
if (MarkForDeletion())
|
|
|
|
DoDeletion();
|
2010-01-22 15:22:01 +00:00
|
|
|
}
|
|
|
|
|
2010-04-27 13:12:03 +00:00
|
|
|
BaseDeletableObject::BaseDeletableObject()
|
2010-01-22 15:22:01 +00:00
|
|
|
{
|
2016-11-12 15:28:37 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
// Bleh, this fails because _CrtIsValidHeapPointer calls HeapValidate on the
|
|
|
|
// pointer, but the pointer is a virtual base class, so it's not a valid block. >_<
|
|
|
|
//pxAssertDev( _CrtIsValidHeapPointer( this ), "BaseDeletableObject types cannot be created on the stack or as temporaries!" );
|
|
|
|
#endif
|
2010-01-22 15:22:01 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
m_IsBeingDeleted.store(false, std::memory_order_relaxed);
|
2010-01-22 15:22:01 +00:00
|
|
|
}
|
|
|
|
|
2017-05-06 12:22:00 +00:00
|
|
|
BaseDeletableObject::~BaseDeletableObject()
|
2010-01-22 15:22:01 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
AffinityAssert_AllowFrom_MainUI();
|
2010-01-22 15:22:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
2010-01-04 11:51:09 +00:00
|
|
|
// Creates a text control which is right-justified and has it's minimum width configured to suit
|
|
|
|
// the number of digits requested.
|
2021-09-06 18:28:26 +00:00
|
|
|
wxTextCtrl* CreateNumericalTextCtrl(wxWindow* parent, int digits, long flags)
|
2010-01-04 11:51:09 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
wxTextCtrl* ctrl = new wxTextCtrl(parent, wxID_ANY);
|
|
|
|
ctrl->SetWindowStyleFlag(flags);
|
|
|
|
pxFitToDigits(ctrl, digits);
|
|
|
|
return ctrl;
|
2010-01-04 11:51:09 +00:00
|
|
|
}
|
2009-11-11 11:36:13 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
void pxFitToDigits(wxWindow* win, int digits)
|
2010-01-04 11:51:09 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
int ex;
|
|
|
|
win->GetTextExtent(wxString(L'0', digits + 1), &ex, NULL);
|
|
|
|
win->SetMinSize(wxSize(ex + 10, wxDefaultCoord)); // +10 for text control borders/insets and junk.
|
2010-01-04 11:51:09 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
void pxFitToDigits(wxSpinCtrl* win, int digits)
|
2010-01-04 11:51:09 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
// HACK!! The better way would be to create a pxSpinCtrl class that extends wxSpinCtrl and thus
|
|
|
|
// have access to wxSpinButton::DoGetBestSize(). But since I don't want to do that, we'll just
|
|
|
|
// make/fake it with a value it's pretty common to Win32/GTK/Mac:
|
2010-01-04 11:51:09 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
static const int MagicSpinnerSize = 18;
|
2010-01-04 11:51:09 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
int ex;
|
|
|
|
win->GetTextExtent(wxString(L'0', digits + 1), &ex, NULL);
|
|
|
|
win->SetMinSize(wxSize(ex + 10 + MagicSpinnerSize, wxDefaultCoord)); // +10 for text control borders/insets and junk.
|
2010-01-04 11:51:09 +00:00
|
|
|
}
|
2009-11-08 01:56:24 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
bool pxDialogExists(const wxString& name)
|
2009-09-16 17:23:02 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return wxFindWindowByName(name) != NULL;
|
2009-09-16 17:23:02 +00:00
|
|
|
}
|
|
|
|
|
2010-01-04 11:51:09 +00:00
|
|
|
// =====================================================================================================
|
|
|
|
// wxDialogWithHelpers Class Implementations
|
|
|
|
// =====================================================================================================
|
|
|
|
|
2016-06-14 22:17:37 +00:00
|
|
|
wxDEFINE_EVENT(pxEvt_OnDialogCreated, wxCommandEvent);
|
2010-05-20 22:29:30 +00:00
|
|
|
|
2019-05-12 03:43:47 +00:00
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxDialogWithHelpers, wxDialog);
|
2009-11-18 07:53:02 +00:00
|
|
|
|
|
|
|
wxDialogWithHelpers::wxDialogWithHelpers()
|
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
m_hasContextHelp = false;
|
|
|
|
m_extraButtonSizer = NULL;
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
Init(pxDialogFlags());
|
2009-12-14 12:18:55 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxDialogWithHelpers::wxDialogWithHelpers(wxWindow* parent, const wxString& title, const pxDialogCreationFlags& cflags)
|
|
|
|
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, cflags.GetWxWindowFlags())
|
2009-12-14 12:18:55 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
m_hasContextHelp = cflags.hasContextHelp;
|
|
|
|
if ((int)cflags.BoxSizerOrient != 0)
|
|
|
|
{
|
|
|
|
SetSizer(new wxBoxSizer(cflags.BoxSizerOrient));
|
|
|
|
*this += StdPadding;
|
|
|
|
}
|
2009-11-18 07:53:02 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
Init(cflags);
|
|
|
|
SetMinSize(cflags.MinimumSize);
|
2009-12-14 12:18:55 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
void wxDialogWithHelpers::Init(const pxDialogCreationFlags& cflags)
|
2009-12-14 12:18:55 +00:00
|
|
|
{
|
2016-11-12 15:28:37 +00:00
|
|
|
// Note to self: if any comments indicate platform specific behaviour then
|
|
|
|
// ifdef them out to see if they fix the issue. I wasted too much time
|
|
|
|
// figuring out why the close box wouldn't work on wxGTK modal dialogs that
|
|
|
|
// had a minimise button.
|
2015-06-24 22:26:22 +00:00
|
|
|
#if _WIN32
|
2021-09-06 18:28:26 +00:00
|
|
|
// This fixes it so that the dialogs show up in the task bar in Vista:
|
|
|
|
// (otherwise they go stupid iconized mode if the user minimizes them)
|
|
|
|
if (cflags.hasMinimizeBox)
|
|
|
|
SetExtraStyle(GetExtraStyle() & ~wxTOPLEVEL_EX_DIALOG);
|
2015-06-24 22:26:22 +00:00
|
|
|
#endif
|
2010-06-06 23:26:07 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
m_extraButtonSizer = NULL;
|
2009-11-14 08:36:57 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
if (m_hasContextHelp)
|
|
|
|
delete wxHelpProvider::Set(new wxSimpleHelpProvider());
|
2009-07-04 20:53:05 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
Bind(pxEvt_OnDialogCreated, &wxDialogWithHelpers::OnDialogCreated, this);
|
2009-12-14 12:18:55 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
Bind(wxEVT_BUTTON, &wxDialogWithHelpers::OnOkCancel, this, wxID_OK);
|
|
|
|
Bind(wxEVT_BUTTON, &wxDialogWithHelpers::OnOkCancel, this, wxID_CANCEL);
|
2010-05-20 22:29:30 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxCommandEvent createEvent(pxEvt_OnDialogCreated);
|
|
|
|
createEvent.SetId(GetId());
|
|
|
|
AddPendingEvent(createEvent);
|
2010-05-20 22:29:30 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
void wxDialogWithHelpers::OnDialogCreated(wxCommandEvent& evt)
|
2010-05-20 22:29:30 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
evt.Skip();
|
|
|
|
if ((evt.GetId() == GetId()) && !GetDialogName().IsEmpty())
|
|
|
|
SetName(L"Dialog:" + GetDialogName());
|
2010-05-20 22:29:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
wxString wxDialogWithHelpers::GetDialogName() const
|
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return wxEmptyString;
|
2009-07-04 20:53:05 +00:00
|
|
|
}
|
|
|
|
|
2010-06-06 23:26:07 +00:00
|
|
|
void wxDialogWithHelpers::DoAutoCenter()
|
2009-09-16 17:23:02 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
// Smart positioning logic! If our parent window is larger than our window by some
|
|
|
|
// good amount, then we center on that. If not, center relative to the screen. This
|
|
|
|
// avoids the popup automatically eclipsing the parent window (which happens in PCSX2
|
|
|
|
// a lot since the main window is small).
|
2009-12-14 12:18:55 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
bool centerfail = true;
|
|
|
|
if (wxWindow* parent = GetParent())
|
|
|
|
{
|
|
|
|
const wxSize parentSize(parent->GetSize());
|
2009-12-14 12:18:55 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
if ((parentSize.x > ((int)GetSize().x * 1.5)) || (parentSize.y > ((int)GetSize().y * 1.5)))
|
|
|
|
{
|
|
|
|
CenterOnParent();
|
|
|
|
centerfail = false;
|
|
|
|
}
|
|
|
|
}
|
2009-12-14 12:18:55 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
if (centerfail)
|
|
|
|
CenterOnScreen();
|
2009-12-14 12:18:55 +00:00
|
|
|
}
|
|
|
|
|
2010-06-06 23:26:07 +00:00
|
|
|
void wxDialogWithHelpers::SmartCenterFit()
|
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
Fit();
|
|
|
|
|
|
|
|
const wxString dlgName(GetDialogName());
|
|
|
|
if (dlgName.IsEmpty())
|
|
|
|
{
|
|
|
|
DoAutoCenter();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wxConfigBase* cfg = wxConfigBase::Get(false))
|
|
|
|
{
|
|
|
|
wxRect screenRect(GetScreenRect());
|
|
|
|
|
|
|
|
IniLoader loader(cfg);
|
|
|
|
ScopedIniGroup group(loader, L"DialogPositions");
|
|
|
|
cfg->SetRecordDefaults(false);
|
|
|
|
|
|
|
|
if (GetWindowStyle() & wxRESIZE_BORDER)
|
|
|
|
{
|
|
|
|
wxSize size;
|
|
|
|
loader.Entry(dlgName + L"_Size", size, screenRect.GetSize());
|
|
|
|
SetSize(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!cfg->Exists(dlgName + L"_Pos"))
|
|
|
|
DoAutoCenter();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wxPoint pos;
|
|
|
|
loader.Entry(dlgName + L"_Pos", pos, screenRect.GetPosition());
|
|
|
|
SetPosition(pos);
|
|
|
|
}
|
|
|
|
cfg->SetRecordDefaults(true);
|
|
|
|
}
|
2010-06-06 23:26:07 +00:00
|
|
|
}
|
|
|
|
|
2009-12-14 12:18:55 +00:00
|
|
|
// Overrides wxDialog behavior to include automatic Fit() and CenterOnParent/Screen. The centering
|
|
|
|
// is based on a heuristic the centers against the parent window if the parent window is at least
|
|
|
|
// 75% larger than the fitted dialog.
|
|
|
|
int wxDialogWithHelpers::ShowModal()
|
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
SmartCenterFit();
|
|
|
|
m_CreatedRect = GetScreenRect();
|
|
|
|
return wxDialog::ShowModal();
|
2009-12-14 12:18:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Overrides wxDialog behavior to include automatic Fit() and CenterOnParent/Screen. The centering
|
|
|
|
// is based on a heuristic the centers against the parent window if the parent window is at least
|
|
|
|
// 75% larger than the fitted dialog.
|
2016-11-12 15:28:37 +00:00
|
|
|
bool wxDialogWithHelpers::Show(bool show)
|
2009-12-14 12:18:55 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
if (show)
|
|
|
|
{
|
|
|
|
SmartCenterFit();
|
|
|
|
m_CreatedRect = GetScreenRect();
|
|
|
|
}
|
|
|
|
return wxDialog::Show(show);
|
2009-09-16 17:23:02 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxStaticText& wxDialogWithHelpers::Label(const wxString& label)
|
2009-11-20 03:26:10 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return *new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_VERTICAL);
|
2009-11-20 03:26:10 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
pxStaticText& wxDialogWithHelpers::Text(const wxString& label)
|
2009-11-20 03:26:10 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return *new pxStaticText(this, label);
|
2010-06-04 08:00:19 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
pxStaticText& wxDialogWithHelpers::Heading(const wxString& label)
|
2010-06-04 08:00:19 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return *new pxStaticHeading(this, label);
|
2009-11-20 03:26:10 +00:00
|
|
|
}
|
|
|
|
|
2015-06-25 15:46:20 +00:00
|
|
|
void wxDialogWithHelpers::RememberPosition()
|
2009-12-14 12:18:55 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
// Save the dialog position if the dialog is named...
|
|
|
|
// FIXME : This doesn't get called if the app is exited by alt-f4'ing the main app window.
|
|
|
|
// ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers
|
|
|
|
// that systematically get closed. Seems like work, maybe later. --air
|
2010-12-12 07:43:21 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
if (wxConfigBase* cfg = IsIconized() ? NULL : wxConfigBase::Get(false))
|
|
|
|
{
|
|
|
|
const wxString dlgName(GetDialogName());
|
|
|
|
const wxRect screenRect(GetScreenRect());
|
|
|
|
if (!dlgName.IsEmpty() && (m_CreatedRect != screenRect))
|
|
|
|
{
|
|
|
|
wxPoint pos(screenRect.GetPosition());
|
|
|
|
IniSaver saver(cfg);
|
|
|
|
ScopedIniGroup group(saver, L"DialogPositions");
|
2010-06-06 23:26:07 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
if (GetWindowStyle() & wxRESIZE_BORDER)
|
|
|
|
{
|
|
|
|
wxSize size(screenRect.GetSize());
|
|
|
|
saver.Entry(dlgName + L"_Size", size, screenRect.GetSize());
|
|
|
|
}
|
|
|
|
saver.Entry(dlgName + L"_Pos", pos, screenRect.GetPosition());
|
|
|
|
}
|
|
|
|
}
|
2009-12-14 12:18:55 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
void wxDialogWithHelpers::OnOkCancel(wxCommandEvent& evt)
|
2009-12-14 12:18:55 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
RememberPosition();
|
2015-06-25 15:46:20 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
// Modal dialogs should be destroyed after ShowModal returns, otherwise there
|
|
|
|
// might be double delete problems if the dialog was declared on the stack.
|
|
|
|
if (!IsModal())
|
|
|
|
Destroy();
|
|
|
|
else
|
|
|
|
evt.Skip();
|
2009-12-14 12:18:55 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
void wxDialogWithHelpers::AddOkCancel(wxSizer& sizer, bool hasApply)
|
2009-07-04 20:53:05 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
wxStdDialogButtonSizer& s_buttons(*new wxStdDialogButtonSizer());
|
2009-11-25 15:38:24 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
s_buttons.AddButton(new wxButton(this, wxID_OK));
|
|
|
|
s_buttons.AddButton(new wxButton(this, wxID_CANCEL));
|
2009-11-25 15:38:24 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
if (hasApply)
|
|
|
|
s_buttons.AddButton(new wxButton(this, wxID_APPLY));
|
2009-11-25 15:38:24 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
m_extraButtonSizer = new wxBoxSizer(wxHORIZONTAL);
|
2009-11-25 15:38:24 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
// Add the context-sensitive help button on the caption for the platforms
|
|
|
|
// which support it (currently MSW only)
|
|
|
|
if (m_hasContextHelp)
|
|
|
|
{
|
|
|
|
SetExtraStyle(wxDIALOG_EX_CONTEXTHELP);
|
2009-11-27 06:47:32 +00:00
|
|
|
#ifndef __WXMSW__
|
2021-09-06 18:28:26 +00:00
|
|
|
*m_extraButtonSizer += new wxContextHelpButton(this) | StdButton();
|
2009-11-27 06:47:32 +00:00
|
|
|
#endif
|
2021-09-06 18:28:26 +00:00
|
|
|
}
|
2009-11-26 03:37:10 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
// create a sizer to hold the help and ok/cancel buttons, for platforms
|
|
|
|
// that need a custom help icon. [fixme: help icon prolly better off somewhere else]
|
|
|
|
wxFlexGridSizer& flex(*new wxFlexGridSizer(2));
|
|
|
|
flex.AddGrowableCol(0, 1);
|
|
|
|
flex.AddGrowableCol(1, 15);
|
2009-07-11 08:31:38 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
flex += m_extraButtonSizer | pxAlignLeft;
|
|
|
|
flex += s_buttons | (pxExpand & pxCenter);
|
2009-07-11 08:31:38 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
sizer += flex | StdExpand();
|
2009-07-11 08:31:38 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
s_buttons.Realize();
|
2009-07-04 20:53:05 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
void wxDialogWithHelpers::AddOkCancel(wxSizer* sizer, bool hasApply)
|
2010-05-03 13:51:46 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
if (sizer == NULL)
|
|
|
|
sizer = GetSizer();
|
|
|
|
pxAssert(sizer);
|
|
|
|
AddOkCancel(*sizer, hasApply);
|
2010-05-03 13:51:46 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxDialogWithHelpers& wxDialogWithHelpers::SetMinWidth(int newWidth)
|
2010-06-04 08:00:19 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
SetMinSize(wxSize(newWidth, GetMinHeight()));
|
|
|
|
if (wxSizer* sizer = GetSizer())
|
|
|
|
sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight()));
|
|
|
|
return *this;
|
2010-06-04 08:00:19 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxDialogWithHelpers& wxDialogWithHelpers::SetMinHeight(int newHeight)
|
2010-06-06 23:26:07 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
SetMinSize(wxSize(GetMinWidth(), newHeight));
|
|
|
|
if (wxSizer* sizer = GetSizer())
|
|
|
|
sizer->SetMinSize(wxSize(sizer->GetMinSize().GetWidth(), newHeight));
|
|
|
|
return *this;
|
2010-06-06 23:26:07 +00:00
|
|
|
}
|
|
|
|
|
2010-06-08 12:09:28 +00:00
|
|
|
int wxDialogWithHelpers::GetCharHeight() const
|
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return pxGetCharHeight(this, 1);
|
2010-06-08 12:09:28 +00:00
|
|
|
}
|
|
|
|
|
2009-11-18 07:53:02 +00:00
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// wxPanelWithHelpers Implementations
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
2019-05-12 03:43:47 +00:00
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxPanelWithHelpers, wxPanel);
|
2009-11-18 07:53:02 +00:00
|
|
|
|
|
|
|
void wxPanelWithHelpers::Init()
|
2009-07-07 20:53:32 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-11-21 07:44:11 +00:00
|
|
|
// Creates a Static Box container for this panel. the static box sizer becomes the default
|
|
|
|
// sizer for this panel. If the panel already has a sizer set, then that sizer will be
|
|
|
|
// transfered to the new StaticBoxSizer (and will be the first item in it's list, retaining
|
|
|
|
// consistent and expected layout)
|
2021-09-06 18:28:26 +00:00
|
|
|
wxPanelWithHelpers* wxPanelWithHelpers::AddFrame(const wxString& label, wxOrientation orient)
|
2009-07-07 20:53:32 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
wxSizer* oldSizer = GetSizer();
|
2009-11-18 07:53:02 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
SetSizer(new wxStaticBoxSizer(orient, this, label), false);
|
|
|
|
Init();
|
2009-11-18 07:53:02 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
if (oldSizer)
|
|
|
|
*this += oldSizer | pxExpand;
|
2010-04-25 00:31:27 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
return this;
|
2009-11-18 07:53:02 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxStaticText& wxPanelWithHelpers::Label(const wxString& label)
|
2009-11-20 03:26:10 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return *new wxStaticText(this, wxID_ANY, label);
|
2009-11-20 03:26:10 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
pxStaticText& wxPanelWithHelpers::Text(const wxString& label)
|
2009-11-20 03:26:10 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return *new pxStaticText(this, label);
|
2010-06-04 08:00:19 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
pxStaticText& wxPanelWithHelpers::Heading(const wxString& label)
|
2010-06-04 08:00:19 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return *new pxStaticHeading(this, label);
|
2009-11-20 03:26:10 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, wxOrientation orient, const wxString& staticBoxLabel)
|
|
|
|
: wxPanel(parent)
|
2009-11-18 07:53:02 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
SetSizer(new wxStaticBoxSizer(orient, this, staticBoxLabel));
|
|
|
|
Init();
|
2009-11-18 07:53:02 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, wxOrientation orient)
|
|
|
|
: wxPanel(parent)
|
2009-11-18 07:53:02 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
SetSizer(new wxBoxSizer(orient));
|
|
|
|
Init();
|
2009-11-18 07:53:02 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent)
|
|
|
|
: wxPanel(parent)
|
2009-11-18 07:53:02 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
Init();
|
2009-11-18 07:53:02 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, const wxPoint& pos, const wxSize& size)
|
|
|
|
: wxPanel(parent, wxID_ANY, pos, size)
|
2009-11-18 07:53:02 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
Init();
|
2009-07-07 20:53:32 +00:00
|
|
|
}
|
2010-06-04 08:00:19 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
wxPanelWithHelpers& wxPanelWithHelpers::SetMinWidth(int newWidth)
|
2010-06-04 08:00:19 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
SetMinSize(wxSize(newWidth, GetMinHeight()));
|
|
|
|
if (wxSizer* sizer = GetSizer())
|
|
|
|
sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight()));
|
|
|
|
return *this;
|
2010-06-04 08:00:19 +00:00
|
|
|
}
|
2010-06-09 17:37:11 +00:00
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
int pxGetCharHeight(const wxWindow* wind, int rows)
|
2010-06-09 17:37:11 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
if (!wind)
|
|
|
|
return 0;
|
|
|
|
wxClientDC dc(wx_const_cast(wxWindow*, wind));
|
|
|
|
dc.SetFont(wind->GetFont());
|
2014-08-03 18:11:22 +00:00
|
|
|
#ifdef __linux__
|
2021-09-06 18:28:26 +00:00
|
|
|
// It seems there is a bad detection of the size of the font (non standard dpi ???). Font are cut in top or bottom.
|
|
|
|
// Add a correction factor to leave enough room. Visualy 1.7 seems fine but feel free to tune it -- Gregory
|
|
|
|
return (dc.GetCharHeight() * 1.7 + 1) * rows;
|
2011-05-10 09:26:39 +00:00
|
|
|
#else
|
2021-09-06 18:28:26 +00:00
|
|
|
return (dc.GetCharHeight() + 1) * rows;
|
2011-05-10 09:26:39 +00:00
|
|
|
#endif
|
2010-06-09 17:37:11 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:28:26 +00:00
|
|
|
int pxGetCharHeight(const wxWindow& wind, int rows)
|
2010-06-09 17:37:11 +00:00
|
|
|
{
|
2021-09-06 18:28:26 +00:00
|
|
|
return pxGetCharHeight(&wind, rows);
|
2010-06-09 17:37:11 +00:00
|
|
|
}
|