Files
pcsx2/common/src/Utilities/pxStaticText.cpp
T
cottonvibes c05dc759e3 Big gif transfer code rewrite!
Pcsx2 now has a gifUnit class which acts like the ps2's gif and executes a single gif transfer at a time (and performs path arbitration according to priority and path3 slicing).

This new code is generally a speedup for most games. Particularly VU heavy games like GoW.
This revision breaks old saved state compatibility so don't update if you wish to keep playing with your old saved states.
Leave comments if this revision fixes or breaks anything...

Message to GS Plugin authors:
This new code now uses only 1 gif callback to transfer data to the gs plugin (GSgifTransfer).
pcsx2 also is garaunteed to send full GS primitives to the plugin. So you don't have to account for partial-transfers anymore.

Thanks goes out to shadowlady who tested around 500 games for me :D

Note 1: The old gif code is still in this revision, and can be enabled by the USE_OLD_GIF macro. The old code will be deleted soon.
Note 2: This revision also enables assertion dialogs in devel builds, and changed a lot of assume cases into assertions.


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4821 96395faa-99c1-11dd-bbfe-3dabce05a288
2011-07-24 13:02:50 +00:00

379 lines
9.3 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 "PrecompiledHeader.h"
#include "pxStaticText.h"
#include <wx/wizard.h>
// --------------------------------------------------------------------------------------
// pxStaticText (implementations)
// --------------------------------------------------------------------------------------
pxStaticText::pxStaticText( wxWindow* parent )
: _parent( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER )
{
m_heightInLines = 1;
}
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;
Connect( wxEVT_PAINT, wxPaintEventHandler(pxStaticText::paintEvent) );
}
// 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(wxBOLD);
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();
newWidth -= (int)(newWidth*m_paddingPct_horiz*2) + (m_paddingPix_horiz*2);
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 );
}