mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-10-13 22:40:56 +02:00
* common: format AlignedMalloc.cpp * common: format AppTrait.h * common: format Assertions.h * common: format CheckedStaticBox * common: format Console * common: format Dependencies.h * common: format EmbeddedImage * common: format EventSource * common: format Exceptions * common: format FastFormatString.cpp * common: format General.h * common: format InitInterface * common: format MathUtils.h * common: format MemsetFast/MemcpyFast * common: format Mutex.cpp * common: format PageFaultSource.h * common: format Path.h * common: format PathUtils.cpp * common: format Pcsx2Types.h * common: format Perf * common: format PersistentThread.h * common: format RwMutex * common: format SafeArray * common: format ScopedAlloc.h * common: format ScopedPtrMT.h * common: format Semaphore.cpp * common: format StringHelpers * common: format ThreadTools.cpp * common: format Threading.h * common: format ThreadingDialogs * common: format ThreadingInternal.h * common: format TraceLog.h * common: format VirtualMemory.cpp * common: format pxCheckBox * common: format pxEvents.h * common: format pxForwardDefs.h * common: format pxRadioPanel * common: format pxStaticText * common: format pxStreams * common: format pxTranslate.cpp * common: format pxWindowTextWriter.cpp * common: format wxAppWithHelpers * common: format wxBaseTools.h * common: format wxGuiTools * common: format wxHelpers.cpp * common: format Darwin directory * common: format Linux directory * common: format Windows directory * common: format LnxCpuDetect.cpp * common: format WinCpuDetect.cpp * common: format bmi.cpp * common: format cpudetect.cpp * common: format cpu_detect_internal.h * common: format fpu.cpp * common: format groups.cpp * common: format instructions.h * common: format internal.h * common: format jmp.cpp * common: format legacy.cpp * common: format legacy_instructions.h * common: format legacy_internal.h * common: format movs.cpp * common: format simd.cpp * common: format tools.h * common: format x86emitter.cpp * common: format x86types.h * common: format bmi.h * common: format dwshift.h * common: format group1.h group2.h group3.h * common: format incdec.h * common: format jmpcall.h * common: format movs.h * common: format simd_arithmetic.h * common: format simd_comparisons.h * common: format simd_helpers.h * common: format simd_moremovs.h * common: format simd_shufflepack.h * common: format simd_templated_helpers.h * common: format test.h
392 lines
9.2 KiB
C++
392 lines
9.2 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/>.
|
|
*/
|
|
|
|
#include <wx/wizard.h>
|
|
#include "common/pxStaticText.h"
|
|
#include "common/Assertions.h"
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxStaticText (implementations)
|
|
// --------------------------------------------------------------------------------------
|
|
pxStaticText::pxStaticText(wxWindow* parent)
|
|
: _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER)
|
|
{
|
|
m_align = wxALIGN_CENTRE_HORIZONTAL;
|
|
m_autowrap = true;
|
|
m_wrappedWidth = -1;
|
|
m_heightInLines = 1;
|
|
|
|
SetPaddingDefaults();
|
|
}
|
|
|
|
pxStaticText::pxStaticText(wxWindow* parent, const wxString& label, wxAlignment align)
|
|
: _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER)
|
|
{
|
|
m_heightInLines = 1;
|
|
m_align = align;
|
|
|
|
SetPaddingDefaults();
|
|
Init(label);
|
|
}
|
|
|
|
void pxStaticText::Init(const wxString& label)
|
|
{
|
|
m_autowrap = true;
|
|
m_wrappedWidth = -1;
|
|
m_label = label;
|
|
Bind(wxEVT_PAINT, &pxStaticText::paintEvent, this);
|
|
}
|
|
|
|
// we need to refresh the window after changing its size as the standard
|
|
// control doesn't always update itself properly (fials typically on window resizes where
|
|
// the control is expanded to fit -- ie the control's size changes but the position does not)
|
|
void pxStaticText::DoSetSize(int x, int y, int w, int h, int sizeFlags)
|
|
{
|
|
_parent::DoSetSize(x, y, w, h, sizeFlags);
|
|
Refresh();
|
|
}
|
|
|
|
void pxStaticText::SetPaddingDefaults()
|
|
{
|
|
m_paddingPix_horiz = 7;
|
|
m_paddingPix_vert = 1;
|
|
|
|
m_paddingPct_horiz = 0.0f;
|
|
m_paddingPct_vert = 0.0f;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::SetMinWidth(int width)
|
|
{
|
|
SetMinSize(wxSize(width, GetMinHeight()));
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::SetMinHeight(int height)
|
|
{
|
|
SetMinSize(wxSize(GetMinWidth(), height));
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::SetHeight(int lines)
|
|
{
|
|
if (!pxAssert(lines > 0))
|
|
lines = 2;
|
|
m_heightInLines = lines;
|
|
|
|
const int newHeight = (pxGetCharHeight(this) * m_heightInLines) + (m_paddingPix_vert * 2);
|
|
SetMinSize(wxSize(GetMinWidth(), newHeight));
|
|
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::Align(wxAlignment align)
|
|
{
|
|
m_align = align;
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::Bold()
|
|
{
|
|
wxFont bold(GetFont());
|
|
bold.SetWeight(wxFONTWEIGHT_BOLD);
|
|
SetFont(bold);
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::PaddingPixH(int pixels)
|
|
{
|
|
m_paddingPix_horiz = pixels;
|
|
UpdateWrapping(false);
|
|
Refresh();
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::PaddingPixV(int pixels)
|
|
{
|
|
m_paddingPix_vert = pixels;
|
|
Refresh();
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::PaddingPctH(float pct)
|
|
{
|
|
pxAssert(pct < 0.5);
|
|
|
|
m_paddingPct_horiz = pct;
|
|
UpdateWrapping(false);
|
|
Refresh();
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::PaddingPctV(float pct)
|
|
{
|
|
pxAssert(pct < 0.5);
|
|
|
|
m_paddingPct_vert = pct;
|
|
Refresh();
|
|
return *this;
|
|
}
|
|
|
|
pxStaticText& pxStaticText::Unwrapped()
|
|
{
|
|
m_autowrap = false;
|
|
UpdateWrapping(false);
|
|
return *this;
|
|
}
|
|
|
|
int pxStaticText::calcPaddingWidth(int newWidth) const
|
|
{
|
|
return (int)(newWidth * m_paddingPct_horiz * 2) + (m_paddingPix_horiz * 2);
|
|
}
|
|
|
|
int pxStaticText::calcPaddingHeight(int newHeight) const
|
|
{
|
|
return (int)(newHeight * m_paddingPct_vert * 2) + (m_paddingPix_vert * 2);
|
|
}
|
|
|
|
wxSize pxStaticText::GetBestWrappedSize(const wxClientDC& dc) const
|
|
{
|
|
pxAssert(m_autowrap);
|
|
|
|
// Find an ideal(-ish) width, based on a search of all parent controls and their
|
|
// valid Minimum sizes.
|
|
|
|
int idealWidth = wxDefaultCoord;
|
|
int parentalAdjust = 0;
|
|
double parentalFactor = 1.0;
|
|
const wxWindow* millrun = this;
|
|
|
|
while (millrun)
|
|
{
|
|
// IMPORTANT : wxWizard changes its min size and then expects everything else
|
|
// to play nice and NOT resize according to the new min size. (wtf stupid)
|
|
// Anyway, this fixes it -- ignore min size specifier on wxWizard!
|
|
if (wxIsKindOf(millrun, wxWizard))
|
|
break;
|
|
|
|
int min = (int)((millrun->GetMinWidth() - parentalAdjust) * parentalFactor);
|
|
|
|
if (min > 0 && ((idealWidth < 0) || (min < idealWidth)))
|
|
{
|
|
idealWidth = min;
|
|
}
|
|
|
|
parentalAdjust += pxSizerFlags::StdPadding * 2;
|
|
millrun = millrun->GetParent();
|
|
}
|
|
|
|
if (idealWidth <= 0)
|
|
{
|
|
// FIXME: The minimum size of this control is unknown, so let's just pick a guess based on
|
|
// the size of the user's display area.
|
|
|
|
idealWidth = (int)(wxGetDisplaySize().GetWidth() * 0.66) - (parentalAdjust * 2);
|
|
}
|
|
|
|
return dc.GetMultiLineTextExtent(pxTextWrapper().Wrap(this, m_label, idealWidth - calcPaddingWidth(idealWidth)).GetResult());
|
|
}
|
|
|
|
pxStaticText& pxStaticText::WrapAt(int width)
|
|
{
|
|
m_autowrap = false;
|
|
|
|
if ((width <= 1) || (width == m_wrappedWidth))
|
|
return *this;
|
|
|
|
wxString wrappedLabel;
|
|
m_wrappedWidth = width;
|
|
|
|
if (width > 1)
|
|
wrappedLabel = pxTextWrapper().Wrap(this, m_label, width).GetResult();
|
|
|
|
if (m_wrappedLabel != wrappedLabel)
|
|
{
|
|
m_wrappedLabel = wrappedLabel;
|
|
wxSize area = wxClientDC(this).GetMultiLineTextExtent(m_wrappedLabel);
|
|
SetMinSize(wxSize(
|
|
area.GetWidth() + calcPaddingWidth(area.GetWidth()),
|
|
area.GetHeight() + calcPaddingHeight(area.GetHeight())));
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool pxStaticText::_updateWrapping(bool textChanged)
|
|
{
|
|
if (!m_autowrap)
|
|
{
|
|
//m_wrappedLabel = wxEmptyString;
|
|
//m_wrappedWidth = -1;
|
|
return false;
|
|
}
|
|
|
|
wxString wrappedLabel;
|
|
int newWidth = GetSize().GetWidth();
|
|
|
|
if (!textChanged && (newWidth == m_wrappedWidth))
|
|
return false;
|
|
|
|
// Note: during various stages of sizer-calc, width can be 1, 0, or -1.
|
|
// We ignore wrapping in these cases. (the PaintEvent also checks the wrapping
|
|
// and updates it if needed, in case the control's size isn't figured out prior
|
|
// to being painted).
|
|
|
|
m_wrappedWidth = newWidth;
|
|
if (m_wrappedWidth > 1)
|
|
wrappedLabel = pxTextWrapper().Wrap(this, m_label, m_wrappedWidth).GetResult();
|
|
|
|
if (m_wrappedLabel == wrappedLabel)
|
|
return false;
|
|
m_wrappedLabel = wrappedLabel;
|
|
|
|
return true;
|
|
}
|
|
|
|
void pxStaticText::UpdateWrapping(bool textChanged)
|
|
{
|
|
if (_updateWrapping(textChanged))
|
|
Refresh();
|
|
}
|
|
|
|
void pxStaticText::SetLabel(const wxString& label)
|
|
{
|
|
const bool labelChanged(label != m_label);
|
|
if (labelChanged)
|
|
{
|
|
m_label = label;
|
|
Refresh();
|
|
}
|
|
|
|
// Always update wrapping, in case window width or something else also changed.
|
|
UpdateWrapping(labelChanged);
|
|
InvalidateBestSize();
|
|
}
|
|
|
|
wxFont pxStaticText::GetFontOk() const
|
|
{
|
|
wxFont font(GetFont());
|
|
if (!font.Ok())
|
|
return wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
|
return font;
|
|
}
|
|
|
|
bool pxStaticText::Enable(bool enabled)
|
|
{
|
|
if (_parent::Enable(enabled))
|
|
{
|
|
Refresh();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void pxStaticText::paintEvent(wxPaintEvent& evt)
|
|
{
|
|
wxPaintDC dc(this);
|
|
const int dcWidth = dc.GetSize().GetWidth();
|
|
const int dcHeight = dc.GetSize().GetHeight();
|
|
if (dcWidth < 1)
|
|
return;
|
|
dc.SetFont(GetFontOk());
|
|
|
|
if (IsEnabled())
|
|
dc.SetTextForeground(GetForegroundColour());
|
|
else
|
|
dc.SetTextForeground(*wxLIGHT_GREY);
|
|
|
|
pxWindowTextWriter writer(dc);
|
|
writer.Align(m_align);
|
|
|
|
const wxString& label(m_autowrap ? m_wrappedLabel : m_label);
|
|
if (m_autowrap)
|
|
_updateWrapping(false);
|
|
|
|
int tWidth, tHeight;
|
|
dc.GetMultiLineTextExtent(label, &tWidth, &tHeight);
|
|
|
|
writer.Align(m_align);
|
|
if (m_align & wxALIGN_CENTER_VERTICAL)
|
|
writer.SetY((dcHeight - tHeight) / 2);
|
|
else
|
|
writer.SetY((int)(dcHeight * m_paddingPct_vert) + m_paddingPix_vert);
|
|
|
|
writer.WriteLn(label); // without formatting please.
|
|
|
|
//dc.SetBrush( *wxTRANSPARENT_BRUSH );
|
|
//dc.DrawRectangle(wxPoint(), dc.GetSize());
|
|
}
|
|
|
|
// Overloaded form wxPanel and friends.
|
|
wxSize pxStaticText::DoGetBestSize() const
|
|
{
|
|
wxClientDC dc(const_cast<pxStaticText*>(this));
|
|
dc.SetFont(GetFontOk());
|
|
|
|
wxSize best;
|
|
|
|
if (m_autowrap)
|
|
{
|
|
best = GetBestWrappedSize(dc);
|
|
//best.x = wxDefaultCoord;
|
|
}
|
|
else
|
|
{
|
|
// No autowrapping, so we can force a specific size here!
|
|
best = dc.GetMultiLineTextExtent(GetLabel());
|
|
best.x += calcPaddingWidth(best.x);
|
|
}
|
|
|
|
best.y += calcPaddingHeight(best.y);
|
|
|
|
CacheBestSize(best);
|
|
return best;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// pxStaticHeading (implementations)
|
|
// --------------------------------------------------------------------------------------
|
|
pxStaticHeading::pxStaticHeading(wxWindow* parent, const wxString& label)
|
|
: _parent(parent)
|
|
{
|
|
m_align = wxALIGN_CENTER;
|
|
|
|
SetPaddingDefaults();
|
|
Init(label);
|
|
}
|
|
|
|
void pxStaticHeading::SetPaddingDefaults()
|
|
{
|
|
m_paddingPix_horiz = 4;
|
|
m_paddingPix_vert = 1;
|
|
|
|
m_paddingPct_horiz = 0.08f;
|
|
m_paddingPct_vert = 0.0f;
|
|
}
|
|
|
|
void operator+=(wxSizer& target, pxStaticText* src)
|
|
{
|
|
if (src)
|
|
target.Add(src, pxExpand);
|
|
}
|
|
|
|
void operator+=(wxSizer& target, pxStaticText& src)
|
|
{
|
|
target.Add(&src, pxExpand);
|
|
}
|
|
|
|
void operator+=(wxSizer* target, pxStaticText& src)
|
|
{
|
|
target->Add(&src, pxExpand);
|
|
}
|