|
|
|
/*==LICENSE==*
|
|
|
|
|
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools
|
|
|
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
|
|
or by snail mail at:
|
|
|
|
Cyan Worlds, Inc.
|
|
|
|
14617 N Newport Hwy
|
|
|
|
Mead, WA 99021
|
|
|
|
|
|
|
|
*==LICENSE==*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// //
|
|
|
|
// pfGUIListElement Class Definitions //
|
|
|
|
// //
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "hsTypes.h"
|
|
|
|
#include "pfGUIListElement.h"
|
|
|
|
#include "pfGameGUIMgr.h"
|
|
|
|
|
|
|
|
#include "pfGUIPopUpMenu.h" // For skins
|
|
|
|
|
|
|
|
#include "plGImage/plDynamicTextMap.h"
|
|
|
|
#include "plGImage/hsCodecManager.h"
|
|
|
|
#include "plPipeline/plDebugText.h" // To quickly and hackily get the screen size in pixels
|
|
|
|
#include "hsResMgr.h"
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//// Base Stuff //////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfGUIListElement::Read( hsStream *s, hsResMgr *mgr )
|
|
|
|
{
|
|
|
|
fSelected = s->ReadBool();
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListElement::Write( hsStream *s, hsResMgr *mgr )
|
|
|
|
{
|
|
|
|
s->WriteBool( fSelected );
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//// pfGUIListText ///////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//// Constructor/Destructor //////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pfGUIListText::pfGUIListText() : pfGUIListElement( kText )
|
|
|
|
{
|
|
|
|
fText = nil;
|
|
|
|
fJustify = kLeftJustify;
|
|
|
|
}
|
|
|
|
|
|
|
|
pfGUIListText::pfGUIListText( const char *text ) : pfGUIListElement( kText )
|
|
|
|
{
|
|
|
|
fText = hsStringToWString(text);
|
|
|
|
fJustify = kLeftJustify;
|
|
|
|
}
|
|
|
|
|
|
|
|
pfGUIListText::pfGUIListText( const wchar_t *text ) : pfGUIListElement( kText )
|
|
|
|
{
|
|
|
|
fText = TRACKED_NEW wchar_t[ wcslen( text ) + 1 ];
|
|
|
|
wcscpy( fText, text );
|
|
|
|
fJustify = kLeftJustify;
|
|
|
|
}
|
|
|
|
|
|
|
|
pfGUIListText::~pfGUIListText()
|
|
|
|
{
|
|
|
|
delete [] fText;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Virtuals ////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfGUIListText::Read( hsStream *s, hsResMgr *mgr )
|
|
|
|
{
|
|
|
|
pfGUIListElement::Read( s, mgr );
|
|
|
|
|
|
|
|
char *text = s->ReadSafeString();
|
|
|
|
fText = hsStringToWString(text);
|
|
|
|
delete [] text;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListText::Write( hsStream *s, hsResMgr *mgr )
|
|
|
|
{
|
|
|
|
pfGUIListElement::Write( s, mgr );
|
|
|
|
|
|
|
|
char *text = hsWStringToString(fText);
|
|
|
|
s->WriteSafeString(text);
|
|
|
|
delete [] text;
|
|
|
|
}
|
|
|
|
|
|
|
|
hsBool pfGUIListText::Draw( plDynamicTextMap *textGen, UInt16 x, UInt16 y, UInt16 maxWidth, UInt16 maxHeight )
|
|
|
|
{
|
|
|
|
textGen->SetJustify( (plDynamicTextMap::Justify)fJustify );
|
|
|
|
if( fSelected )
|
|
|
|
{
|
|
|
|
textGen->FillRect( x, y, maxWidth, maxHeight, fColors->fSelBackColor );
|
|
|
|
textGen->SetTextColor( fColors->fSelForeColor, fColors->fTransparent && fColors->fSelBackColor.a == 0.f );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Normal back color will be cleared for us
|
|
|
|
textGen->SetTextColor( fColors->fForeColor, fColors->fTransparent && fColors->fBackColor.a == 0.f );
|
|
|
|
}
|
|
|
|
|
|
|
|
textGen->DrawClippedString( x + 4, y, GetText(), maxWidth - 8, maxHeight );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListText::GetSize( plDynamicTextMap *textGen, UInt16 *width, UInt16 *height )
|
|
|
|
{
|
|
|
|
*width = textGen->CalcStringWidth( GetText(), height );
|
|
|
|
if( height != nil )
|
|
|
|
{
|
|
|
|
if( *height == 0 )
|
|
|
|
*height = 10; // Never allow zero height elements
|
|
|
|
else
|
|
|
|
*height += 0; // Add one pixel on each side for padding (or not, 3.21.02 mcn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int pfGUIListText::CompareTo( pfGUIListElement *rightSide )
|
|
|
|
{
|
|
|
|
pfGUIListText *text = (pfGUIListText *)rightSide;
|
|
|
|
|
|
|
|
if( text->fType != kText )
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
return wcscmp( GetText(), text->GetText() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListText::SetText( const char *text )
|
|
|
|
{
|
|
|
|
wchar_t *wText = hsStringToWString(text);
|
|
|
|
SetText(wText);
|
|
|
|
delete [] wText;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListText::SetText( const wchar_t *text )
|
|
|
|
{
|
|
|
|
delete [] fText;
|
|
|
|
if( text != nil )
|
|
|
|
{
|
|
|
|
fText = TRACKED_NEW wchar_t[ wcslen( text ) + 1 ];
|
|
|
|
wcscpy( fText, text );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fText = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListText::SetJustify( JustifyTypes justify )
|
|
|
|
{
|
|
|
|
switch( justify )
|
|
|
|
{
|
|
|
|
case kRightJustify:
|
|
|
|
fJustify = plDynamicTextMap::kRightJustify;
|
|
|
|
break;
|
|
|
|
case kCenter:
|
|
|
|
fJustify = plDynamicTextMap::kCenter;
|
|
|
|
break;
|
|
|
|
case kLeftJustify:
|
|
|
|
default:
|
|
|
|
fJustify = plDynamicTextMap::kLeftJustify;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//// pfGUIListPicture ////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//// Constructor/Destructor //////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pfGUIListPicture::pfGUIListPicture() : pfGUIListElement( kPicture )
|
|
|
|
{
|
|
|
|
fBorderSize = 2;
|
|
|
|
fMipmapKey = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
pfGUIListPicture::pfGUIListPicture( plKey mipKey, hsBool respectAlpha ) : pfGUIListElement( kPicture )
|
|
|
|
{
|
|
|
|
fBorderSize = 2;
|
|
|
|
fMipmapKey = mipKey;
|
|
|
|
fRespectAlpha = respectAlpha;
|
|
|
|
|
|
|
|
plMipmap *mip = plMipmap::ConvertNoRef( fMipmapKey->ObjectIsLoaded() );
|
|
|
|
if( mip != nil && mip->IsCompressed() )
|
|
|
|
{
|
|
|
|
// Gotta make and grab an uncompressed one
|
|
|
|
plMipmap *uncompBuffer = hsCodecManager::Instance().CreateUncompressedMipmap( mip, hsCodecManager::k32BitDepth );
|
|
|
|
char str[ 512 ];
|
|
|
|
sprintf( str, "%s_uncomp", mip->GetKeyName() );
|
|
|
|
fMipmapKey = hsgResMgr::ResMgr()->NewKey( str, uncompBuffer, fMipmapKey->GetUoid().GetLocation() );
|
|
|
|
fMipmapKey->RefObject();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pfGUIListPicture::~pfGUIListPicture()
|
|
|
|
{
|
|
|
|
fMipmapKey->UnRefObject();
|
|
|
|
fMipmapKey = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Virtuals ////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfGUIListPicture::Read( hsStream *s, hsResMgr *mgr )
|
|
|
|
{
|
|
|
|
pfGUIListElement::Read( s, mgr );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListPicture::Write( hsStream *s, hsResMgr *mgr )
|
|
|
|
{
|
|
|
|
pfGUIListElement::Write( s, mgr );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
hsBool pfGUIListPicture::Draw( plDynamicTextMap *textGen, UInt16 x, UInt16 y, UInt16 maxWidth, UInt16 maxHeight )
|
|
|
|
{
|
|
|
|
if( fSelected )
|
|
|
|
textGen->FillRect( x, y, maxWidth, maxHeight, fColors->fSelBackColor );
|
|
|
|
|
|
|
|
plMipmap *mip = plMipmap::ConvertNoRef( fMipmapKey->ObjectIsLoaded() );
|
|
|
|
if( mip != nil )
|
|
|
|
{
|
|
|
|
if( mip->GetWidth() + fBorderSize + fBorderSize > maxWidth || mip->GetHeight() + fBorderSize + fBorderSize > maxHeight )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
textGen->DrawImage( x + fBorderSize, y + fBorderSize, mip, fRespectAlpha ? plDynamicTextMap::kImgBlend : plDynamicTextMap::kImgNoAlpha );
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListPicture::GetSize( plDynamicTextMap *textGen, UInt16 *width, UInt16 *height )
|
|
|
|
{
|
|
|
|
plMipmap *mip = plMipmap::ConvertNoRef( fMipmapKey->ObjectIsLoaded() );
|
|
|
|
if( mip == nil )
|
|
|
|
{
|
|
|
|
*width = 16;
|
|
|
|
if( height != nil )
|
|
|
|
*height = 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
*width = (UInt16)(mip->GetWidth() + fBorderSize + fBorderSize);
|
|
|
|
if( height != nil )
|
|
|
|
*height = (UInt16)(mip->GetHeight() + fBorderSize + fBorderSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
int pfGUIListPicture::CompareTo( pfGUIListElement *rightSide )
|
|
|
|
{
|
|
|
|
pfGUIListPicture *text = (pfGUIListPicture *)rightSide;
|
|
|
|
|
|
|
|
if( text->fType != kPicture )
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//// pfGUIListTreeRoot ///////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//// Constructor/Destructor //////////////////////////////////////////////////
|
|
|
|
|
|
|
|
pfGUIListTreeRoot::pfGUIListTreeRoot() : pfGUIListElement( kTreeRoot )
|
|
|
|
{
|
|
|
|
fText = nil;
|
|
|
|
fShowChildren = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
pfGUIListTreeRoot::pfGUIListTreeRoot( const char *text ) : pfGUIListElement( kTreeRoot )
|
|
|
|
{
|
|
|
|
fText = hsStringToWString(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
pfGUIListTreeRoot::pfGUIListTreeRoot( const wchar_t *text ) : pfGUIListElement( kTreeRoot )
|
|
|
|
{
|
|
|
|
fText = TRACKED_NEW wchar_t[ wcslen( text ) + 1 ];
|
|
|
|
wcscpy( fText, text );
|
|
|
|
}
|
|
|
|
|
|
|
|
pfGUIListTreeRoot::~pfGUIListTreeRoot()
|
|
|
|
{
|
|
|
|
delete [] fText;
|
|
|
|
}
|
|
|
|
|
|
|
|
//// Virtuals ////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::Read( hsStream *s, hsResMgr *mgr )
|
|
|
|
{
|
|
|
|
pfGUIListElement::Read( s, mgr );
|
|
|
|
|
|
|
|
char *temp = s->ReadSafeString();
|
|
|
|
fText = hsStringToWString(temp);
|
|
|
|
delete [] temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::Write( hsStream *s, hsResMgr *mgr )
|
|
|
|
{
|
|
|
|
pfGUIListElement::Write( s, mgr );
|
|
|
|
|
|
|
|
char *temp = hsWStringToString(fText);
|
|
|
|
s->WriteSafeString( temp );
|
|
|
|
delete [] temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
hsBool pfGUIListTreeRoot::Draw( plDynamicTextMap *textGen, UInt16 x, UInt16 y, UInt16 maxWidth, UInt16 maxHeight )
|
|
|
|
{
|
|
|
|
textGen->SetJustify( plDynamicTextMap::kLeftJustify );
|
|
|
|
if( fSelected )
|
|
|
|
{
|
|
|
|
textGen->FillRect( x, y, maxWidth, maxHeight, fColors->fSelBackColor );
|
|
|
|
textGen->SetTextColor( fColors->fSelForeColor, fColors->fTransparent && fColors->fSelBackColor.a == 0.f );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Normal back color will be cleared for us
|
|
|
|
textGen->SetTextColor( fColors->fForeColor, fColors->fTransparent && fColors->fBackColor.a == 0.f );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fSkin != nil )
|
|
|
|
{
|
|
|
|
const pfGUISkin::pfSRect &r = fSkin->GetElement( fShowChildren ? pfGUISkin::kTreeButtonOpen : pfGUISkin::kTreeButtonClosed );
|
|
|
|
|
|
|
|
Int16 e = ( maxHeight - r.fHeight );
|
|
|
|
if( e < 0 )
|
|
|
|
e = 0;
|
|
|
|
e >>= 1;
|
|
|
|
|
|
|
|
textGen->DrawClippedImage( x + 2, y + e, fSkin->GetTexture(), r.fX, r.fY, r.fWidth, r.fHeight, plDynamicTextMap::kImgSprite );
|
|
|
|
x += r.fWidth + 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
textGen->DrawClippedString( x + 4, y, GetTitle(), maxWidth - 8, maxHeight );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
hsBool pfGUIListTreeRoot::MouseClicked( UInt16 localX, UInt16 localY )
|
|
|
|
{
|
|
|
|
if( fSkin != nil )
|
|
|
|
{
|
|
|
|
const pfGUISkin::pfSRect &r = fSkin->GetElement( fShowChildren ? pfGUISkin::kTreeButtonOpen : pfGUISkin::kTreeButtonClosed );
|
|
|
|
|
|
|
|
// For now, I can't think of a clean way of getting the current visible height to this function,
|
|
|
|
// but just testing the X value for tree controls is good enough for now. If we need Y testing for
|
|
|
|
// other elements, I'll figure out something.
|
|
|
|
if( localX >= 2 && localX <= 2 + r.fWidth )
|
|
|
|
{
|
|
|
|
ShowChildren( !fShowChildren );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::GetSize( plDynamicTextMap *textGen, UInt16 *width, UInt16 *height )
|
|
|
|
{
|
|
|
|
*width = textGen->CalcStringWidth( GetTitle(), height );
|
|
|
|
if( height != nil )
|
|
|
|
{
|
|
|
|
if( *height == 0 )
|
|
|
|
*height = 10; // Never allow zero height elements
|
|
|
|
else
|
|
|
|
*height += 0; // Add one pixel on each side for padding (or not, 3.21.02 mcn)
|
|
|
|
|
|
|
|
if( fSkin != nil )
|
|
|
|
{
|
|
|
|
UInt16 h = fSkin->GetElement( pfGUISkin::kTreeButtonClosed ).fHeight;
|
|
|
|
if( *height < h )
|
|
|
|
*height = h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fSkin != nil )
|
|
|
|
*width += fSkin->GetElement( pfGUISkin::kTreeButtonClosed ).fWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pfGUIListTreeRoot::CompareTo( pfGUIListElement *rightSide )
|
|
|
|
{
|
|
|
|
pfGUIListTreeRoot *text = (pfGUIListTreeRoot *)rightSide;
|
|
|
|
|
|
|
|
if( text->fType != kTreeRoot )
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
return wcscmp( GetTitle(), text->GetTitle() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::SetTitle( const char *text )
|
|
|
|
{
|
|
|
|
wchar_t *wText = hsStringToWString(text);
|
|
|
|
SetTitle(wText);
|
|
|
|
delete [] wText;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::SetTitle( const wchar_t *text )
|
|
|
|
{
|
|
|
|
delete [] fText;
|
|
|
|
if( text != nil )
|
|
|
|
{
|
|
|
|
fText = TRACKED_NEW wchar_t[ wcslen( text ) + 1 ];
|
|
|
|
wcscpy( fText, text );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fText = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::AddChild( pfGUIListElement *el )
|
|
|
|
{
|
|
|
|
fChildren.Append( el );
|
|
|
|
el->SetIndentLevel( GetIndentLevel() + 1 );
|
|
|
|
el->SetCollapsed( !fShowChildren );
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::RemoveChild( UInt32 idx )
|
|
|
|
{
|
|
|
|
fChildren.Remove( idx );
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::ShowChildren( hsBool s )
|
|
|
|
{
|
|
|
|
UInt32 i;
|
|
|
|
|
|
|
|
|
|
|
|
fShowChildren = s;
|
|
|
|
for( i = 0; i < fChildren.GetCount(); i++ )
|
|
|
|
fChildren[ i ]->SetCollapsed( !s );
|
|
|
|
}
|
|
|
|
|
|
|
|
void pfGUIListTreeRoot::SetCollapsed( hsBool c )
|
|
|
|
{
|
|
|
|
UInt32 i;
|
|
|
|
|
|
|
|
|
|
|
|
pfGUIListElement::SetCollapsed( c );
|
|
|
|
for( i = 0; i < fChildren.GetCount(); i++ )
|
|
|
|
fChildren[ i ]->SetCollapsed( c ? true : !fShowChildren );
|
|
|
|
}
|