mirror of https://github.com/PCSX2/pcsx2.git
805 lines
22 KiB
C++
805 lines
22 KiB
C++
/* PCSX2 - PS2 Emulator for PCs
|
|
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
|
*
|
|
* 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.
|
|
*
|
|
* 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.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <stack>
|
|
#include <wx/wx.h>
|
|
#include "common/Dependencies.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxGuiTools.h
|
|
//
|
|
// This file is meant to contain utility classes for users of the wxWidgets library.
|
|
// All classes in this file are dependent on wxBase and wxCore libraries! Meaning
|
|
// you will have to use wxCore header files and link against wxCore (GUI) to build
|
|
// them. For tools which require only wxBase, see wxBaseTools.h
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class pxStaticText;
|
|
class pxStaticHeading;
|
|
class pxCheckBox;
|
|
class wxSpinCtrl;
|
|
|
|
namespace pxSizerFlags
|
|
{
|
|
static int StdPadding = 4;
|
|
|
|
extern wxSizerFlags StdSpace();
|
|
extern wxSizerFlags StdCenter();
|
|
extern wxSizerFlags StdExpand();
|
|
extern wxSizerFlags TopLevelBox();
|
|
extern wxSizerFlags SubGroup();
|
|
extern wxSizerFlags StdButton();
|
|
extern wxSizerFlags Checkbox();
|
|
extern void SetBestPadding();
|
|
}; // namespace pxSizerFlags
|
|
|
|
#define wxSF wxSizerFlags()
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxAlignment / pxStretchType
|
|
// --------------------------------------------------------------------------------------
|
|
// These are full blown class types instead of enumerations because wxSizerFlags has an
|
|
// implicit conversion from integer (silly design flaw creating more work for me!)
|
|
//
|
|
struct pxAlignmentType
|
|
{
|
|
enum
|
|
{
|
|
Centre,
|
|
Center = Centre,
|
|
Middle,
|
|
Left,
|
|
Right,
|
|
Top,
|
|
Bottom
|
|
};
|
|
|
|
int intval;
|
|
|
|
wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const;
|
|
|
|
wxSizerFlags operator&(const wxSizerFlags& _flgs) const
|
|
{
|
|
return Apply(_flgs);
|
|
}
|
|
|
|
wxSizerFlags Expand() const
|
|
{
|
|
return Apply().Expand();
|
|
}
|
|
|
|
wxSizerFlags Border(int dir, int padding) const
|
|
{
|
|
return Apply().Border(dir, padding);
|
|
}
|
|
|
|
wxSizerFlags Proportion() const
|
|
{
|
|
return Apply().Proportion(intval);
|
|
}
|
|
|
|
operator wxSizerFlags() const
|
|
{
|
|
return Apply();
|
|
}
|
|
};
|
|
|
|
struct pxStretchType
|
|
{
|
|
enum
|
|
{
|
|
Shrink,
|
|
Expand,
|
|
Shaped,
|
|
ReserveHidden,
|
|
FixedMinimum
|
|
};
|
|
|
|
int intval;
|
|
|
|
wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const;
|
|
|
|
wxSizerFlags operator&(const wxSizerFlags& _flgs) const
|
|
{
|
|
return Apply(_flgs);
|
|
}
|
|
|
|
wxSizerFlags Border(int dir, int padding) const
|
|
{
|
|
return Apply().Border(dir, padding);
|
|
}
|
|
|
|
wxSizerFlags Proportion() const
|
|
{
|
|
return Apply().Proportion(intval);
|
|
}
|
|
|
|
operator wxSizerFlags() const
|
|
{
|
|
return Apply();
|
|
}
|
|
};
|
|
|
|
static __fi wxSizerFlags pxProportion(int prop)
|
|
{
|
|
return wxSizerFlags(prop);
|
|
}
|
|
|
|
static __fi wxSizerFlags pxBorder(int dir = wxALL, int pad = pxSizerFlags::StdPadding)
|
|
{
|
|
return wxSizerFlags().Border(dir, pad);
|
|
}
|
|
|
|
class pxStretchSpacer
|
|
{
|
|
public:
|
|
int proportion;
|
|
|
|
pxStretchSpacer(int prop = 0)
|
|
{
|
|
proportion = prop;
|
|
}
|
|
};
|
|
|
|
extern const pxAlignmentType
|
|
pxCentre, // Horizontal centered alignment
|
|
pxCenter,
|
|
pxMiddle, // vertical centered alignment
|
|
|
|
pxAlignLeft,
|
|
pxAlignRight,
|
|
pxAlignTop,
|
|
pxAlignBottom;
|
|
|
|
extern const pxStretchType
|
|
pxShrink,
|
|
pxExpand,
|
|
pxShaped,
|
|
pxReserveHidden,
|
|
pxFixedMinimum;
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxWindowAndFlags
|
|
// --------------------------------------------------------------------------------------
|
|
// This struct is a go-between for combining windows and sizer flags in "neat" fashion.
|
|
// To create the struct, use the | operator, like so:
|
|
//
|
|
// myPanel | wxSizerFlags().Expand()
|
|
//
|
|
// Implementation Note: This struct is a template as it allows us to use a special
|
|
// version of the += operator that retains the type information of the window, in case
|
|
// the window implements its own += overloads (one example is pxStaticText). Without the
|
|
// template, the type of the window would only be known as "wxWindow" when it's added to the
|
|
// sizer, and would thus fail to invoke the correct operator overload.
|
|
//
|
|
template <typename WinType>
|
|
struct pxWindowAndFlags
|
|
{
|
|
WinType* window;
|
|
wxSizerFlags flags;
|
|
};
|
|
|
|
|
|
extern wxSizerFlags operator&(const wxSizerFlags& _flgs, const wxSizerFlags& _flgs2);
|
|
|
|
template <typename WinType, typename = typename std::enable_if<std::is_base_of<wxObject, WinType>::value>::type>
|
|
pxWindowAndFlags<WinType> operator|(WinType* _win, const wxSizerFlags& _flgs)
|
|
{
|
|
pxWindowAndFlags<WinType> result = {_win, _flgs};
|
|
return result;
|
|
}
|
|
|
|
template <typename WinType, typename = typename std::enable_if<std::is_base_of<wxObject, WinType>::value>::type>
|
|
pxWindowAndFlags<WinType> operator|(WinType& _win, const wxSizerFlags& _flgs)
|
|
{
|
|
pxWindowAndFlags<WinType> result = {&_win, _flgs};
|
|
return result;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// wxSizer Operator += .. a wxSizer.Add() Substitute
|
|
// --------------------------------------------------------------------------------------
|
|
// This set of operators is the *recommended* method for adding windows to sizers, not just
|
|
// because it's a lot prettier but also because it allows controls like pxStaticText to over-
|
|
// ride default sizerflags behavior.
|
|
//
|
|
// += operator works on either sizers, wxDialogs or wxPanels. In the latter case, the window
|
|
// is added to the dialog/panel's toplevel sizer (wxPanel.GetSizer() is used). If the panel
|
|
// has no sizer set via SetSizer(), an assertion is generated.
|
|
//
|
|
|
|
extern void operator+=(wxSizer& target, wxWindow* src);
|
|
extern void operator+=(wxSizer& target, wxSizer* src);
|
|
extern void operator+=(wxSizer& target, wxWindow& src);
|
|
extern void operator+=(wxSizer& target, wxSizer& src);
|
|
|
|
extern void operator+=(wxSizer* target, wxWindow& src);
|
|
extern void operator+=(wxSizer* target, wxSizer& src);
|
|
|
|
extern void operator+=(wxSizer& target, int spacer);
|
|
extern void operator+=(wxWindow& target, int spacer);
|
|
extern void operator+=(wxSizer& target, const pxStretchSpacer& spacer);
|
|
extern void operator+=(wxWindow& target, const pxStretchSpacer& spacer);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Important: This template is needed in order to retain window type information and
|
|
// invoke the proper overloaded version of += (which is used by pxStaticText and other
|
|
// classes to perform special actions when added to sizers).
|
|
template <typename WinType>
|
|
void operator+=(wxWindow& target, WinType* src)
|
|
{
|
|
if (!pxAssert(target.GetSizer() != NULL))
|
|
return;
|
|
*target.GetSizer() += src;
|
|
}
|
|
|
|
template <typename WinType>
|
|
void operator+=(wxWindow& target, WinType& src)
|
|
{
|
|
if (!pxAssert(target.GetSizer() != NULL))
|
|
return;
|
|
*target.GetSizer() += src;
|
|
}
|
|
|
|
template <typename WinType>
|
|
void operator+=(wxWindow& target, const pxWindowAndFlags<WinType>& src)
|
|
{
|
|
if (!pxAssert(target.GetSizer() != NULL))
|
|
return;
|
|
*target.GetSizer() += src;
|
|
}
|
|
|
|
template <typename WinType>
|
|
void operator+=(wxSizer& target, const pxWindowAndFlags<WinType>& src)
|
|
{
|
|
target.Add(src.window, src.flags);
|
|
}
|
|
|
|
wxDECLARE_EVENT(pxEvt_OnDialogCreated, wxCommandEvent);
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxDialogCreationFlags
|
|
// --------------------------------------------------------------------------------------
|
|
class pxDialogCreationFlags
|
|
{
|
|
public:
|
|
wxSize MinimumSize;
|
|
wxOrientation BoxSizerOrient;
|
|
|
|
bool isResizable;
|
|
bool hasContextHelp;
|
|
bool hasCaption;
|
|
bool hasMinimizeBox;
|
|
bool hasMaximizeBox;
|
|
bool hasSystemMenu;
|
|
bool hasCloseBox;
|
|
|
|
public:
|
|
virtual ~pxDialogCreationFlags() = default;
|
|
|
|
pxDialogCreationFlags()
|
|
{
|
|
MinimumSize = wxDefaultSize;
|
|
BoxSizerOrient = wxVERTICAL;
|
|
isResizable = false;
|
|
hasContextHelp = false;
|
|
|
|
hasCloseBox = true;
|
|
hasSystemMenu = true;
|
|
hasMinimizeBox = false;
|
|
hasMaximizeBox = false;
|
|
hasCaption = true;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetSizerOrient(wxOrientation orient)
|
|
{
|
|
BoxSizerOrient = orient;
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetResize(bool enable = true)
|
|
{
|
|
isResizable = enable;
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetMinimize(bool enable = true)
|
|
{
|
|
hasMinimizeBox = enable;
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetMaximize(bool enable = true)
|
|
{
|
|
hasMaximizeBox = enable;
|
|
return *this;
|
|
}
|
|
|
|
// NOTE: Enabling system menu on dialogs usually doesn't work, and might cause
|
|
// other unwanted behavior, such as a missing close button.
|
|
pxDialogCreationFlags& SetSystemMenu(bool enable = true)
|
|
{
|
|
hasSystemMenu = enable;
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetCaption(bool enable = true)
|
|
{
|
|
hasCaption = enable;
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetCloseBox(bool enable = true)
|
|
{
|
|
hasCloseBox = enable;
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags SetContextHelp(bool enabled = true)
|
|
{
|
|
hasContextHelp = enabled;
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetMinWidth(int width)
|
|
{
|
|
if (width > MinimumSize.x)
|
|
MinimumSize.SetWidth(width);
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetMinHeight(int height)
|
|
{
|
|
if (height > MinimumSize.y)
|
|
MinimumSize.SetHeight(height);
|
|
return *this;
|
|
}
|
|
|
|
pxDialogCreationFlags& SetMinSize(const wxSize& size)
|
|
{
|
|
return SetMinWidth(size.x).SetMinHeight(size.y);
|
|
}
|
|
|
|
|
|
pxDialogCreationFlags Horizontal() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetSizerOrient(wxHORIZONTAL);
|
|
}
|
|
|
|
pxDialogCreationFlags Vertical() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetSizerOrient(wxVERTICAL);
|
|
}
|
|
|
|
pxDialogCreationFlags NoSizer() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetSizerOrient((wxOrientation)0);
|
|
}
|
|
|
|
pxDialogCreationFlags Resize(bool enable = true) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetResize(enable);
|
|
}
|
|
|
|
pxDialogCreationFlags Minimize(bool enable = true) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetMinimize(enable);
|
|
}
|
|
|
|
pxDialogCreationFlags Maximize(bool enable = true) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetMaximize(enable);
|
|
}
|
|
|
|
// NOTE: Enabling system menu on dialogs usually doesn't work, and might cause
|
|
// other unwanted behavior, such as a missing close button.
|
|
pxDialogCreationFlags SystemMenu(bool enable = true) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetSystemMenu(false);
|
|
}
|
|
|
|
pxDialogCreationFlags Caption(bool enable = true) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetCaption(enable);
|
|
}
|
|
|
|
pxDialogCreationFlags CloseBox(bool enable = true) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetCloseBox(enable);
|
|
}
|
|
|
|
pxDialogCreationFlags NoResize() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetResize(false);
|
|
}
|
|
|
|
pxDialogCreationFlags NoMinimize() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetMinimize(false);
|
|
}
|
|
|
|
pxDialogCreationFlags NoMaximize() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetMaximize(false);
|
|
}
|
|
|
|
pxDialogCreationFlags NoSystemMenu() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetSystemMenu(false);
|
|
}
|
|
|
|
pxDialogCreationFlags NoCaption() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetCaption(false);
|
|
}
|
|
|
|
pxDialogCreationFlags NoCloseBox() const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetCloseBox(false);
|
|
}
|
|
|
|
pxDialogCreationFlags MinWidth(int width) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetMinWidth(width);
|
|
}
|
|
|
|
pxDialogCreationFlags MinHeight(int height) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetMinHeight(height);
|
|
}
|
|
|
|
pxDialogCreationFlags MinSize(const wxSize& size) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetMinSize(size);
|
|
}
|
|
|
|
pxDialogCreationFlags MinSize(int width, int height) const
|
|
{
|
|
return pxDialogCreationFlags(*this).SetMinWidth(width).SetMinHeight(height);
|
|
}
|
|
|
|
int GetWxWindowFlags() const
|
|
{
|
|
int retval = 0;
|
|
if (isResizable)
|
|
retval |= wxRESIZE_BORDER;
|
|
if (hasCaption)
|
|
retval |= wxCAPTION;
|
|
if (hasMaximizeBox)
|
|
retval |= wxMAXIMIZE_BOX;
|
|
if (hasMinimizeBox)
|
|
retval |= wxMINIMIZE_BOX;
|
|
if (hasSystemMenu)
|
|
retval |= wxSYSTEM_MENU;
|
|
if (hasCloseBox)
|
|
retval |= wxCLOSE_BOX;
|
|
|
|
return retval;
|
|
}
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// wxDialogWithHelpers
|
|
// --------------------------------------------------------------------------------------
|
|
class wxDialogWithHelpers : public wxDialog
|
|
{
|
|
typedef wxDialog _parent;
|
|
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxDialogWithHelpers);
|
|
|
|
protected:
|
|
bool m_hasContextHelp;
|
|
wxBoxSizer* m_extraButtonSizer;
|
|
wxRect m_CreatedRect;
|
|
|
|
public:
|
|
wxDialogWithHelpers();
|
|
wxDialogWithHelpers(wxWindow* parent, const wxString& title, const pxDialogCreationFlags& cflags = pxDialogCreationFlags());
|
|
virtual ~wxDialogWithHelpers() = default;
|
|
|
|
void Init(const pxDialogCreationFlags& cflags);
|
|
void AddOkCancel(wxSizer& sizer, bool hasApply = false);
|
|
void AddOkCancel(wxSizer* sizer = NULL, bool hasApply = false);
|
|
void RememberPosition();
|
|
|
|
virtual void SmartCenterFit();
|
|
virtual int ShowModal();
|
|
virtual bool Show(bool show = true);
|
|
|
|
// Must return the same thing as GetNameStatic; a name ideal for use in uniquely
|
|
// identifying dialogs. (this version is the 'instance' version, which is called
|
|
// by BaseConfigurationDialog to assign the wxWidgets dialog name, and for saving
|
|
// screenshots to disk)
|
|
virtual wxString GetDialogName() const;
|
|
|
|
virtual wxStaticText& Label(const wxString& label);
|
|
virtual pxStaticText& Text(const wxString& label);
|
|
virtual pxStaticText& Heading(const wxString& label);
|
|
|
|
wxDialogWithHelpers& SetMinWidth(int newWidth);
|
|
wxDialogWithHelpers& SetMinHeight(int newHeight);
|
|
|
|
int GetCharHeight() const;
|
|
|
|
protected:
|
|
void OnDialogCreated(wxCommandEvent& evt);
|
|
void OnOkCancel(wxCommandEvent& evt);
|
|
|
|
bool ShouldPreventAppExit() const { return false; }
|
|
|
|
void DoAutoCenter();
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// wxPanelWithHelpers
|
|
// --------------------------------------------------------------------------------------
|
|
// Overview of Helpers provided by this class:
|
|
// * Simpler constructors that have wxID, position, and size parameters removed (We never
|
|
// use them in pcsx2)
|
|
//
|
|
// * Automatic 'primary box sizer' creation, assigned via SetSizer() -- use GetSizer()
|
|
// to retrieve it, or use the "*this += window;" syntax to add windows directly to it.
|
|
//
|
|
// * Built-in support for StaticBoxes (aka groupboxes). Create one at construction with
|
|
// a wxString label, or add one "after the fact" using AddFrame.
|
|
//
|
|
// * Propagates IdealWidth settings from parenting wxPanelWithHelpers classes, and auto-
|
|
// matically adjusts the width based on the sizer type (groupsizers get truncated to
|
|
// account for borders).
|
|
//
|
|
class wxPanelWithHelpers : public wxPanel
|
|
{
|
|
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxPanelWithHelpers);
|
|
|
|
public:
|
|
wxPanelWithHelpers(wxWindow* parent, wxOrientation orient, const wxString& staticBoxLabel);
|
|
wxPanelWithHelpers(wxWindow* parent, wxOrientation orient);
|
|
wxPanelWithHelpers(wxWindow* parent, const wxPoint& pos, const wxSize& size = wxDefaultSize);
|
|
explicit wxPanelWithHelpers(wxWindow* parent = NULL);
|
|
|
|
wxPanelWithHelpers* AddFrame(const wxString& label, wxOrientation orient = wxVERTICAL);
|
|
|
|
wxStaticText& Label(const wxString& label);
|
|
pxStaticText& Text(const wxString& label);
|
|
pxStaticText& Heading(const wxString& label);
|
|
|
|
virtual wxPanelWithHelpers& SetMinWidth(int newWidth);
|
|
|
|
protected:
|
|
void Init();
|
|
};
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxTextWrapperBase
|
|
// --------------------------------------------------------------------------------------
|
|
// this class is used to wrap the text on word boundary: wrapping is done by calling
|
|
// OnStartLine() and OnOutputLine() functions. This class by itself can be used as a
|
|
// line counting tool, but produces no formatted text output.
|
|
//
|
|
// [class "borrowed" from wxWidgets private code, made public, and renamed to avoid possible
|
|
// conflicts with future editions of wxWidgets which might make it public. Why this isn't
|
|
// publicly available already in wxBase I'll never know-- air]
|
|
//
|
|
class pxTextWrapperBase
|
|
{
|
|
protected:
|
|
bool m_eol;
|
|
int m_linecount;
|
|
wxString m_indent;
|
|
|
|
public:
|
|
virtual ~pxTextWrapperBase() = default;
|
|
|
|
pxTextWrapperBase(const wxString& indent = wxEmptyString)
|
|
: m_indent(indent)
|
|
{
|
|
m_eol = false;
|
|
m_linecount = 0;
|
|
}
|
|
|
|
// win is used for getting the font, text is the text to wrap, width is the
|
|
// max line width or -1 to disable wrapping
|
|
pxTextWrapperBase& Wrap(const wxWindow& win, const wxString& text, int widthMax);
|
|
|
|
int GetLineCount() const
|
|
{
|
|
return m_linecount;
|
|
}
|
|
|
|
protected:
|
|
// line may be empty
|
|
virtual void OnOutputLine(const wxString& line) {}
|
|
|
|
// called at the start of every new line (except the very first one)
|
|
virtual void OnNewLine() {}
|
|
|
|
void DoOutputLine(const wxString& line);
|
|
bool IsStartOfNewLine();
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxTextWrapper
|
|
// --------------------------------------------------------------------------------------
|
|
// This class extends pxTextWrapperBase and adds the ability to retrieve the formatted
|
|
// result of word wrapping.
|
|
//
|
|
class pxTextWrapper : public pxTextWrapperBase
|
|
{
|
|
typedef pxTextWrapperBase _parent;
|
|
|
|
protected:
|
|
wxString m_text;
|
|
|
|
public:
|
|
pxTextWrapper(const wxString& wrapPrefix = wxEmptyString)
|
|
: pxTextWrapperBase(wrapPrefix)
|
|
{
|
|
}
|
|
|
|
virtual ~pxTextWrapper() = default;
|
|
|
|
const wxString& GetResult() const
|
|
{
|
|
return m_text;
|
|
}
|
|
|
|
pxTextWrapper& Wrap(const wxWindow& win, const wxString& text, int widthMax);
|
|
pxTextWrapper& Wrap(const wxWindow* win, const wxString& text, int widthMax);
|
|
|
|
protected:
|
|
void OnOutputLine(const wxString& line);
|
|
void OnNewLine();
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxWindowTextWriter
|
|
// --------------------------------------------------------------------------------------
|
|
class pxWindowTextWriter
|
|
{
|
|
protected:
|
|
wxDC& m_dc;
|
|
|
|
wxAlignment m_align;
|
|
wxPoint m_curpos;
|
|
int m_leading;
|
|
|
|
virtual void _DoWriteLn(const wxString& msg);
|
|
void _DoWrite(const wxChar* msg);
|
|
|
|
public:
|
|
pxWindowTextWriter(wxDC& dc);
|
|
virtual ~pxWindowTextWriter() = default;
|
|
|
|
virtual void OnFontChanged();
|
|
|
|
pxWindowTextWriter& WriteLn();
|
|
pxWindowTextWriter& FormatLn(const wxChar* fmt, ...);
|
|
pxWindowTextWriter& WriteLn(const wxChar* fmt);
|
|
pxWindowTextWriter& SetFont(const wxFont& font);
|
|
pxWindowTextWriter& Align(const wxAlignment& align);
|
|
pxWindowTextWriter& WriteLn(const wxString fmt);
|
|
|
|
pxWindowTextWriter& SetLeading(int lead)
|
|
{
|
|
m_leading = lead;
|
|
return *this;
|
|
}
|
|
|
|
pxWindowTextWriter& SetWeight(wxFontWeight weight);
|
|
pxWindowTextWriter& SetStyle(wxFontStyle style);
|
|
pxWindowTextWriter& Normal();
|
|
|
|
pxWindowTextWriter& Bold()
|
|
{
|
|
return SetWeight(wxFONTWEIGHT_BOLD);
|
|
}
|
|
|
|
pxWindowTextWriter& Italic()
|
|
{
|
|
return SetStyle(wxFONTSTYLE_ITALIC);
|
|
}
|
|
|
|
pxWindowTextWriter& SetPos(const wxPoint& pos);
|
|
pxWindowTextWriter& MovePos(const wxSize& delta);
|
|
|
|
pxWindowTextWriter& SetPos(int xpos, int ypos)
|
|
{
|
|
return SetPos(wxPoint(xpos, ypos));
|
|
}
|
|
|
|
pxWindowTextWriter& MovePos(int xdelta, int ydelta)
|
|
{
|
|
return MovePos(wxSize(xdelta, ydelta));
|
|
}
|
|
|
|
pxWindowTextWriter& SetY(int ypos);
|
|
pxWindowTextWriter& MoveY(int ydelta);
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// MoreStockCursors
|
|
// --------------------------------------------------------------------------------------
|
|
// Because (inexplicably) the ArrowWait cursor isn't in wxWidgets stock list.
|
|
//
|
|
class MoreStockCursors
|
|
{
|
|
protected:
|
|
std::unique_ptr<wxCursor> m_arrowWait;
|
|
|
|
public:
|
|
MoreStockCursors() {}
|
|
virtual ~MoreStockCursors() = default;
|
|
const wxCursor& GetArrowWait();
|
|
};
|
|
|
|
enum BusyCursorType
|
|
{
|
|
Cursor_NotBusy,
|
|
Cursor_KindaBusy,
|
|
Cursor_ReallyBusy,
|
|
};
|
|
|
|
extern MoreStockCursors StockCursors;
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// ScopedBusyCursor
|
|
// --------------------------------------------------------------------------------------
|
|
// ... because wxWidgets wxBusyCursor doesn't really do proper nesting (doesn't let me
|
|
// override a partially-busy cursor with a really busy one)
|
|
|
|
class ScopedBusyCursor
|
|
{
|
|
protected:
|
|
static std::stack<BusyCursorType> m_cursorStack;
|
|
static BusyCursorType m_defBusyType;
|
|
|
|
public:
|
|
ScopedBusyCursor(BusyCursorType busytype);
|
|
virtual ~ScopedBusyCursor();
|
|
|
|
static void SetDefault(BusyCursorType busytype);
|
|
static void SetManualBusyCursor(BusyCursorType busytype);
|
|
};
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxFitToDigits
|
|
// --------------------------------------------------------------------------------------
|
|
// Fits a given text or spinner control to the number of digits requested, since by default
|
|
// they're usually way over-sized.
|
|
|
|
extern void pxFitToDigits(wxWindow* win, int digits);
|
|
extern void pxFitToDigits(wxSpinCtrl* win, int digits);
|
|
extern wxTextCtrl* CreateNumericalTextCtrl(wxWindow* parent, int digits, long flags = wxTE_RIGHT);
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern bool pxDialogExists(const wxString& name);
|
|
extern bool pxIsValidWindowPosition(const wxWindow& window, const wxPoint& windowPos);
|
|
extern wxRect wxGetDisplayArea();
|
|
extern wxString pxGetAppName();
|
|
|
|
extern int pxGetCharHeight(const wxWindow* wind, int rows = 1);
|
|
extern int pxGetCharHeight(const wxWindow& wind, int rows = 1);
|
|
|
|
extern void pxSetToolTip(wxWindow* wind, const wxString& src);
|
|
extern void pxSetToolTip(wxWindow& wind, const wxString& src);
|
|
extern wxFont pxGetFixedFont(int ptsize = 8, wxFontWeight weight = wxFONTWEIGHT_NORMAL, bool underline = false);
|
|
|
|
extern pxDialogCreationFlags pxDialogFlags();
|