2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -04:00

CWE Directory Reorganization

Rearrange directory structure of CWE to be loosely equivalent to
the H'uru Plasma repository.

Part 1: Movement of directories and files.
This commit is contained in:
rarified
2021-05-15 12:49:46 -06:00
parent c3f4a640a3
commit 96903e8dca
4002 changed files with 159 additions and 644 deletions

View File

@ -0,0 +1,408 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIButtonMod Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIButtonMod.h"
#include "pfGUIDraggableMod.h"
#include "pfGameGUIMgr.h"
#include "pfGUIControlHandlers.h"
#include "pfGUIDialogMod.h"
#include "../plInputCore/plInputInterface.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plAvatar/plAGModifier.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Control Proc For Managing the Draggable /////////////////////////////////
class pfGUIButtonDragProc : public pfGUICtrlProcObject
{
protected:
pfGUICtrlProcObject *fOrigProc;
pfGUIButtonMod *fParent;
pfGUIDraggableMod *fDraggable;
hsBool fReportDrag;
public:
pfGUIButtonDragProc( pfGUIButtonMod *parent, pfGUIDraggableMod *draggable, pfGUICtrlProcObject *origProc, hsBool reportDrag )
{
fParent = parent;
fDraggable = draggable;
fOrigProc = origProc;
fReportDrag = reportDrag;
}
virtual void DoSomething( pfGUIControlMod *ctrl )
{
// The draggable was let up, so now we stop dragging, disable the draggable again, and pass
// on the event to our original proc
if( fOrigProc != nil && fParent->IsTriggering() )
fOrigProc->DoSomething( ctrl );
if (!fParent->IsButtonDown())
fParent->StopDragging( false );
}
virtual void HandleExtendedEvent( pfGUIControlMod *ctrl, UInt32 event )
{
if( event == pfGUIDraggableMod::kDragging )
{
// First test if we're inside our button (if so, we stop dragging)
if( fParent->PointInBounds( fDraggable->GetLastMousePt() ) )
{
// Cancel the drag
fParent->StopDragging( true );
return;
}
if( !fReportDrag )
return;
}
if( fOrigProc != nil )
fOrigProc->HandleExtendedEvent( ctrl, event );
}
virtual void UserCallback( UInt32 userValue )
{
if( fOrigProc != nil )
fOrigProc->UserCallback( userValue );
}
};
void pfGUIButtonMod::StopDragging( hsBool cancel )
{
fDraggable->StopDragging( cancel );
fDraggable->SetVisible( false );
fDraggable->SetHandler( fOrigHandler );
fOrigHandler = nil;
if( !fOrigReportedDrag )
fDraggable->ClearFlag( pfGUIDraggableMod::kReportDragging );
// Steal interest back
fDialog->SetControlOfInterest( this );
}
void pfGUIButtonMod::StartDragging( void )
{
fOrigReportedDrag = fDraggable->HasFlag( pfGUIDraggableMod::kReportDragging );
fDraggable->SetFlag( pfGUIDraggableMod::kReportDragging );
fOrigHandler = fDraggable->GetHandler();
fDraggable->SetVisible( true );
fDraggable->SetHandler( TRACKED_NEW pfGUIButtonDragProc( this, fDraggable, fOrigHandler, fOrigReportedDrag ) );
fDraggable->HandleMouseDown( fOrigMouseDownPt, 0 );
}
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIButtonMod::pfGUIButtonMod()
{
fAnimName = nil;
fMouseOverAnimName = nil;
fDraggable = nil;
fOrigHandler = nil;
fClicking = false;
fTriggering = false;
fNotifyType = kNotifyOnUp;
SetFlag( kWantsInterest );
}
pfGUIButtonMod::~pfGUIButtonMod()
{
delete [] fAnimName;
delete [] fMouseOverAnimName;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIButtonMod::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIButtonMod::MsgReceive( plMessage *msg )
{
plGenRefMsg *refMsg = plGenRefMsg::ConvertNoRef( msg );
if( refMsg != nil && refMsg->fType == kRefDraggable )
{
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
{
fDraggable = pfGUIDraggableMod::ConvertNoRef( refMsg->GetRef() );
fDraggable->SetVisible( false ); // Disable until we're dragging
}
else
fDraggable = nil;
return true;
}
return pfGUIControlMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIButtonMod::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
fAnimationKeys.Reset();
UInt32 i, count = s->ReadSwap32();
for( i = 0; i < count; i++ )
fAnimationKeys.Append( mgr->ReadKey( s ) );
fAnimName = s->ReadSafeString();
fMouseOverAnimKeys.Reset();
count = s->ReadSwap32();
for( i = 0; i < count; i++ )
fMouseOverAnimKeys.Append( mgr->ReadKey( s ) );
fMouseOverAnimName = s->ReadSafeString();
fNotifyType = s->ReadSwap32();
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefDraggable ), plRefFlags::kActiveRef );
}
void pfGUIButtonMod::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Write( s, mgr );
UInt32 i, count = fAnimationKeys.GetCount();
s->WriteSwap32( count );
for( i = 0; i < count; i++ )
mgr->WriteKey( s, fAnimationKeys[ i ] );
s->WriteSafeString( fAnimName );
count = fMouseOverAnimKeys.GetCount();
s->WriteSwap32( count );
for( i = 0; i < count; i++ )
mgr->WriteKey( s, fMouseOverAnimKeys[ i ] );
s->WriteSafeString( fMouseOverAnimName );
s->WriteSwap32( fNotifyType );
mgr->WriteKey( s, fDraggable != nil ? fDraggable->GetKey() : nil );
}
//// UpdateBounds ////////////////////////////////////////////////////////////
void pfGUIButtonMod::UpdateBounds( hsMatrix44 *invXformMatrix, hsBool force )
{
pfGUIControlMod::UpdateBounds( invXformMatrix, force );
if( fAnimationKeys.GetCount() > 0 || fMouseOverAnimKeys.GetCount() > 0 )
fBoundsValid = false;
}
//// HandleMouseDown/Up //////////////////////////////////////////////////////
void pfGUIButtonMod::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
fClicking = true;
if( fAnimationKeys.GetCount() > 0 )
{
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
msg->SetCmd( plAnimCmdMsg::kContinue );
msg->SetCmd( plAnimCmdMsg::kSetForewards );
msg->SetCmd( plAnimCmdMsg::kGoToBegin );
msg->SetAnimName( fAnimName );
msg->AddReceivers( fAnimationKeys );
plgDispatch::MsgSend( msg );
}
IPlaySound( kMouseDown );
fOrigMouseDownPt = mousePt;
if ( fNotifyType == kNotifyOnDown || fNotifyType == kNotifyOnUpAndDown)
{
fTriggering = true;
DoSomething();
fTriggering = false;
}
}
void pfGUIButtonMod::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
// make sure that we got the down click first
if ( !fClicking )
return;
fClicking = false;
if( fAnimationKeys.GetCount() > 0 )
{
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
msg->SetCmd( plAnimCmdMsg::kContinue );
msg->SetCmd( plAnimCmdMsg::kSetBackwards );
msg->SetCmd( plAnimCmdMsg::kGoToEnd );
msg->SetAnimName( fAnimName );
msg->AddReceivers( fAnimationKeys );
plgDispatch::MsgSend( msg );
}
IPlaySound( kMouseUp );
// Don't run the command if the mouse is outside our bounds
if( !fBounds.IsInside( &mousePt ) && fNotifyType != kNotifyOnUpAndDown )
return;
if ( fNotifyType == kNotifyOnUp || fNotifyType == kNotifyOnUpAndDown)
fTriggering = true;
DoSomething();
fTriggering = false;
}
void pfGUIButtonMod::HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers )
{
if( !fClicking )
return;
if( fDraggable == nil )
return;
if( !fDraggable->IsVisible() )
{
// Are we outside ourselves?
if( !PointInBounds( mousePt ) )
{
// Yes, start dragging
StartDragging();
// Hand off our interest to the draggable
fDialog->SetControlOfInterest( fDraggable );
}
}
}
void pfGUIButtonMod::SetNotifyType(Int32 kind)
{
fNotifyType = kind;
}
Int32 pfGUIButtonMod::GetNotifyType()
{
return fNotifyType;
}
hsBool pfGUIButtonMod::IsButtonDown()
{
return fClicking;
}
//// SetInteresting //////////////////////////////////////////////////////////
// Overridden to play mouse over animation when we're interesting
void pfGUIButtonMod::SetInteresting( hsBool i )
{
pfGUIControlMod::SetInteresting( i );
if( fMouseOverAnimKeys.GetCount() )
{
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
msg->SetCmd( plAnimCmdMsg::kContinue );
msg->SetCmd( fInteresting ? plAnimCmdMsg::kSetForewards : plAnimCmdMsg::kSetBackwards );
msg->SetAnimName( fMouseOverAnimName );
msg->AddReceivers( fMouseOverAnimKeys );
plgDispatch::MsgSend( msg );
}
if( i )
IPlaySound( kMouseOver );
else
IPlaySound( kMouseOff );
}
void pfGUIButtonMod::SetAnimationKeys( hsTArray<plKey> &keys, const char *name )
{
fAnimationKeys = keys;
delete [] fAnimName;
if( name != nil )
{
fAnimName = TRACKED_NEW char[ strlen( name ) + 1 ];
strcpy( fAnimName, name );
}
else
fAnimName = nil;
}
void pfGUIButtonMod::SetMouseOverAnimKeys( hsTArray<plKey> &keys, const char *name )
{
fMouseOverAnimKeys = keys;
delete [] fMouseOverAnimName;
if( name != nil )
{
fMouseOverAnimName = TRACKED_NEW char[ strlen( name ) + 1 ];
strcpy( fMouseOverAnimName, name );
}
else
fMouseOverAnimName = nil;
}
//// IGetDesiredCursor ///////////////////////////////////////////////////////
UInt32 pfGUIButtonMod::IGetDesiredCursor( void ) const
{
if( fHandler == nil )
return 0;
if( fClicking )
return plInputInterface::kCursorClicked;
return plInputInterface::kCursorPoised;
}

View File

@ -0,0 +1,137 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIButtonMod Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIButtonMod_h
#define _pfGUIButtonMod_h
#include "pfGUIControlMod.h"
class plMessage;
class plPostEffectMod;
class plAGMasterMod;
class pfGUIDraggableMod;
class pfGUIButtonMod : public pfGUIControlMod
{
protected:
hsTArray<plKey> fAnimationKeys;
char *fAnimName;
hsTArray<plKey> fMouseOverAnimKeys;
char *fMouseOverAnimName;
hsBool fClicking;
hsBool fTriggering;
hsPoint3 fOrigMouseDownPt;
pfGUIDraggableMod *fDraggable;
pfGUICtrlProcObject *fOrigHandler;
hsBool fOrigReportedDrag;
Int32 fNotifyType;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual UInt32 IGetDesiredCursor( void ) const; // As specified in plInputInterface.h
public:
pfGUIButtonMod();
virtual ~pfGUIButtonMod();
CLASSNAME_REGISTER( pfGUIButtonMod );
GETINTERFACE_ANY( pfGUIButtonMod, pfGUIControlMod );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void SetInteresting( hsBool i );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual void UpdateBounds( hsMatrix44 *invXformMatrix = nil, hsBool force = false );
virtual void SetNotifyType(Int32 kind);
virtual Int32 GetNotifyType();
virtual hsBool IsButtonDown();
virtual hsBool IsTriggering() { return fTriggering; }
enum SoundEvents
{
kMouseDown,
kMouseUp,
kMouseOver,
kMouseOff
};
enum
{
kRefDraggable = kRefDerivedStart
};
enum NotifyType
{
kNotifyOnUp = 0,
kNotifyOnDown,
kNotifyOnUpAndDown
};
void StartDragging( void );
void StopDragging( hsBool cancel );
// Export only
void SetAnimationKeys( hsTArray<plKey> &keys, const char *name );
void SetMouseOverAnimKeys( hsTArray<plKey> &keys, const char *name );
};
#endif // _pfGUIButtonMod_h

View File

@ -0,0 +1,222 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUICheckBoxCtrl Definition //
// //
// Almost like buttons, only they keep their stated (pressed/unpressed) //
// when you click them, instead of reverting on mouse up. //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUICheckBoxCtrl.h"
#include "pfGameGUIMgr.h"
#include "../plInputCore/plInputInterface.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plAvatar/plAGModifier.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUICheckBoxCtrl::pfGUICheckBoxCtrl()
{
fAnimName = nil;
SetFlag( kWantsInterest );
fChecked = false;
fClicking = false;
fPlaySound = true;
}
pfGUICheckBoxCtrl::~pfGUICheckBoxCtrl()
{
delete [] fAnimName;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUICheckBoxCtrl::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUICheckBoxCtrl::MsgReceive( plMessage *msg )
{
return pfGUIControlMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUICheckBoxCtrl::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
fAnimationKeys.Reset();
UInt32 i, count = s->ReadSwap32();
for( i = 0; i < count; i++ )
fAnimationKeys.Append( mgr->ReadKey( s ) );
fAnimName = s->ReadSafeString();
fChecked = s->ReadBool();
}
void pfGUICheckBoxCtrl::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Write( s, mgr );
UInt32 i, count = fAnimationKeys.GetCount();
s->WriteSwap32( count );
for( i = 0; i < count; i++ )
mgr->WriteKey( s, fAnimationKeys[ i ] );
s->WriteSafeString( fAnimName );
s->WriteBool( fChecked );
}
//// UpdateBounds ////////////////////////////////////////////////////////////
void pfGUICheckBoxCtrl::UpdateBounds( hsMatrix44 *invXformMatrix, hsBool force )
{
pfGUIControlMod::UpdateBounds( invXformMatrix, force );
if( fAnimationKeys.GetCount() > 0 )
fBoundsValid = false;
}
//// HandleMouseDown/Up //////////////////////////////////////////////////////
void pfGUICheckBoxCtrl::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
fClicking = true;
if(fPlaySound)
IPlaySound( kMouseDown );
}
void pfGUICheckBoxCtrl::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
if( fClicking )
{
fClicking = false;
if(fPlaySound)
IPlaySound( kMouseUp );
// Don't run the command if the mouse is outside our bounds
if( fBounds.IsInside( &mousePt ) )
{
SetChecked( !fChecked );
DoSomething();
}
}
}
//// SetChecked //////////////////////////////////////////////////////////////
void pfGUICheckBoxCtrl::SetChecked( hsBool checked, hsBool immediate /*= false*/ )
{
fChecked = checked;
if( fAnimationKeys.GetCount() > 0 )
{
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
if( fChecked )
{
// Moving to true
if( immediate )
{
msg->SetCmd( plAnimCmdMsg::kGoToEnd );
}
else
{
msg->SetCmd( plAnimCmdMsg::kContinue );
msg->SetCmd( plAnimCmdMsg::kSetForewards );
msg->SetCmd( plAnimCmdMsg::kGoToBegin );
}
}
else
{
// Moving to false
if( immediate )
{
msg->SetCmd( plAnimCmdMsg::kGoToBegin );
}
else
{
msg->SetCmd( plAnimCmdMsg::kContinue );
msg->SetCmd( plAnimCmdMsg::kSetBackwards );
msg->SetCmd( plAnimCmdMsg::kGoToEnd );
}
}
msg->SetAnimName( fAnimName );
msg->AddReceivers( fAnimationKeys );
plgDispatch::MsgSend( msg );
}
}
void pfGUICheckBoxCtrl::SetAnimationKeys( hsTArray<plKey> &keys, const char *name )
{
fAnimationKeys = keys;
delete [] fAnimName;
if( name != nil )
{
fAnimName = TRACKED_NEW char[ strlen( name ) + 1 ];
strcpy( fAnimName, name );
}
else
fAnimName = nil;
}
//// IGetDesiredCursor ///////////////////////////////////////////////////////
UInt32 pfGUICheckBoxCtrl::IGetDesiredCursor( void ) const
{
if( fClicking )
return plInputInterface::kCursorClicked;
return plInputInterface::kCursorPoised;
}

View File

@ -0,0 +1,111 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUICheckBoxCtrl Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUICheckBoxCtrl_h
#define _pfGUICheckBoxCtrl_h
#include "pfGUIControlMod.h"
class plMessage;
class plPostEffectMod;
class plAGMasterMod;
class pfGUICheckBoxCtrl : public pfGUIControlMod
{
protected:
hsTArray<plKey> fAnimationKeys;
char *fAnimName;
hsBool fClicking;
hsBool fChecked;
hsBool fPlaySound;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual UInt32 IGetDesiredCursor( void ) const; // As specified in plInputInterface.h
public:
pfGUICheckBoxCtrl();
virtual ~pfGUICheckBoxCtrl();
CLASSNAME_REGISTER( pfGUICheckBoxCtrl );
GETINTERFACE_ANY( pfGUICheckBoxCtrl, pfGUIControlMod );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void UpdateBounds( hsMatrix44 *invXformMatrix = nil, hsBool force = false );
void SetChecked( hsBool checked, hsBool immediate = false );
hsBool IsChecked( void ) { return fChecked; }
void DontPlaySounds() { fPlaySound = false; } // should the checkbox play sounds?
const hsTArray<plKey> &GetAnimationKeys( void ) const { return fAnimationKeys; }
const char *GetAnimationName( void ) const { return fAnimName; }
enum SoundEvents
{
kMouseDown,
kMouseUp,
kMouseOver,
kMouseOff
};
// Export only
void SetAnimationKeys( hsTArray<plKey> &keys, const char *name );
};
#endif // _pfGUICheckBoxCtrl_h

View File

@ -0,0 +1,146 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIClickMapCtrl Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIClickMapCtrl.h"
#include "pfGameGUIMgr.h"
#include "pfGUIDialogMod.h"
#include "../plInputCore/plInputInterface.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIClickMapCtrl::pfGUIClickMapCtrl()
{
fTracking = false;
fCustomCursor = -1;
}
pfGUIClickMapCtrl::~pfGUIClickMapCtrl()
{
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIClickMapCtrl::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIClickMapCtrl::MsgReceive( plMessage *msg )
{
return pfGUIControlMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIClickMapCtrl::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
}
void pfGUIClickMapCtrl::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Write( s, mgr );
}
void pfGUIClickMapCtrl::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
IScreenToLocalPt( mousePt );
fLastMousePt = fLastMouseDragPt = mousePt;
fTracking = true;
}
void pfGUIClickMapCtrl::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
if( fTracking )
{
IScreenToLocalPt( mousePt );
fLastMousePt = fLastMouseUpPt = fLastMouseDragPt = mousePt;
DoSomething();
fTracking = false;
}
}
void pfGUIClickMapCtrl::HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers )
{
if( fTracking )
{
IScreenToLocalPt( mousePt );
fLastMousePt = fLastMouseDragPt = mousePt;
if( HasFlag( kReportDragging ) )
HandleExtendedEvent( kMouseDragged );
}
}
void pfGUIClickMapCtrl::HandleMouseHover( hsPoint3 &mousePt, UInt8 modifiers )
{
IScreenToLocalPt( mousePt );
fLastMousePt = mousePt;
if( HasFlag( kReportHovering ) )
HandleExtendedEvent( kMouseHovered );
}
//// IGetDesiredCursor ///////////////////////////////////////////////////////
UInt32 pfGUIClickMapCtrl::IGetDesiredCursor( void ) const
{
if( fCustomCursor != -1 )
return (UInt32)fCustomCursor;
return plInputInterface::kCursorPoised;
}

View File

@ -0,0 +1,105 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIClickMapCtrl Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIClickMapCtrl_h
#define _pfGUIClickMapCtrl_h
#include "pfGUIControlMod.h"
class plMessage;
class pfGUIClickMapCtrl : public pfGUIControlMod
{
protected:
hsPoint3 fLastMousePt, fLastMouseUpPt, fLastMouseDragPt;
hsBool fTracking;
Int32 fCustomCursor;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual UInt32 IGetDesiredCursor( void ) const; // As specified in plInputInterface.h
public:
pfGUIClickMapCtrl();
virtual ~pfGUIClickMapCtrl();
CLASSNAME_REGISTER( pfGUIClickMapCtrl );
GETINTERFACE_ANY( pfGUIClickMapCtrl, pfGUIControlMod );
enum OurFlags
{
kReportDragging = kDerivedFlagsStart,
kReportHovering
};
// Extended event types
enum ExtendedEvents
{
kMouseDragged,
kMouseHovered
};
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseHover( hsPoint3 &mousePt, UInt8 modifiers );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
const hsPoint3 &GetLastMousePt( void ) const { return fLastMousePt; }
const hsPoint3 &GetLastMouseUpPt( void ) const { return fLastMouseUpPt; }
const hsPoint3 &GetLastMouseDragPt( void ) const { return fLastMouseDragPt; }
void SetCustomCursor( Int32 cursor = -1 ) { fCustomCursor = cursor; }
};
#endif // _pfGUIClickMapCtrl_h

View File

@ -0,0 +1,202 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIControl Handler Definitions //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIControlHandlers.h"
#include "pfGUIControlMod.h"
#include "pfGUIDialogMod.h"
#include "../plMessage/plConsoleMsg.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Writeable Stuff /////////////////////////////////////////////////////////
void pfGUICtrlProcWriteableObject::Write( pfGUICtrlProcWriteableObject *obj, hsStream *s )
{
if( obj != nil )
{
s->WriteSwap32( obj->fType );
obj->IWrite( s );
}
else
s->WriteSwap32( kNull );
}
pfGUICtrlProcWriteableObject *pfGUICtrlProcWriteableObject::Read( hsStream *s )
{
pfGUICtrlProcWriteableObject *obj;
UInt32 type = s->ReadSwap32();
switch( type )
{
case kConsoleCmd:
obj = TRACKED_NEW pfGUIConsoleCmdProc;
break;
case kPythonScript:
obj = TRACKED_NEW pfGUIPythonScriptProc;
break;
case kCloseDlg:
obj = TRACKED_NEW pfGUICloseDlgProc;
break;
case kNull:
return nil;
default:
hsAssert( false, "Invalid proc type in Read()" );
return nil;
}
obj->IRead( s );
return obj;
}
//////////////////////////////////////////////////////////////////////////////
//// Predefined Exportables //////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//// pfGUIConsoleCmdProc /////////////////////////////////////////////////////
pfGUIConsoleCmdProc::pfGUIConsoleCmdProc() : pfGUICtrlProcWriteableObject( kConsoleCmd )
{
fCommand = nil;
}
pfGUIConsoleCmdProc::pfGUIConsoleCmdProc( const char *cmd )
: pfGUICtrlProcWriteableObject( kConsoleCmd )
{
fCommand = nil;
SetCommand( cmd );
}
pfGUIConsoleCmdProc::~pfGUIConsoleCmdProc()
{
delete [] fCommand;
}
void pfGUIConsoleCmdProc::IRead( hsStream *s )
{
int i = s->ReadSwap32();
if( i > 0 )
{
fCommand = TRACKED_NEW char[ i + 1 ];
memset( fCommand, 0, i + 1 );
s->Read( i, fCommand );
}
else
fCommand = nil;
}
void pfGUIConsoleCmdProc::IWrite( hsStream *s )
{
if( fCommand != nil )
{
s->WriteSwap32( strlen( fCommand ) );
s->Write( strlen( fCommand ), fCommand );
}
else
s->WriteSwap32( 0 );
}
void pfGUIConsoleCmdProc::DoSomething( pfGUIControlMod *ctrl )
{
if( fCommand != nil )
{
plConsoleMsg *cMsg = TRACKED_NEW plConsoleMsg( plConsoleMsg::kExecuteLine, fCommand );
plgDispatch::MsgSend( cMsg );
}
}
void pfGUIConsoleCmdProc::SetCommand( const char *cmd )
{
delete [] fCommand;
if( cmd == nil )
fCommand = nil;
else
{
fCommand = TRACKED_NEW char[ strlen( cmd ) + 1 ];
memset( fCommand, 0, strlen( cmd ) + 1 );
strcpy( fCommand, cmd );
}
}
//// pfGUIPythonScriptProc ///////////////////////////////////////////////////
pfGUIPythonScriptProc::pfGUIPythonScriptProc() : pfGUICtrlProcWriteableObject( kPythonScript )
{
}
pfGUIPythonScriptProc::~pfGUIPythonScriptProc()
{
}
void pfGUIPythonScriptProc::IRead( hsStream *s )
{
}
void pfGUIPythonScriptProc::IWrite( hsStream *s )
{
}
void pfGUIPythonScriptProc::DoSomething( pfGUIControlMod *ctrl )
{
}
//////////////////////////////////////////////////////////////////////////////
//// Simple Runtime Ones /////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
void pfGUICloseDlgProc::DoSomething( pfGUIControlMod *ctrl )
{
ctrl->GetOwnerDlg()->Hide();
}

View File

@ -0,0 +1,196 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIControlHandlers Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIControlHandlers_h
#define _pfGUIControlHandlers_h
#include "hsStream.h"
//// pfGUICtrlProcObject Definition //////////////////////////////////////////
// Any control which "does something" (buttons, edit boxes on Enter/Return,
// etc) uses this in some form. Basically, each control will have an (optional?)
// pointer to an object derived from this class type. The class has a single
// standard, virtual function that gets called on the "do something" event.
// Derive from this class, override the virtual and set the control's handler
// to your object and you're all set. Kinda like windowProcs wrapped in a
// C++ object.
// Note: there are some predefined objects for simple, common events. See
// below.
// Note the second: DoSomething() takes a parameter--namely, a pointer to
// the control that called it. Thus, you can make one object handle
// several controls by just switch()ing on that parameter and save yourself
// some object creation.
//
// UserCallback() is an additional function for use in communicating between
// procs. Basically, if you want another proc to do something (another dialog),
// and want you to get called once it's done, set the callback on the other
// proc/whatever to you and override UserCallback().
//
// HandleExtendedEvent() is similar to DoSomething(), but is called for extended
// event types, such as value changing (for an edit control while typing) or
// list scrolled. The event parameter is control-type-specific.
//
// Dialogs will use a similar functionality, but with more functions available.
class pfGUIControlMod;
class pfGUICtrlProcObject
{
protected:
UInt32 fRefCnt;
public:
pfGUICtrlProcObject() { fRefCnt = 0; }
virtual ~pfGUICtrlProcObject() { ; }
virtual void DoSomething( pfGUIControlMod *ctrl ) = 0;
virtual void HandleExtendedEvent( pfGUIControlMod *ctrl, UInt32 event ) { ; }
virtual void UserCallback( UInt32 userValue ) { ; }
// ONLY THE GUI SYSTEM SHOULD CALL THESE
void IncRef( void ) { fRefCnt++; }
hsBool DecRef( void ) { fRefCnt--; return ( fRefCnt > 0 ) ? false : true; }
};
//// pfGUICtrlProcWriteableObject ////////////////////////////////////////////
// This one is a read/writeable version of the above. Basically, you can just
// call Read/Write() and it'll do all the mini-functionality of the factory
// stuff so you don't have to worry about the derived type at runtime. Do
// NOT derive from this class for your own handlers; this is just for the
// handfull that will get added on export.
class pfGUICtrlProcWriteableObject : public pfGUICtrlProcObject
{
protected:
UInt32 fType;
virtual void IRead( hsStream *s ) = 0;
virtual void IWrite( hsStream *s ) = 0;
public:
enum Types
{
kNull,
kConsoleCmd,
kPythonScript,
kCloseDlg
};
pfGUICtrlProcWriteableObject() { fType = kNull; }
pfGUICtrlProcWriteableObject( UInt32 type ) : fType( type ) { ; }
virtual ~pfGUICtrlProcWriteableObject() { ; }
virtual void DoSomething( pfGUIControlMod *ctrl ) = 0;
static void Write( pfGUICtrlProcWriteableObject *obj, hsStream *s );
static pfGUICtrlProcWriteableObject *Read( hsStream *s );
};
//// pfGUIConsoleCmdProc /////////////////////////////////////////////////////
// Simply runs the console command specified. Exportable.
class pfGUIConsoleCmdProc : public pfGUICtrlProcWriteableObject
{
protected:
char *fCommand;
virtual void IRead( hsStream *s );
virtual void IWrite( hsStream *s );
public:
pfGUIConsoleCmdProc();
pfGUIConsoleCmdProc( const char *cmd );
virtual ~pfGUIConsoleCmdProc();
virtual void DoSomething( pfGUIControlMod *ctrl );
void SetCommand( const char *cmd );
};
//// pfGUIPythonScriptProc ///////////////////////////////////////////////////
class pfGUIPythonScriptProc : public pfGUICtrlProcWriteableObject
{
protected:
virtual void IRead( hsStream *s );
virtual void IWrite( hsStream *s );
public:
pfGUIPythonScriptProc();
virtual ~pfGUIPythonScriptProc();
virtual void DoSomething( pfGUIControlMod *ctrl );
};
//// Simple Runtime Ones /////////////////////////////////////////////////////
class pfGUICloseDlgProc : public pfGUICtrlProcWriteableObject
{
protected:
virtual void IRead( hsStream *s ) {}
virtual void IWrite( hsStream *s ) {}
public:
pfGUICloseDlgProc() : pfGUICtrlProcWriteableObject( kCloseDlg ) {}
virtual ~pfGUICloseDlgProc() {}
virtual void DoSomething( pfGUIControlMod *ctrl );
};
#endif // _pfGUIControlHandlers_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,268 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIControlMod Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIControlMod_h
#define _pfGUIControlMod_h
#include "../pnModifier/plSingleModifier.h"
#include "hsBounds.h"
#include "../plMessage/plInputEventMsg.h"
#include "pfGameGUIMgr.h"
#include "hsColorRGBA.h"
#include "hsRefCnt.h"
class plMessage;
class plPostEffectMod;
class pfGUIDialogMod;
class pfGUICtrlProcObject;
class pfGUIDropTargetProc;
class plDynamicTextMap;
class plLayerInterface;
//// pfGUIColorScheme ////////////////////////////////////////////////////////
// Tiny helper wrapper for a set of colors used to draw various controls
class pfGUIColorScheme : public hsRefCnt
{
public:
hsColorRGBA fForeColor, fBackColor;
hsColorRGBA fSelForeColor, fSelBackColor;
hsBool fTransparent;
char *fFontFace;
UInt8 fFontSize;
UInt8 fFontFlags;
enum FontFlags
{
kFontBold = 0x01,
kFontItalic = 0x02,
kFontShadowed = 0x04
};
pfGUIColorScheme();
~pfGUIColorScheme();
pfGUIColorScheme( hsColorRGBA &foreColor, hsColorRGBA &backColor );
pfGUIColorScheme( const char *face, UInt8 size, UInt8 fontFlags );
void SetFontFace( const char *face );
void Read( hsStream *s );
void Write( hsStream *s );
hsBool IsBold( void ) { return ( fFontFlags & kFontBold ) ? true : false; }
hsBool IsItalic( void ) { return ( fFontFlags & kFontItalic ) ? true : false; }
hsBool IsShadowed( void ) { return ( fFontFlags & kFontShadowed ) ? true : false; }
protected:
void IReset( void );
};
//// Class Def ///////////////////////////////////////////////////////////////
class pfGUISkin;
class pfGUIControlMod : public plSingleModifier
{
friend class pfGUIDialogMod;
protected:
UInt32 fTagID;
hsBool fEnabled, fFocused, fVisible, fInteresting;
hsBool fNotifyOnInteresting;
pfGUIDialogMod *fDialog;
hsBounds3 fBounds, fInitialBounds; // Z component is 0-1
hsScalar fScreenMinZ; // Closest Z coordinate in screen space
hsPoint3 fScreenCenter;
hsBool fBoundsValid, fCenterValid;
hsMatrix44 fXformMatrix; // Only used for doing drag work, etc.
pfGUICtrlProcObject *fHandler;
pfGUIDropTargetProc *fDropTargetHdlr;
plDynamicTextMap *fDynTextMap; // Some controls use this; for others, it'll be nil
plLayerInterface *fDynTextLayer; // Juse so we can reset the transform. Sheesh!
pfGUIColorScheme *fColorScheme;
plSceneObject *fProxy;
hsTArray<hsPoint3> fBoundsPoints; // For more accurate bounds tests
hsTArray<int> fSoundIndices; // Indices of sounds to trigger on the target SO's audible interface
pfGUISkin *fSkin;
hsBool ISetUpDynTextMap( plPipeline *pipe );
virtual void IPostSetUpDynTextMap( void ) {}
virtual void IGrowDTMDimsToDesiredSize( UInt16 &width, UInt16 &height ) { }
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
void ISetDialog( pfGUIDialogMod *mod ) { fDialog = mod; }
void IScreenToLocalPt( hsPoint3 &pt );
virtual void IUpdate( void ) {;}
void ISetHandler( pfGUICtrlProcObject *h, hsBool clearInheritFlag = false );
void IPlaySound( UInt8 guiCtrlEvent, hsBool loop = false );
void IStopSound( UInt8 guiCtrlEvent );
virtual UInt32 IGetDesiredCursor( void ) const { return 0; } // As specified in plInputInterface.h
public:
pfGUIControlMod();
virtual ~pfGUIControlMod();
CLASSNAME_REGISTER( pfGUIControlMod );
GETINTERFACE_ANY( pfGUIControlMod, plSingleModifier );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
UInt32 GetTagID( void ) { return fTagID; }
virtual void SetEnabled( hsBool e );
virtual hsBool IsEnabled( void ) { return fEnabled; }
virtual void SetFocused( hsBool e );
virtual hsBool IsFocused( void ) { return fFocused; }
virtual void SetVisible( hsBool vis );
virtual hsBool IsVisible( void ) { return fVisible; }
virtual void SetInteresting( hsBool i );
hsBool IsInteresting( void ) { return fInteresting; }
virtual void SetNotifyOnInteresting( hsBool state ) { fNotifyOnInteresting = state; }
pfGUIDialogMod *GetOwnerDlg( void ) { return fDialog; }
virtual void Refresh( void );
virtual void UpdateBounds( hsMatrix44 *invXformMatrix = nil, hsBool force = false );
void SetObjectCenter( hsScalar x, hsScalar y );
virtual hsPoint3 GetObjectCenter() { return fScreenCenter; }
hsScalar GetScreenMinZ( void ) { return fScreenMinZ; }
void CalcInitialBounds( void );
const hsBounds3 &GetBounds( void );
hsBool PointInBounds( const hsPoint3 &point );
virtual void SetTarget( plSceneObject *object );
// Return false if you actually DON'T want the mouse clicked at this point (should only be used for non-rectangular region rejection)
virtual hsBool FilterMousePosition( hsPoint3 &mousePt ) { return true; }
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers ) {;}
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers ) {;}
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers ) {;}
virtual void HandleMouseHover( hsPoint3 &mousePt, UInt8 modifiers ) {;}
virtual void HandleMouseDblClick( hsPoint3 &mousePt, UInt8 modifiers ) {;}
virtual hsBool HandleKeyPress( char key, UInt8 modifiers );
virtual hsBool HandleKeyEvent( pfGameGUIMgr::EventType event, plKeyDef key, UInt8 modifiers );
void SetHandler( pfGUICtrlProcObject *h ) { ISetHandler( h, true ); }
void DoSomething( void ); // Will call the handler
void HandleExtendedEvent( UInt32 event ); // Will call the handler
pfGUICtrlProcObject *GetHandler( void ) const { return fHandler; }
void SetDropTargetHdlr( pfGUIDropTargetProc *drop );
pfGUIDropTargetProc *GetDropTargetHdlr( void ) { return fDropTargetHdlr; }
enum
{
kRefDynTextMap,
kRefDynTextLayer,
kRefProxy,
kRefSkin,
kRefDerivedStart = 32
};
enum Flags // plSingleModifier already has SetFlag()/HasFlag()
{
kWantsInterest,
kInheritProcFromDlg,
kIntangible, // I.E. it doesn't exists on the screen/can't be clicked on.
// Used for group objects like the up/down pair
kXparentBgnd,
kScaleTextWithResolution, // I.E. take up the same space on screen no matter the resolution
kTakesSpecialKeys, // I.E. disable bindings for keys like backspace because we want them
kHasProxy,
kBetterHitTesting,
kDerivedFlagsStart = 32
};
virtual void SetColorScheme( pfGUIColorScheme *newScheme );
pfGUIColorScheme *GetColorScheme( void ) const;
virtual void UpdateColorScheme() { IPostSetUpDynTextMap(); IUpdate(); }
// should be override by specific GUIcontrol
virtual void PurgeDynaTextMapImage() {;}
// Override from plModifier so we can update our bounds
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
// Forces an immediate play of the given GUI control event sound
void PlaySound( UInt8 guiCtrlEvent, hsBool loop = false ) { IPlaySound( guiCtrlEvent, loop ); }
void StopSound( UInt8 guiCtrlEvent ) { IStopSound( guiCtrlEvent ); }
// Export only
void SetTagID( UInt32 id ) { fTagID = id; }
void SetDynTextMap( plLayerInterface *layer, plDynamicTextMap *dynText );
void SetSoundIndex( UInt8 guiCtrlEvent, int soundIndex );
};
#endif // _pfGUIControlMod_h

View File

@ -0,0 +1,524 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUICtrlGenerator Definitions //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUICtrlGenerator.h"
#include "pfGameGUIMgr.h"
#include "pfGUIControlMod.h"
#include "pfGUIDialogMod.h"
#include "pfGUIButtonMod.h"
#include "pfGUIDragBarCtrl.h"
#include "pfGUIControlHandlers.h"
#include "pfGUIMenuItem.h"
#include "../plSurface/hsGMaterial.h"
#include "../plSurface/plLayer.h"
#include "../plGImage/plMipmap.h"
#include "../pnKeyedObject/plFixedKey.h"
#include "../plDrawable/plDrawableSpans.h"
#include "../plDrawable/plDrawableGenerator.h"
#include "../pnSceneObject/plSceneObject.h"
#include "../pnSceneObject/plDrawInterface.h"
#include "../pnSceneObject/plCoordinateInterface.h"
#include "../pnMessage/plIntRefMsg.h"
#include "../pnMessage/plObjRefMsg.h"
#include "../pnMessage/plNodeRefMsg.h"
#include "../plPipeline/plTextGenerator.h"
#include "../plScene/plPostEffectMod.h"
#include "../plScene/plSceneNode.h"
#include "../pnMessage/plClientMsg.h"
#include "../plMessage/plLayRefMsg.h"
#include "../pnMessage/plAttachMsg.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUICtrlGenerator::pfGUICtrlGenerator()
{
strcpy( fFontFace, "Arial" );
fFontSize = 18;
}
pfGUICtrlGenerator::~pfGUICtrlGenerator()
{
Shutdown();
}
void pfGUICtrlGenerator::Shutdown( void )
{
int i;
// Destroy our scene nodes and dialogs
for( i = 0; i < fDynDlgNodes.GetCount(); i++ )
{
pfGameGUIMgr::GetInstance()->UnloadDialog( fDynDialogs[ i ] );
fDynDlgNodes[ i ]->GetKey()->UnRefObject();
}
fDynDlgNodes.Reset();
fDynDialogs.Reset();
for( i = 0; i < fTextGens.GetCount(); i++ )
delete fTextGens[ i ];
fTextGens.Reset();
}
//// Instance ////////////////////////////////////////////////////////////////
pfGUICtrlGenerator &pfGUICtrlGenerator::Instance( void )
{
static pfGUICtrlGenerator myInstance;
return myInstance;
}
//// IGetNextKeyName /////////////////////////////////////////////////////////
void pfGUICtrlGenerator::IGetNextKeyName( char *name, const char *prefix )
{
static UInt32 keyCount = 0;
sprintf( name, "%s%d", prefix, keyCount++ );
}
//// IAddKey /////////////////////////////////////////////////////////////////
plKey pfGUICtrlGenerator::IAddKey( hsKeyedObject *ko, const char *prefix )
{
char keyName[ 128 ];
IGetNextKeyName( keyName, prefix );
return hsgResMgr::ResMgr()->NewKey( keyName, ko, plLocation::kGlobalFixedLoc );
}
//// SetFont /////////////////////////////////////////////////////////////////
void pfGUICtrlGenerator::SetFont( const char *face, UInt16 size )
{
strcpy( fFontFace, face );
fFontSize = size;
}
//// ICreateSolidMaterial ////////////////////////////////////////////////////
// Creates a material with no texture, just color.
hsGMaterial *pfGUICtrlGenerator::ICreateSolidMaterial( hsColorRGBA &color )
{
hsColorRGBA black;
// Create a material with a simple blank layer, fully ambient
hsGMaterial *material = TRACKED_NEW hsGMaterial;
IAddKey( material, "GUIMaterial" );
plLayer *lay = material->MakeBaseLayer();
black.Set( 0.f,0.f,0.f,1.f );
lay->SetRuntimeColor( black );
lay->SetPreshadeColor( black );
lay->SetAmbientColor( color );
return material;
}
//// ICreateTextMaterial /////////////////////////////////////////////////////
// Creates a material with a texture that has a string centered on it.
hsGMaterial *pfGUICtrlGenerator::ICreateTextMaterial( const char *text, hsColorRGBA &bgColor,
hsColorRGBA &textColor, float objWidth, float objHeight )
{
UInt16 pixWidth, pixHeight, strWidth, strHeight;
hsColorRGBA black, white;
// Guess at some pixel width and heights we want. We're guessing b/c we want it to look reasonably
// good on the screen, but we don't know exactly how big is big, so we guess
pixWidth = (UInt16)(objWidth * 64.f);
pixHeight = (UInt16)(objHeight * 64.f);
// Create blank mipmap
plMipmap *bitmap = TRACKED_NEW plMipmap( 1, 1, plMipmap::kRGB32Config, 1 );
IAddKey( bitmap, "GUIMipmap" );
// Create textGen to write string with
plTextGenerator *textGen = TRACKED_NEW plTextGenerator( bitmap, pixWidth, pixHeight );
textGen->SetFont( fFontFace, (UInt16)fFontSize );
textGen->ClearToColor( bgColor );
textGen->SetTextColor( textColor );
strWidth = textGen->CalcStringWidth( text, &strHeight );
textGen->DrawString( ( pixWidth - strWidth ) >> 1, ( pixHeight - strHeight ) >> 1, text );
textGen->FlushToHost();
fTextGens.Append( textGen );
// Create a material with a simple blank layer, fully ambient
hsGMaterial *material = TRACKED_NEW hsGMaterial;
IAddKey( material, "GUIMaterial" );
plLayer *lay = material->MakeBaseLayer();
white.Set( 1.f,1.f,1.f,1.f );
black.Set( 0.f,0.f,0.f,1.f );
lay->SetRuntimeColor( black );
lay->SetPreshadeColor( black );
lay->SetAmbientColor( white );
hsgResMgr::ResMgr()->AddViaNotify( bitmap->GetKey(), TRACKED_NEW plLayRefMsg( lay->GetKey(), plRefMsg::kOnCreate, 0, plLayRefMsg::kTexture ), plRefFlags::kActiveRef );
// lay->SetTexture( bitmap );
lay->SetTransform( textGen->GetLayerTransform() );
return material;
}
//// GenerateDialog //////////////////////////////////////////////////////////
void pfGUICtrlGenerator::GenerateDialog( const char *name )
{
IGenerateDialog( name, 20.f, false );
}
//// IGenSceneObject /////////////////////////////////////////////////////////
plSceneObject *pfGUICtrlGenerator::IGenSceneObject( pfGUIDialogMod *dlg, plDrawable *myDraw, plSceneObject *parent,
hsMatrix44 *l2w, hsMatrix44 *w2l )
{
plKey snKey = ( dlg != nil ) ? ( dlg->GetTarget() != nil ? dlg->GetTarget()->GetSceneNode() : nil ) : nil;
if( snKey == nil )
snKey = fDynDlgNodes.Peek()->GetKey();
hsgResMgr::ResMgr()->SendRef( myDraw->GetKey(), TRACKED_NEW plNodeRefMsg( snKey, plRefMsg::kOnCreate, 0, plNodeRefMsg::kDrawable ), plRefFlags::kActiveRef );
plDrawInterface *newDI = TRACKED_NEW plDrawInterface;
IAddKey( newDI, "GUIDrawIFace" );
plSceneObject *newObj = TRACKED_NEW plSceneObject;
IAddKey( newObj, "GUISceneObject" );
plCoordinateInterface *newCI = TRACKED_NEW plCoordinateInterface;
IAddKey( newCI, "GUICoordIFace" );
hsgResMgr::ResMgr()->SendRef( newCI->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface ), plRefFlags::kActiveRef );
hsgResMgr::ResMgr()->SendRef( newDI->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface ), plRefFlags::kActiveRef );
hsgResMgr::ResMgr()->SendRef( myDraw->GetKey(), TRACKED_NEW plIntRefMsg( newDI->GetKey(), plRefMsg::kOnCreate, 0, plIntRefMsg::kDrawable ), plRefFlags::kActiveRef );
if( parent == nil )
{
parent = ( fDynDragBars.GetCount() > 0 ) ? fDynDragBars.Peek() : nil;
if( parent == nil )
parent = dlg->GetTarget();
}
if( parent != nil )
// hsgResMgr::ResMgr()->SendRef( newCI->GetKey(), TRACKED_NEW plIntRefMsg( parent->GetKey(), plRefMsg::kOnCreate, 0, plIntRefMsg::kChild ), plRefFlags::kActiveRef );
hsgResMgr::ResMgr()->SendRef( newCI->GetKey(), TRACKED_NEW plAttachMsg( parent->GetKey(), nil, plRefMsg::kOnRequest ), plRefFlags::kActiveRef );
newObj->SetSceneNode( snKey );
if( l2w != nil )
{
newObj->SetTransform( *l2w, *w2l );
// newCI->SetLocalToParent( *l2w, *w2l );
// myDraw->SetTransform( -1, *l2w, *w2l );
}
return newObj;
}
//// GenerateRectButton //////////////////////////////////////////////////////
pfGUIButtonMod *pfGUICtrlGenerator::GenerateRectButton( const char *title, float x, float y, float width, float height,
const char *consoleCmd, hsColorRGBA &color, hsColorRGBA &textColor )
{
hsGMaterial *material;
hsMatrix44 l2w, w2l;
hsVector3 vec;
pfGUIDialogMod *dlgToAddTo = IGetDialog();
// Get us a material
material = ICreateTextMaterial( title, color, textColor, width * 20.f, height * 20.f );
pfGUIButtonMod *but = CreateRectButton( dlgToAddTo, title, x, y, width, height, material );
if( but != nil )
but->SetHandler( TRACKED_NEW pfGUIConsoleCmdProc( consoleCmd ) );
return but;
}
//// CreateRectButton ////////////////////////////////////////////////////////
pfGUIButtonMod *pfGUICtrlGenerator::CreateRectButton( pfGUIDialogMod *parent, const char *title, float x, float y, float width, float height,
hsGMaterial *material, hsBool asMenuItem )
{
wchar_t *wTitle = hsStringToWString(title);
pfGUIButtonMod *retVal = CreateRectButton(parent,wTitle,x,y,width,height,material,asMenuItem);
delete [] wTitle;
return retVal;
}
pfGUIButtonMod *pfGUICtrlGenerator::CreateRectButton( pfGUIDialogMod *parent, const wchar_t *title, float x, float y, float width, float height,
hsGMaterial *material, hsBool asMenuItem )
{
plDrawableSpans *myDraw;
hsMatrix44 l2w, w2l;
hsVector3 vec;
// Translate x and y from (0:1) to (-10:10)
x = ( x - 0.5f ) * 20.f;
y = ( y - 0.5f ) * 20.f;
// Translate width and height from (0:1) to (-10:10)
width *= 20.f;
height *= 20.f;
// Create drawable that is rectangular
l2w.Reset();
hsPoint3 corner( x, -y, -100 );
hsVector3 xVec( width, 0, 0 ), yVec( 0, height, 0 ), zVec( 0, 0, 0.1f );
myDraw = plDrawableGenerator::GeneratePlanarDrawable( corner, xVec, yVec, material, l2w );
plSceneObject *newObj = IGenSceneObject( parent, myDraw );
pfGUIButtonMod *newBtn = asMenuItem ? TRACKED_NEW pfGUIMenuItem : TRACKED_NEW pfGUIButtonMod;
IAddKey( newBtn, "GUIButton" );
hsgResMgr::ResMgr()->SendRef( newBtn->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kModifier ), plRefFlags::kActiveRef );
parent->AddControl( newBtn );
hsgResMgr::ResMgr()->AddViaNotify( newBtn->GetKey(), TRACKED_NEW plGenRefMsg( parent->GetKey(), plRefMsg::kOnCreate, parent->GetNumControls() - 1, pfGUIDialogMod::kControlRef ), plRefFlags::kActiveRef );
return newBtn;
}
//// GenerateSphereButton ////////////////////////////////////////////////////
pfGUIButtonMod *pfGUICtrlGenerator::GenerateSphereButton( float x, float y, float radius,
const char *consoleCmd, hsColorRGBA &color )
{
hsGMaterial *material;
plDrawableSpans *myDraw;
hsMatrix44 l2w, w2l;
hsVector3 vec;
hsPoint3 pt( x, -y, -100.f );
pfGUIDialogMod *dlgToAddTo = IGetDialog();
// Translate x and y from (0:1) to (-10:10)
x = ( x - 0.5f ) * 20.f;
y = ( y - 0.5f ) * 20.f;
// Translate width and height from (0:1) to (-10:10)
radius *= 20.f;
// Get us a material
material = ICreateSolidMaterial( color );
// Create drawable that is rectangular
l2w.Reset();
// We bump up the quality since we're actually far closer to these things then the normal
// world camera would put us
myDraw = plDrawableGenerator::GenerateSphericalDrawable( pt, radius, material, l2w,
false, nil, nil, nil, 100.f );
vec.Set( x, -y, 0 );
l2w.MakeTranslateMat( &vec );
l2w.GetInverse( &w2l );
plSceneObject *newObj = IGenSceneObject( dlgToAddTo, myDraw );//, nil, &l2w, &w2l );
pfGUIButtonMod *newBtn = TRACKED_NEW pfGUIButtonMod;
IAddKey( newBtn, "GUIButton" );
newBtn->SetHandler( TRACKED_NEW pfGUIConsoleCmdProc( consoleCmd ) );
hsgResMgr::ResMgr()->AddViaNotify( newBtn->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kModifier ), plRefFlags::kActiveRef );
dlgToAddTo->AddControl( newBtn );
return newBtn;
}
//// GenerateDragBar //////////////////////////////////////////////////////
pfGUIDragBarCtrl *pfGUICtrlGenerator::GenerateDragBar( float x, float y, float width, float height, hsColorRGBA &color )
{
hsGMaterial *material;
plDrawableSpans *myDraw;
hsMatrix44 l2w, w2l;
hsVector3 vec;
pfGUIDialogMod *dlgToAddTo = IGetDialog();
// Translate x and y from (0:1) to (-10:10)
x = ( x - 0.5f ) * 20.f;
y = ( y - 0.5f ) * 20.f;
// Translate width and height from (0:1) to (-10:10)
width *= 20.f;
height *= 20.f;
// Get us a material
material = ICreateSolidMaterial( color );
// Create drawable that is rectangular
l2w.Reset();
hsPoint3 corner( x, -y, -100 );//x - width / 2.f, -y - height / 2.f, -100 );
hsVector3 xVec( width, 0, 0 ), yVec( 0, height, 0 ), zVec( 0, 0, 0.1f );
myDraw = plDrawableGenerator::GenerateBoxDrawable( corner, xVec, yVec, zVec,/*width, height, 0.01f, */material, l2w );
// Drag bars are special--everything else gets attached to them and they get attached to the dialog
vec.Set( x, -y, -100 );
l2w.MakeTranslateMat( &vec );
l2w.GetInverse( &w2l );
plSceneObject *newObj = IGenSceneObject( dlgToAddTo, myDraw, dlgToAddTo->GetTarget(), &l2w, &w2l );
fDynDragBars[ fDynDragBars.GetCount() - 1 ] = newObj;
pfGUIDragBarCtrl *newBtn = TRACKED_NEW pfGUIDragBarCtrl;
IAddKey( newBtn, "GUIDragBar" );
hsgResMgr::ResMgr()->AddViaNotify( newBtn->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kModifier ), plRefFlags::kActiveRef );
dlgToAddTo->AddControl( newBtn );
/* vec.Set( -x, y, 100 );
l2w.MakeTranslateMat( &vec );
l2w.GetInverse( &w2l );
plCoordinateInterface *ci = (plCoordinateInterface *)dlgToAddTo->GetTarget()->GetCoordinateInterface();
ci->SetLocalToParent( l2w, w2l );
*/
return newBtn;
}
//// IGetDialog //////////////////////////////////////////////////////////////
pfGUIDialogMod *pfGUICtrlGenerator::IGetDialog( void )
{
if( fDynDialogs.GetCount() == 0 )
IGenerateDialog( "GUIBaseDynamicDlg", 20.f );
hsAssert( fDynDialogs.GetCount() > 0, "Unable to get a dynamic dialog to add buttons to" );
return fDynDialogs.Peek();
}
//// IGenerateDialog /////////////////////////////////////////////////////////
pfGUIDialogMod *pfGUICtrlGenerator::IGenerateDialog( const char *name, float scrnWidth, hsBool show )
{
float fovX, fovY;
plSceneNode *node;
pfGUIDialogMod *dialog;
// Create the rendermod
plPostEffectMod *renderMod = TRACKED_NEW plPostEffectMod;
IAddKey( renderMod, "GUIRenderMod" );
renderMod->SetHither( 0.5f );
renderMod->SetYon( 200.f );
// fovX should be such that scrnWidth is the projected width at z=100
fovX = atan( scrnWidth / ( 2.f * 100.f ) ) * 2.f;
fovY = fovX;// * 3.f / 4.f;
renderMod->SetFovX( fovX * 180.f / hsScalarPI );
renderMod->SetFovY( fovY * 180.f / hsScalarPI );
// Create the sceneNode to go with it
node = TRACKED_NEW plSceneNode;
IAddKey( node, "GUISceneNode" );
node->GetKey()->RefObject();
fDynDlgNodes.Append( node );
fDynDragBars.Append( nil );
hsgResMgr::ResMgr()->AddViaNotify( node->GetKey(), TRACKED_NEW plGenRefMsg( renderMod->GetKey(), plRefMsg::kOnCreate, 0, plPostEffectMod::kNodeRef ), plRefFlags::kPassiveRef );
// Create the dialog
dialog = TRACKED_NEW pfGUIDialogMod;
IAddKey( dialog, "GUIDialog" );
dialog->SetRenderMod( renderMod );
dialog->SetName( name );
// Create the dummy scene object to hold the dialog
plSceneObject *newObj = TRACKED_NEW plSceneObject;
IAddKey( newObj, "GUISceneObject" );
// *#&$(*@&#$ need a coordIface...
plCoordinateInterface *newCI = TRACKED_NEW plCoordinateInterface;
IAddKey( newCI, "GUICoordIFace" );
hsMatrix44 l2w, w2l;
l2w.Reset();
// l2w.NotIdentity();
l2w.GetInverse( &w2l );
// Using SendRef here because AddViaNotify will queue the messages up, which doesn't do us any good
// if we need these refs right away
hsgResMgr::ResMgr()->SendRef( dialog->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kModifier ), plRefFlags::kActiveRef );
hsgResMgr::ResMgr()->AddViaNotify( newCI->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface ), plRefFlags::kActiveRef );
hsgResMgr::ResMgr()->AddViaNotify( renderMod->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kModifier ), plRefFlags::kActiveRef );
// Add the dialog to the GUI mgr
plGenRefMsg *refMsg = TRACKED_NEW plGenRefMsg( pfGameGUIMgr::GetInstance()->GetKey(),
plRefMsg::kOnCreate, 0, pfGameGUIMgr::kDlgModRef );
hsgResMgr::ResMgr()->AddViaNotify( dialog->GetKey(), refMsg, plRefFlags::kActiveRef );
newObj->SetSceneNode( node->GetKey() );
newObj->SetTransform( l2w, w2l );
// newCI->SetLocalToParent( l2w, w2l );
if( show )
pfGameGUIMgr::GetInstance()->ShowDialog( dialog );
fDynDialogs.Append( dialog );
return dialog;
}

View File

@ -0,0 +1,129 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUICtrlGenerator Header //
// Generates really primitive GUI controls (and dialogs) at runtime. //
// Useful for, well, generating really primitive GUI controls and dialogs //
// at runtime...
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUICtrlGenerator_h
#define _pfGUICtrlGenerator_h
#include "hsStream.h"
#include "hsTemplates.h"
//// pfGUICtrlGenerator Definition ///////////////////////////////////////////
class pfGUIDialogMod;
class pfGUIButtonMod;
class pfGUIDragBarCtrl;
class hsGMaterial;
struct hsColorRGBA;
class plSceneNode;
class hsKeyedObject;
class plKey;
class plTextGenerator;
class plSceneObject;
class plDrawable;
struct hsMatrix44;
class pfGUICtrlGenerator
{
protected:
char fFontFace[ 256 ];
UInt32 fFontSize;
hsTArray<plTextGenerator *> fTextGens;
hsTArray<plSceneNode *> fDynDlgNodes;
hsTArray<pfGUIDialogMod *> fDynDialogs;
hsTArray<plSceneObject *> fDynDragBars;
plKey IAddKey( hsKeyedObject *ko, const char *prefix );
void IGetNextKeyName( char *name, const char *prefix );
hsGMaterial *ICreateSolidMaterial( hsColorRGBA &color );
hsGMaterial *ICreateTextMaterial( const char *text, hsColorRGBA &bgColor,
hsColorRGBA &textColor, float objWidth, float objHeight );
pfGUIDialogMod *IGetDialog( void );
pfGUIDialogMod *IGenerateDialog( const char *name, float scrnWidth, hsBool show = true );
plSceneObject *IGenSceneObject( pfGUIDialogMod *dlg, plDrawable *myDraw, plSceneObject *parent = nil, hsMatrix44 *l2w = nil, hsMatrix44 *w2l = nil );
public:
pfGUICtrlGenerator();
~pfGUICtrlGenerator();
void Shutdown( void );
void SetFont( const char *face, UInt16 size );
pfGUIButtonMod *GenerateRectButton( const char *title, float x, float y, float width, float height,
const char *consoleCmd, hsColorRGBA &color, hsColorRGBA &textColor );
pfGUIButtonMod *GenerateSphereButton( float x, float y, float radius,
const char *consoleCmd, hsColorRGBA &color );
pfGUIDragBarCtrl *GenerateDragBar( float x, float y, float width, float height, hsColorRGBA &color );
void GenerateDialog( const char *name );
pfGUIButtonMod *CreateRectButton( pfGUIDialogMod *parent, const char *title, float x, float y,
float width, float height, hsGMaterial *material, hsBool asMenuItem = false );
pfGUIButtonMod *CreateRectButton( pfGUIDialogMod *parent, const wchar_t *title, float x, float y,
float width, float height, hsGMaterial *material, hsBool asMenuItem = false );
static pfGUICtrlGenerator &Instance( void );
};
#endif // _pfGUICtrlGenerator_h

View File

@ -0,0 +1,113 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDialogHandlers Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIDialogHandlers_h
#define _pfGUIDialogHandlers_h
#include "hsStream.h"
#include "pfGUIControlHandlers.h"
//// pfGUIDialogProc Definition //////////////////////////////////////////////
// This works very much like the control proc objects. The idea is, if you
// want to do some custom work on a dialog (and who doesn't?), you create an
// object derived from this type, override the functions, and do as you
// please. The class type also derives from the control proc type, meaning
// that you can implement DoSomething() as well and use the same object for
// both your dialog and your control procs. (DoSomething() is overloaded here
// so that it's no longer pure virtual, so you can use it for only handling
// dialogs if you prefer).
class pfGUIDialogMod;
class pfGUIDialogProc : public pfGUICtrlProcObject
{
protected:
pfGUIDialogMod *fDialog;
public:
pfGUIDialogProc() { }
virtual ~pfGUIDialogProc() { ; }
// Called by the mgr--don't call yourself!
void SetDialog( pfGUIDialogMod *dlg ) { fDialog = dlg; }
// Enums for OnControlEvent
enum ControlEvt
{
kExitMode
};
//////// FUNCTIONS TO OVERLOAD ////////
// Overloaded here so you don't have to unless you want to. Overload
// it if you want to use this for a control handler as well.
virtual void DoSomething( pfGUIControlMod *ctrl ) {;}
// Called on dialog init (i.e. first showing, before OnShow() is called), only ever called once
virtual void OnInit( void ) { ; }
// Called before the dialog is shown, always after OnInit()
virtual void OnShow( void ) { ; }
// Called before the dialog is hidden
virtual void OnHide( void ) { ; }
// Called on the dialog's destructor, before it's unregistered with the game GUI manager
virtual void OnDestroy( void ) { ; }
// Called when the dialog's focused control changes
virtual void OnCtrlFocusChange( pfGUIControlMod *oldCtrl, pfGUIControlMod *newCtrl ) { ; }
// Called when the key bound to a GUI event is pressed. Only called on the top modal dialog
virtual void OnControlEvent( ControlEvt event ) { ; }
// Called when the GUI changes interesting state
virtual void OnInterestingEvent( pfGUIControlMod *ctrl ) { ; }
};
#endif // _pfGUIDialogHandlers_h

View File

@ -0,0 +1,848 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDialogMod Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGameGUIMgr.h"
#include "pfGUIDialogMod.h"
#include "pfGUIControlMod.h"
#include "pfGUIDialogHandlers.h"
#include "pfGUIDialogNotifyProc.h"
#include "pfGUIListElement.h"
#include "../plScene/plPostEffectMod.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plScene/plSceneNode.h"
#include "../pnSceneObject/plSceneObject.h"
#include "../pnKeyedObject/plKey.h"
#include "../pnKeyedObject/plFixedKey.h"
#include "../pnSceneObject/plCoordinateInterface.h"
#include "../plStatusLog/plStatusLog.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
#include "plViewTransform.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIDialogMod::pfGUIDialogMod() : fRenderMod( nil ), fNext( nil ), fPrevPtr( nil )
{
memset( fName, 0, sizeof( fName ) );
fEnabled = false;
fControlOfInterest = nil;
fFocusCtrl = nil;
fMousedCtrl = nil;
fTagID = 0;
fHandler = nil;
fVersion = 0;
fDragMode = false;
fDragReceptive = false;
fDragTarget = nil;
fProcReceiver = nil;
fColorScheme = TRACKED_NEW pfGUIColorScheme();
}
pfGUIDialogMod::~pfGUIDialogMod()
{
// Call the handler's destroy if there is one
if( fHandler )
fHandler->OnDestroy();
// Unregister us with the Game GUI manager
plUoid lu( kGameGUIMgr_KEY );
plKey mgrKey = hsgResMgr::ResMgr()->FindKey( lu );
if( mgrKey )
{
plGenRefMsg *refMsg = TRACKED_NEW plGenRefMsg( mgrKey, plRefMsg::kOnRemove, 0, pfGameGUIMgr::kDlgModRef );
refMsg->SetRef( this );
plgDispatch::MsgSend( refMsg );
}
SetHandler( nil );
hsRefCnt_SafeUnRef( fColorScheme );
fColorScheme = nil;
}
//// ScreenToWorldPoint //////////////////////////////////////////////////////
// Sometimes it just sucks not having access to the pipeline at just the
// right time.
void pfGUIDialogMod::ScreenToWorldPoint( hsScalar x, hsScalar y, hsScalar z, hsPoint3 &outPt )
{
plViewTransform view = fRenderMod->GetViewTransform();
view.SetScreenSize( 1, 1 );
outPt = view.ScreenToWorld( hsPoint3( x, y, z ) );
}
//// WorldToScreenPoint //////////////////////////////////////////////////////
// Given a point in world-space, translates it into screen coordinates
// (with range 0-1, origin top-left).
hsPoint3 pfGUIDialogMod::WorldToScreenPoint( const hsPoint3 &inPt )
{
plViewTransform view = fRenderMod->GetViewTransform();
view.SetScreenSize( 1, 1 );
hsPoint3 tempPt = view.WorldToScreen( inPt );
tempPt.fZ = view.WorldToCamera( inPt ).fZ;
return tempPt;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIDialogMod::IEval( double secs, hsScalar del, UInt32 dirty )
{
return false;
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIDialogMod::MsgReceive( plMessage *msg )
{
plGenRefMsg *ref = plGenRefMsg::ConvertNoRef( msg );
if( ref )
{
switch( ref->fType )
{
case kRenderModRef:
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
{
fRenderMod = plPostEffectMod::ConvertNoRef( ref->GetRef() );
fRenderMod->EnableLightsOnRenderRequest();
if( fEnabled )
{
plAnimCmdMsg *animMsg = TRACKED_NEW plAnimCmdMsg( GetKey(), fRenderMod->GetKey(), nil );
animMsg->SetCmd( plAnimCmdMsg::kContinue );
plgDispatch::MsgSend( animMsg );
}
}
else if( ref->GetContext() & ( plRefMsg::kOnRemove | plRefMsg::kOnDestroy ) )
{
plAnimCmdMsg *animMsg = TRACKED_NEW plAnimCmdMsg( GetKey(), fRenderMod->GetKey(), nil );
animMsg->SetCmd( plAnimCmdMsg::kStop );
plgDispatch::MsgSend( animMsg );
fRenderMod = nil;
}
break;
case kControlRef:
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
{
if( ref->fWhich >= fControls.GetCount() )
{
hsAssert( false, "Bad index in reffing a control on a GUI dialog" );
}
else
{
pfGUIControlMod *oldCtrl = fControls[ ref->fWhich ];
fControls[ ref->fWhich ] = pfGUIControlMod::ConvertNoRef( ref->GetRef() );
fControls[ ref->fWhich ]->ISetDialog( this );
if( oldCtrl != fControls[ ref->fWhich ] )
// They're equal on export time, when we DON'T want to be updating the bounds
fControls[ ref->fWhich ]->CalcInitialBounds();
if( fControls[ ref->fWhich ]->HasFlag( pfGUIControlMod::kInheritProcFromDlg ) )
fControls[ ref->fWhich ]->ISetHandler( fHandler );
}
}
else if( ref->GetContext() & ( plRefMsg::kOnRemove | plRefMsg::kOnDestroy ) )
{
if( ref->fWhich >= fControls.GetCount() )
{
hsAssert( false, "Bad index in unreffing a control on a GUI dialog." );
}
else
{
if( fControls[ ref->fWhich ] != nil )
fControls[ ref->fWhich ]->ISetDialog( nil );
fControls[ ref->fWhich ] = nil;
}
}
break;
}
return true;
}
return plSingleModifier::MsgReceive( msg );
}
//// AddControl //////////////////////////////////////////////////////////////
void pfGUIDialogMod::AddControl( pfGUIControlMod *ctrl )
{
fControls.Append( ctrl );
ctrl->ISetDialog( this );
ctrl->CalcInitialBounds();
}
//// AddControlOnExport //////////////////////////////////////////////////////
void pfGUIDialogMod::AddControlOnExport( pfGUIControlMod *ctrl )
{
fControls.Append( ctrl );
hsgResMgr::ResMgr()->AddViaNotify( ctrl->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, fControls.GetCount() - 1, pfGUIDialogMod::kControlRef ), plRefFlags::kActiveRef );
}
//// SetEnabled //////////////////////////////////////////////////////////////
void pfGUIDialogMod::SetEnabled( hsBool e )
{
if( e == fEnabled )
return;
fEnabled = e;
if( fHandler != nil )
{
if( fEnabled )
fHandler->OnShow();
else
fHandler->OnHide();
}
if ( !fEnabled )
{
// if we are being hidden then there should be no controls that have interest
fControlOfInterest = nil;
// also we can purge the dynaText images on the controls
int i;
for( i = 0; i < fControls.GetCount(); i++ )
{
if( fControls[ i ] == nil )
continue;
fControls[ i ]->PurgeDynaTextMapImage();
}
}
if( fRenderMod != nil )
{
plAnimCmdMsg *animMsg = TRACKED_NEW plAnimCmdMsg( GetKey(), fRenderMod->GetKey(), nil );
if( fEnabled )
{
animMsg->SetCmd( plAnimCmdMsg::kContinue );
// Update the bounds on all controls that we own
UpdateAllBounds();
}
else
animMsg->SetCmd( plAnimCmdMsg::kStop );
plgDispatch::MsgSend( animMsg );
}
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIDialogMod::Read( hsStream *s, hsResMgr *mgr )
{
plSingleModifier::Read(s, mgr);
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRenderModRef ), plRefFlags::kActiveRef );
s->Read( sizeof( fName ), fName );
UInt32 i, count = s->ReadSwap32();
fControls.SetCountAndZero( count );
for( i = 0; i < count; i++ )
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, i, kControlRef ), plRefFlags::kActiveRef );
// Register us with the Game GUI manager
plUoid lu( kGameGUIMgr_KEY );
plKey mgrKey = hsgResMgr::ResMgr()->FindKey( lu );
if( mgrKey )
{
plGenRefMsg *refMsg = TRACKED_NEW plGenRefMsg( mgrKey, plRefMsg::kOnCreate, 0, pfGameGUIMgr::kDlgModRef );
hsgResMgr::ResMgr()->AddViaNotify( GetKey(), refMsg, plRefFlags::kPassiveRef );
}
s->ReadSwap( &fTagID );
fProcReceiver = mgr->ReadKey( s );
if( fProcReceiver != nil )
SetHandler( TRACKED_NEW pfGUIDialogNotifyProc( fProcReceiver ) );
s->ReadSwap( &fVersion );
fColorScheme->Read( s );
fSceneNodeKey = mgr->ReadKey( s );
}
void pfGUIDialogMod::Write( hsStream *s, hsResMgr *mgr )
{
UInt32 i;
plSingleModifier::Write( s, mgr );
mgr->WriteKey( s, fRenderMod->GetKey() );
s->Write( sizeof( fName ), fName );
s->WriteSwap32( fControls.GetCount() );
for( i = 0; i < fControls.GetCount(); i++ )
mgr->WriteKey( s, fControls[ i ]->GetKey() );
s->WriteSwap( fTagID );
mgr->WriteKey( s, fProcReceiver );
s->WriteSwap( fVersion );
fColorScheme->Write( s );
mgr->WriteKey( s, fSceneNodeKey );
}
plKey pfGUIDialogMod::GetSceneNodeKey( void )
{
if( fSceneNodeKey != nil )
return fSceneNodeKey;
// Attempt to grab it
if( GetTarget() != nil && GetTarget()->GetSceneNode() != nil )
return ( fSceneNodeKey = GetTarget()->GetSceneNode() );
return nil;
}
//// UpdateInterestingThings /////////////////////////////////////////////////
// Really. We go through and make sure every control marked as interesting
// still has the mouse inside it and vice versa.
void pfGUIDialogMod::UpdateInterestingThings( hsScalar mouseX, hsScalar mouseY, UInt8 modifiers, hsBool modalPreset )
{
int i;
hsPoint3 mousePoint;
mousePoint.Set( mouseX, mouseY, 0.f );
for( i = 0; i < fControls.GetCount(); i++ )
{
if( fControls[ i ] == nil )
continue;
// if there was a modal present and we are not modal, then everything is unInteresting!
if ( modalPreset && !HasFlag(pfGUIDialogMod::kModal) )
{
if( fControls[ i ]->IsInteresting() )
fControls[ i ]->SetInteresting( false );
}
else
{
if( !fControls[ i ]->HasFlag( pfGUIControlMod::kIntangible ) && fControls[ i ]->PointInBounds( mousePoint ) || fControls[ i ] == fControlOfInterest )
{
if( !fControls[ i ]->IsInteresting() )
fControls[ i ]->SetInteresting( true );
}
else
{
if( fControls[ i ]->IsInteresting() )
fControls[ i ]->SetInteresting( false );
}
}
}
}
//// HandleMouseEvent ////////////////////////////////////////////////////////
#ifdef HS_DEBUGGING // Debugging bounds rects
#include "../plPipeline/plDebugText.h"
#endif
hsBool pfGUIDialogMod::HandleMouseEvent( pfGameGUIMgr::EventType event, hsScalar mouseX, hsScalar mouseY,
UInt8 modifiers )
{
hsPoint3 mousePoint;
UInt32 i;
pfGUIControlMod *oldInterestingCtrl = nil;
hsScalar smallestZ;
#ifdef HS_DEBUGGING // Debugging bounds rects
static bool showBounds = false;
if( showBounds )
{
UInt32 sW, sH;
plDebugText::Instance().GetScreenSize(&sW,&sH);
for( i = 0; i < fControls.GetCount(); i++ )
{
if( fControls[ i ] == nil )
continue;
if( fControls[ i ]->HasFlag( pfGUIControlMod::kIntangible ) )
continue;
if( fControls[ i ]->fBoundsPoints.GetCount() > 0 )
{
const hsBounds3 &bnds = fControls[ i ]->GetBounds();
plDebugText::Instance().Draw3DBorder( (UInt16)(sW * bnds.GetMins().fX),
(UInt16)(sH * bnds.GetMins().fY),
(UInt16)(sW * bnds.GetMaxs().fX),
(UInt16)(sH * bnds.GetMaxs().fY), 0x3000ffff, 0x3000ffff );
UInt32 color = 0xffff0000;
for( int j = 0; j < fControls[ i ]->fBoundsPoints.GetCount(); j++ )
{
// color = 0xff000000 | ( ( j * 16 ) << 16 );
float x = sW * fControls[ i ]->fBoundsPoints[ j ].fX;
float y = sH * fControls[ i ]->fBoundsPoints[ j ].fY;
plDebugText::Instance().DrawRect( (UInt16)(x - 2), (UInt16)(y - 2), (UInt16)(x + 2), (UInt16)(y + 2), color );
char str[ 16 ];
itoa( j, str, 10 );
plDebugText::Instance().DrawString( (UInt16)(x + 8), (UInt16)(y - 8), str, color );
}
}
else
{
const hsBounds3 &bnds = fControls[ i ]->GetBounds();
plDebugText::Instance().Draw3DBorder( (UInt16)(sW * bnds.GetMins().fX),
(UInt16)(sH * bnds.GetMins().fY),
(UInt16)(sW * bnds.GetMaxs().fX),
(UInt16)(sH * bnds.GetMaxs().fY), 0x300000ff, 0x300000ff );
}
}
}
#endif
mousePoint.Set( mouseX, mouseY, 0.f );
if( fDragMode )
{
IHandleDrag( mousePoint, event, modifiers );
return true; // We ALWAYS handle events if we're in drag mode
}
oldInterestingCtrl = fMousedCtrl;
if( fControlOfInterest != nil )
{
// A particular control already has interest--pass messages directly to it no matter what
fMousedCtrl = fControlOfInterest;
}
else
{
for( i = 0, fMousedCtrl = nil, smallestZ = 1.e30f; i < fControls.GetCount(); i++ )
{
if( fControls[ i ] != nil && !fControls[ i ]->HasFlag( pfGUIControlMod::kIntangible ) && fControls[ i ]->PointInBounds( mousePoint ) && fControls[ i ]->IsVisible() && fControls[ i ]->IsEnabled() )
{
if( fControls[ i ]->GetScreenMinZ() < smallestZ )
{
if( fControls[ i ]->FilterMousePosition( mousePoint ) )
{
fMousedCtrl = fControls[ i ];
smallestZ = fControls[ i ]->GetScreenMinZ();
}
}
}
}
}
if( fMousedCtrl != nil )
{
#ifdef HS_DEBUGGING // Debugging bounds rects
if( showBounds )
{
const hsBounds3 &bnds = fMousedCtrl->GetBounds();
plDebugText::Instance().DrawString( (UInt16)(bnds.GetMins().fX), (UInt16)(bnds.GetMins().fY), fMousedCtrl->GetKeyName(), (UInt32)0xffffff00 );
}
#endif
if( event == pfGameGUIMgr::kMouseDown )
{
if( fMousedCtrl->HasFlag( pfGUIControlMod::kWantsInterest ) )
fControlOfInterest = fMousedCtrl;
fMousedCtrl->HandleMouseDown( mousePoint, modifiers );
// Clicking on a control (mouse down) also sets focus to that control. Unlike
// control-of-interest, this does NOT get reset until a new control is clicked on
if( fFocusCtrl != fMousedCtrl )
{
if( fHandler != nil )
fHandler->OnCtrlFocusChange( fFocusCtrl, fMousedCtrl );
if( fFocusCtrl != nil )
fFocusCtrl->SetFocused( false );
fFocusCtrl = fMousedCtrl;
fFocusCtrl->SetFocused( true );
}
}
else if( event == pfGameGUIMgr::kMouseUp )
{
fMousedCtrl->HandleMouseUp( mousePoint, modifiers );
// Controls lose interest on mouse up
fControlOfInterest = nil;
}
else if( event == pfGameGUIMgr::kMouseMove )
fMousedCtrl->HandleMouseHover( mousePoint, modifiers );
else if( event == pfGameGUIMgr::kMouseDrag )
fMousedCtrl->HandleMouseDrag( mousePoint, modifiers );
else if( event == pfGameGUIMgr::kMouseDblClick )
fMousedCtrl->HandleMouseDblClick( mousePoint, modifiers );
return true;
}
// Clicked on nobody, make sure we lose focus on any controls
if( fFocusCtrl != nil && event == pfGameGUIMgr::kMouseDown )
{
if( fHandler != nil )
fHandler->OnCtrlFocusChange( fFocusCtrl, nil );
if( fFocusCtrl != nil ) // The handler call could've changed it
fFocusCtrl->SetFocused( false );
fFocusCtrl = nil;
}
return false;
}
//// HandleKeyEvent //////////////////////////////////////////////////////////
hsBool pfGUIDialogMod::HandleKeyEvent( pfGameGUIMgr::EventType event, plKeyDef key, UInt8 modifiers )
{
// Only process if a control has focus...
if( fFocusCtrl != nil )
{
// And guess what, it's up to that control to process it! Gee, how easy...
return fFocusCtrl->HandleKeyEvent( event, key, modifiers );
}
return false;
}
//// HandleKeyPress //////////////////////////////////////////////////////////
hsBool pfGUIDialogMod::HandleKeyPress( char key, UInt8 modifiers )
{
// Same deal as HandleKeyPress. Only problem is, we needed the msg to translate
// to a char, so it had to be done up at the mgr level (sadly)
// Only process if a control has focus...
if( fFocusCtrl != nil )
{
return fFocusCtrl->HandleKeyPress( key, modifiers );
}
return false;
}
//// SetFocus ////////////////////////////////////////////////////////////////
void pfGUIDialogMod::SetFocus( pfGUIControlMod *ctrl )
{
if( ctrl != nil && ctrl->fDialog != this )
{
if( fHandler != nil )
fHandler->OnCtrlFocusChange( fFocusCtrl, nil );
if( fFocusCtrl != nil )
fFocusCtrl->SetFocused( false );
fFocusCtrl = nil;
ctrl->fDialog->SetFocus( ctrl );
}
else if( ctrl != fFocusCtrl )
{
if( fFocusCtrl != nil )
fFocusCtrl->SetFocused( false );
if( fHandler != nil )
fHandler->OnCtrlFocusChange( fFocusCtrl, ctrl );
fFocusCtrl = ctrl;
if( fFocusCtrl != nil )
fFocusCtrl->SetFocused( true );
}
}
//// Show/Hide ///////////////////////////////////////////////////////////////
void pfGUIDialogMod::Show( void )
{
pfGameGUIMgr::GetInstance()->ShowDialog( this );
}
void pfGUIDialogMod::ShowNoReset( void )
{
pfGameGUIMgr::GetInstance()->ShowDialog( this, false );
}
void pfGUIDialogMod::Hide( void )
{
pfGameGUIMgr::GetInstance()->HideDialog( this );
}
//// GetControlFromTag ///////////////////////////////////////////////////////
pfGUIControlMod *pfGUIDialogMod::GetControlFromTag( UInt32 tagID )
{
int i;
int ctrlCount = fControls.GetCount();
for( i = 0; i < ctrlCount; i++ )
{
pfGUIControlMod *ctrl = fControls[i];
if( ctrl && ctrl->GetTagID() == tagID )
return fControls[ i ];
}
return nil;
}
//// SetControlOfInterest ////////////////////////////////////////////////////
void pfGUIDialogMod::SetControlOfInterest( pfGUIControlMod *c )
{
fControlOfInterest = c;
}
//// SetHandler //////////////////////////////////////////////////////////////
void pfGUIDialogMod::SetHandler( pfGUIDialogProc *hdlr )
{
int i;
if( fHandler && fHandler->DecRef() )
delete fHandler;
fHandler = hdlr;
if( fHandler != nil )
{
fHandler->IncRef();
fHandler->SetDialog( this );
}
// We also set the handler for any controls that are flagged to inherit
// from the parent dialog. Note that SetHandlerForAll() can thus be
// seen as a function that forces this flag (temporarily) on all controls
for( i = 0; i < fControls.GetCount(); i++ )
{
// Test for nil controls since we get this also on destruct
if( fControls[ i ] != nil && fControls[ i ]->HasFlag( pfGUIControlMod::kInheritProcFromDlg ) )
fControls[ i ]->ISetHandler( hdlr );
}
}
//// SetHandlerForAll ////////////////////////////////////////////////////////
// Does SetHandler() for the dialog and all of its controls. Handy if you
// have one of those all-encompasing dialog procs. :)
void pfGUIDialogMod::SetHandlerForAll( pfGUIDialogProc *hdlr )
{
int i;
SetHandler( hdlr );
for( i = 0; i < fControls.GetCount(); i++ )
fControls[ i ]->ISetHandler( hdlr );
}
//// SetControlHandler ///////////////////////////////////////////////////////
void pfGUIDialogMod::SetControlHandler( UInt32 tagID, pfGUIDialogProc *hdlr )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
{
if( fControls[ i ]->GetTagID() == tagID )
{
fControls[ i ]->SetHandler( hdlr );
break;
}
}
}
//// UpdateAspectRatio ///////////////////////////////////////////////////////
void pfGUIDialogMod::UpdateAspectRatio( void )
{
if (fRenderMod)
{
// Set width fov respecting height fov
fRenderMod->SetFovX(pfGameGUIMgr::GetInstance()->GetAspectRatio() * fRenderMod->GetFovY());
}
UpdateAllBounds();
}
//// UpdateAllBounds /////////////////////////////////////////////////////////
void pfGUIDialogMod::UpdateAllBounds( void )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
{
if( fControls[ i ] != nil )
fControls[ i ]->UpdateBounds( nil, true );
}
}
//// RefreshAllControls //////////////////////////////////////////////////////
void pfGUIDialogMod::RefreshAllControls( void )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
fControls[ i ]->IUpdate();
}
//////////////////////////////////////////////////////////////////////////////
//// ListElement Drag Functions //////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//// ClearDragList ///////////////////////////////////////////////////////////
void pfGUIDialogMod::ClearDragList( void )
{
fDragElements.Reset();
}
//// AddToDragList ///////////////////////////////////////////////////////////
void pfGUIDialogMod::AddToDragList( pfGUIListElement *e )
{
fDragElements.Append( e );
}
//// EnterDragMode ///////////////////////////////////////////////////////////
void pfGUIDialogMod::EnterDragMode( pfGUIControlMod *source )
{
if( fDragElements.GetCount() > 0 )
{
fDragMode = true;
fDragReceptive = false;
fDragTarget = nil;
fDragSource = source;
}
}
//// IHandleDrag /////////////////////////////////////////////////////////////
// Oooh, we're in dragging-list-elements-around mode! So completely ignore
// the normal way we do things; what we need to do is wait until the mouse
// button is up, all the while testing to see if the control we're on top of
// is capable of receiving the elements we have. Once the mouse button is let
// up, if the control is indeed receptive, we call its drag handler for each
// of our elements, and either way, exit drag mode.
void pfGUIDialogMod::IHandleDrag( hsPoint3 &mousePoint, pfGameGUIMgr::EventType event, UInt8 modifiers )
{
int i;
hsScalar smallestZ;
// First, see if our target control has changed
for( i = 0, fMousedCtrl = nil, smallestZ = 1.e30f; i < fControls.GetCount(); i++ )
{
if( fControls[ i ]->PointInBounds( mousePoint ) && fControls[ i ]->GetBounds().GetMaxs().fZ < smallestZ )
fMousedCtrl = fControls[ i ];
}
if( fMousedCtrl != fDragTarget )
{
// Target has changed, update our receptive flag
fDragTarget = fMousedCtrl;
if( fDragTarget == nil )
fDragReceptive = false;
else
{
pfGUIDropTargetProc *dropProc = fDragTarget->GetDropTargetHdlr();
if( dropProc == nil )
fDragReceptive = false;
else
{
fDragReceptive = true;
for( i = 0; i < fDragElements.GetCount(); i++ )
{
if( !dropProc->CanEat( fDragElements[ i ], fDragSource ) )
{
fDragReceptive = false;
break;
}
}
}
}
}
if( event == pfGameGUIMgr::kMouseUp )
{
/// Mouse got let up--we're exiting drag mode, but can we process the drop?
fDragMode = false;
if( fDragReceptive )
{
pfGUIDropTargetProc *dropProc = fDragTarget->GetDropTargetHdlr();
for( i = 0; i < fDragElements.GetCount(); i++ )
dropProc->Eat( fDragElements[ i ], fDragSource, fDragTarget );
}
}
}
//// GetDesiredCursor ////////////////////////////////////////////////////////
UInt32 pfGUIDialogMod::GetDesiredCursor( void ) const
{
if( fMousedCtrl != nil )
return fMousedCtrl->IGetDesiredCursor();
return 0;
}

View File

@ -0,0 +1,214 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDialogMod Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIDialogMod_h
#define _pfGUIDialogMod_h
#include "../pnModifier/plSingleModifier.h"
#include "pfGameGUIMgr.h"
#include "hsMatrix44.h"
class plMessage;
class plPostEffectMod;
class pfGUIControlMod;
class pfGUIDialogProc;
class pfGUIListElement;
class pfGUIColorScheme;
class pfGUIDialogMod : public plSingleModifier
{
private:
pfGUIDialogMod *fNext, **fPrevPtr;
protected:
UInt32 fTagID; // 0 if none
UInt32 fVersion; // Nice for syncing to C++ code
plPostEffectMod *fRenderMod;
hsBool fEnabled;
char fName[ 128 ];
hsTArray<pfGUIControlMod *> fControls;
pfGUIControlMod *fControlOfInterest;
pfGUIControlMod *fFocusCtrl;
pfGUIControlMod *fMousedCtrl; // Which one is the mouse over?
pfGUIColorScheme *fColorScheme;
pfGUIDialogProc *fHandler;
plKey fProcReceiver; // Non-nil means we handle everything by creating notify messages and sending them to this key
hsTArray<pfGUIListElement *> fDragElements;
hsBool fDragMode, fDragReceptive;
pfGUIControlMod *fDragTarget;
pfGUIControlMod *fDragSource;
plKey fSceneNodeKey;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
void IHandleDrag( hsPoint3 &mousePt, pfGameGUIMgr::EventType event, UInt8 modifiers );
public:
enum
{
kRenderModRef = 0,
kControlRef,
kRefDerviedStart
};
enum Flags
{
kModal,
kDerivedFlagsStart
};
pfGUIDialogMod();
virtual ~pfGUIDialogMod();
CLASSNAME_REGISTER( pfGUIDialogMod );
GETINTERFACE_ANY( pfGUIDialogMod, plSingleModifier );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
void SetSceneNodeKey( plKey &key ) { fSceneNodeKey = key; }
plKey GetSceneNodeKey( void );
virtual void SetEnabled( hsBool e );
hsBool IsEnabled( void ) { return fEnabled; }
const char *GetName( void ) { return fName; }
void ScreenToWorldPoint( hsScalar x, hsScalar y, hsScalar z, hsPoint3 &outPt );
hsPoint3 WorldToScreenPoint( const hsPoint3 &inPt );
virtual hsBool HandleMouseEvent( pfGameGUIMgr::EventType event, hsScalar mouseX, hsScalar mouseY, UInt8 modifiers );
hsBool HandleKeyEvent( pfGameGUIMgr::EventType event, plKeyDef key, UInt8 modifiers );
hsBool HandleKeyPress( char key, UInt8 modifiers );
void UpdateInterestingThings( hsScalar mouseX, hsScalar mouseY, UInt8 modifiers, hsBool modalPreset );
void SetControlOfInterest( pfGUIControlMod *c );
pfGUIControlMod *GetControlOfInterest( void ) const { return fControlOfInterest; }
UInt32 GetDesiredCursor( void ) const;
void UpdateAspectRatio( void );
void UpdateAllBounds( void );
void RefreshAllControls( void );
void AddControl( pfGUIControlMod *ctrl );
UInt32 GetNumControls( void ) { return fControls.GetCount(); }
pfGUIControlMod *GetControl( UInt32 idx ) { return fControls[ idx ]; }
pfGUIColorScheme *GetColorScheme( void ) const { return fColorScheme; }
void LinkToList( pfGUIDialogMod **prevPtr )
{
fNext = *prevPtr;
if( *prevPtr )
(*prevPtr)->fPrevPtr = &fNext;
fPrevPtr = prevPtr;
*prevPtr = this;
}
void Unlink( void )
{
if( fNext )
fNext->fPrevPtr = fPrevPtr;
*fPrevPtr = fNext;
fPrevPtr = nil;
fNext = nil;
}
void SetFocus( pfGUIControlMod *ctrl );
void Show( void );
void ShowNoReset( void );
void Hide( void );
hsBool IsVisible( void ) { return IsEnabled(); }
pfGUIControlMod *GetFocus( void ) { return fFocusCtrl; }
pfGUIDialogMod *GetNext( void ) { return fNext; }
UInt32 GetTagID( void ) { return fTagID; }
pfGUIControlMod *GetControlFromTag( UInt32 tagID );
void SetHandler( pfGUIDialogProc *hdlr );
pfGUIDialogProc *GetHandler( void ) const { return fHandler; }
plPostEffectMod *GetRenderMod( void ) const { return fRenderMod; }
// This sets the handler for the dialog and ALL of its controls
void SetHandlerForAll( pfGUIDialogProc *hdlr );
// Just a little macro-type thing here
void SetControlHandler( UInt32 tagID, pfGUIDialogProc *hdlr );
/// Methods for doing drag & drop of listElements
void ClearDragList( void );
void AddToDragList( pfGUIListElement *e );
void EnterDragMode( pfGUIControlMod *source );
UInt32 GetVersion( void ) const { return fVersion; }
// Export only
void SetRenderMod( plPostEffectMod *mod ) { fRenderMod = mod; }
void SetName( const char *name ) { hsStrncpy( fName, name, sizeof( fName ) - 1 ); }
void AddControlOnExport( pfGUIControlMod *ctrl );
void SetTagID( UInt32 id ) { fTagID = id; }
void SetProcReceiver( plKey key ) { fProcReceiver = key; }
void SetVersion( UInt32 version ) { fVersion = version; }
};
#endif // _pfGUIDialogMod_h

View File

@ -0,0 +1,166 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDialogNotifyProc //
// //
// Helper dialog proc that takes all control events and turns them into //
// notify messages that get sent out. //
//////////////////////////////////////////////////////////////////////////////
#include "pfGUIDialogNotifyProc.h"
#include "hsTypes.h"
#include "pfGameGUIMgr.h"
#include "pfGUIDialogMod.h"
#include "pfGUIControlMod.h"
#include "pfGUIDialogHandlers.h"
#include "pfGUIListElement.h"
#include "pfGUIButtonMod.h" // Next three are for notify stuff
#include "pfGUIListBoxMod.h"
#include "pfGUIEditBoxMod.h"
#include "../pfMessage/pfGUINotifyMsg.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
pfGUIDialogNotifyProc::pfGUIDialogNotifyProc( plKey &r )
{
fReceiver = r;
}
void pfGUIDialogNotifyProc::ISendNotify( plKey ctrlKey, UInt32 event )
{
pfGUINotifyMsg *notify = TRACKED_NEW pfGUINotifyMsg( fDialog->GetKey(), fReceiver, nil );
notify->SetEvent( ctrlKey, event );
plgDispatch::MsgSend( notify );
}
void pfGUIDialogNotifyProc::DoSomething( pfGUIControlMod *ctrl )
{
if( pfGUIButtonMod::ConvertNoRef( ctrl ) != nil ||
pfGUIListBoxMod::ConvertNoRef( ctrl ) != nil ||
pfGUIEditBoxMod::ConvertNoRef( ctrl ) != nil )
{
// only fire the button if it is triggering
// ... all other types just fire
pfGUIButtonMod* btn = pfGUIButtonMod::ConvertNoRef( ctrl );
if ( !btn || btn->IsTriggering() )
ISendNotify( ctrl->GetKey(), pfGUINotifyMsg::kAction );
}
else
ISendNotify( ctrl->GetKey(), pfGUINotifyMsg::kValueChanged );
}
void pfGUIDialogNotifyProc::HandleExtendedEvent( pfGUIControlMod *ctrl, UInt32 event )
{
pfGUIEditBoxMod *edit = pfGUIEditBoxMod::ConvertNoRef( ctrl );
if(edit != nil && event == pfGUIEditBoxMod::kWantAutocomplete)
{
//send notify, somebody will do something with that (like python script)
ISendNotify( ctrl->GetKey(), pfGUINotifyMsg::kSpecialAction );
}
else if(edit && event == pfGUIEditBoxMod::kWantMessageHistoryUp)
{
ISendNotify( ctrl->GetKey(), pfGUINotifyMsg::kMessageHistoryUp );
}
else if(edit && event == pfGUIEditBoxMod::kWantMessageHistoryDown)
{
ISendNotify( ctrl->GetKey(), pfGUINotifyMsg::kMessageHistoryDown );
}
}
void pfGUIDialogNotifyProc::OnInit( void )
{
if ( fDialog )
ISendNotify( fDialog->GetKey(), pfGUINotifyMsg::kDialogLoaded );
else
ISendNotify( nil, pfGUINotifyMsg::kDialogLoaded );
}
void pfGUIDialogNotifyProc::OnShow( void )
{
if ( fDialog )
ISendNotify( fDialog->GetKey(), pfGUINotifyMsg::kShowHide );
else
ISendNotify( nil, pfGUINotifyMsg::kShowHide );
}
void pfGUIDialogNotifyProc::OnHide( void )
{
if ( fDialog )
ISendNotify( fDialog->GetKey(), pfGUINotifyMsg::kShowHide );
else
ISendNotify( nil, pfGUINotifyMsg::kShowHide );
}
void pfGUIDialogNotifyProc::OnDestroy( void )
{
}
void pfGUIDialogNotifyProc::OnControlEvent( ControlEvt event )
{
if( event == kExitMode )
ISendNotify( ( fDialog != nil ) ? fDialog->GetKey() : nil, pfGUINotifyMsg::kExitMode );
}
// Called when the dialog's focused control changes
void pfGUIDialogNotifyProc::OnCtrlFocusChange( pfGUIControlMod *oldCtrl, pfGUIControlMod *newCtrl )
{
if ( newCtrl )
ISendNotify( newCtrl->GetKey(), pfGUINotifyMsg::kFocusChange);
else
ISendNotify( nil, pfGUINotifyMsg::kFocusChange);
}
void pfGUIDialogNotifyProc::OnInterestingEvent( pfGUIControlMod *ctrl )
{
ISendNotify( ( ctrl != nil ) ? ctrl->GetKey() : nil, pfGUINotifyMsg::kInterestingEvent );
}

View File

@ -0,0 +1,83 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDialogNotifyProc Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIDialogNotifyProc_h
#define _pfGUIDialogNotifyProc_h
#include "pfGUIDialogHandlers.h"
#include "../pnKeyedObject/plKey.h"
class plGUIControlMod;
//// pfGUIDialogNotifyProc Definition ////////////////////////////////////////
// Helper dialog proc that takes all control events and turns them into
// notify messages that get sent out.
class pfGUIDialogNotifyProc : public pfGUIDialogProc
{
protected:
plKey fReceiver;
void ISendNotify( plKey ctrlKey, UInt32 event );
public:
pfGUIDialogNotifyProc( plKey &r );
virtual void DoSomething( pfGUIControlMod *ctrl );
virtual void HandleExtendedEvent( pfGUIControlMod *ctrl, UInt32 event );
virtual void OnInit( void );
virtual void OnShow( void );
virtual void OnHide( void );
virtual void OnDestroy( void );
virtual void OnCtrlFocusChange( pfGUIControlMod *oldCtrl, pfGUIControlMod *newCtrl );
virtual void OnControlEvent( ControlEvt event );
virtual void OnInterestingEvent( pfGUIControlMod *ctrl );
};
#endif // _pfGUIDialogNotifyProc_h

View File

@ -0,0 +1,165 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDragBarCtrl Definition //
// //
// DragBars are draggable controls that take their dialogs along with //
// them. Because they're essentially part of the dialog directly (the part //
// that can be dragged), they're processed after the normal hit testing. //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIDragBarCtrl.h"
#include "pfGameGUIMgr.h"
#include "pfGUIDialogMod.h"
#include "../plInputCore/plInputInterface.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plAvatar/plAGModifier.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIDragBarCtrl::pfGUIDragBarCtrl()
{
SetFlag( kWantsInterest );
fDragging = false;
fAnchored = false;
}
pfGUIDragBarCtrl::~pfGUIDragBarCtrl()
{
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIDragBarCtrl::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIDragBarCtrl::MsgReceive( plMessage *msg )
{
return pfGUIControlMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIDragBarCtrl::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
}
void pfGUIDragBarCtrl::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Write( s, mgr );
}
//// UpdateBounds ////////////////////////////////////////////////////////////
void pfGUIDragBarCtrl::UpdateBounds( hsMatrix44 *invXformMatrix, hsBool force )
{
pfGUIControlMod::UpdateBounds( invXformMatrix, force );
fBoundsValid = false;
}
//// HandleMouseDown/Up //////////////////////////////////////////////////////
void pfGUIDragBarCtrl::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
// if we are anchored <to the floor> then don't let it be moved
if ( fAnchored )
return;
fDragging = true;
fDragOffset = fScreenCenter - mousePt;
SetObjectCenter( mousePt.fX + fDragOffset.fX, mousePt.fY + fDragOffset.fY );
// We know that the entire dialog is going to move, so we better make
// sure to update the bounds on all the controls
fDialog->UpdateAllBounds();
}
void pfGUIDragBarCtrl::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
// if we are anchored <to the floor> then don't let it be moved
if ( fAnchored )
return;
fDragging = false;
SetObjectCenter( mousePt.fX + fDragOffset.fX, mousePt.fY + fDragOffset.fY );
fDialog->UpdateAllBounds();
}
void pfGUIDragBarCtrl::HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers )
{
// if we are anchored <to the floor> then don't let it be moved
if ( fAnchored )
return;
SetObjectCenter( mousePt.fX + fDragOffset.fX, mousePt.fY + fDragOffset.fY );
fDialog->UpdateAllBounds();
}
//// IGetDesiredCursor ///////////////////////////////////////////////////////
UInt32 pfGUIDragBarCtrl::IGetDesiredCursor( void ) const
{
// if we are anchored, then no cursors that say we can move
if ( fAnchored )
return 0;
if( fDragging )
return plInputInterface::kCursor4WayDragging;
return plInputInterface::kCursor4WayDraggable;
}

View File

@ -0,0 +1,93 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDragBarCtrl Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIDragBarCtrl_h
#define _pfGUIDragBarCtrl_h
#include "pfGUIControlMod.h"
class plMessage;
class pfGUIDragBarCtrl : public pfGUIControlMod
{
protected:
hsPoint3 fDragOffset;
hsBool fDragging;
hsBool fAnchored;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual UInt32 IGetDesiredCursor( void ) const; // As specified in plInputInterface.h
public:
pfGUIDragBarCtrl();
virtual ~pfGUIDragBarCtrl();
CLASSNAME_REGISTER( pfGUIDragBarCtrl );
GETINTERFACE_ANY( pfGUIDragBarCtrl, pfGUIControlMod );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual void SetAnchored( hsBool anchored ) { fAnchored = anchored; }
virtual hsBool IsAnchored(void) { return fAnchored; }
virtual void UpdateBounds( hsMatrix44 *invXformMatrix = nil, hsBool force = false );
// Export only
};
#endif // _pfGUIDragBarCtrl_h

View File

@ -0,0 +1,181 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDraggableMod Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIDraggableMod.h"
#include "pfGameGUIMgr.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plAvatar/plAGModifier.h"
#include "../plInputCore/plInputInterface.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIDraggableMod::pfGUIDraggableMod()
{
SetFlag( kWantsInterest );
fDragging = false;
}
pfGUIDraggableMod::~pfGUIDraggableMod()
{
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIDraggableMod::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIDraggableMod::MsgReceive( plMessage *msg )
{
return pfGUIControlMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIDraggableMod::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
}
void pfGUIDraggableMod::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Write( s, mgr );
}
//// UpdateBounds ////////////////////////////////////////////////////////////
void pfGUIDraggableMod::UpdateBounds( hsMatrix44 *invXformMatrix, hsBool force )
{
pfGUIControlMod::UpdateBounds( invXformMatrix, force );
fBoundsValid = false;
}
//// HandleMouseDown/Up //////////////////////////////////////////////////////
void pfGUIDraggableMod::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
if( !fDragging )
{
fLastMousePt = mousePt;
fOrigCenter = fScreenCenter;
fDragging = true;
fDragOffset = fScreenCenter - mousePt;
SetObjectCenter( mousePt.fX + fDragOffset.fX, mousePt.fY + fDragOffset.fY );
HandleExtendedEvent( kStartingDrag );
}
}
void pfGUIDraggableMod::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
if( fDragging )
{
fLastMousePt = mousePt;
fDragging = false;
SetObjectCenter( mousePt.fX + fDragOffset.fX, mousePt.fY + fDragOffset.fY );
DoSomething();
if( HasFlag( kAlwaysSnapBackToStart ) )
SetObjectCenter( fOrigCenter.fX, fOrigCenter.fY );
}
}
void pfGUIDraggableMod::HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers )
{
if( fDragging )
{
fLastMousePt = mousePt;
SetObjectCenter( mousePt.fX + fDragOffset.fX, mousePt.fY + fDragOffset.fY );
if( HasFlag( kReportDragging ) )
HandleExtendedEvent( kDragging );
}
}
//// IGetDesiredCursor ///////////////////////////////////////////////////////
UInt32 pfGUIDraggableMod::IGetDesiredCursor( void ) const
{
// if we are anchored, then no cursors that say we can move
if( fDragging )
{
if( HasFlag( kHideCursorWhileDragging ) )
return plInputInterface::kCursorHidden;
return plInputInterface::kCursor4WayDragging;
}
return plInputInterface::kCursor4WayDraggable;
}
void pfGUIDraggableMod::StopDragging( hsBool cancel )
{
if( fDragging )
{
fDragging = false;
if( cancel )
HandleExtendedEvent( kCancelled );
if( HasFlag( kAlwaysSnapBackToStart ) )
SetObjectCenter( fOrigCenter.fX, fOrigCenter.fY );
}
}

View File

@ -0,0 +1,106 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDraggableMod Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIDraggableMod_h
#define _pfGUIDraggableMod_h
#include "pfGUIControlMod.h"
class plMessage;
class pfGUIDraggableMod : public pfGUIControlMod
{
protected:
hsPoint3 fDragOffset, fLastMousePt;
hsPoint3 fOrigCenter;
hsBool fDragging;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual UInt32 IGetDesiredCursor( void ) const; // As specified in plInputInterface.h
public:
pfGUIDraggableMod();
virtual ~pfGUIDraggableMod();
CLASSNAME_REGISTER( pfGUIDraggableMod );
GETINTERFACE_ANY( pfGUIDraggableMod, pfGUIControlMod );
enum OurFlags
{
kReportDragging = kDerivedFlagsStart,
kHideCursorWhileDragging,
kAlwaysSnapBackToStart
};
// Extended event types (endDrag is the default event)
enum ExtendedEvents
{
kDragging,
kCancelled,
kStartingDrag
};
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual void UpdateBounds( hsMatrix44 *invXformMatrix = nil, hsBool force = false );
void StopDragging( hsBool cancel );
const hsPoint3 &GetLastMousePt( void ) const { return fLastMousePt; }
};
#endif // _pfGUIDraggableMod_h

View File

@ -0,0 +1,185 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDynDisplayCtrl Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIDynDisplayCtrl.h"
#include "pfGameGUIMgr.h"
#include "../pnMessage/plRefMsg.h"
#include "../plGImage/plDynamicTextMap.h"
#include "../plSurface/plLayerInterface.h"
#include "../plSurface/hsGMaterial.h"
#include "../plPipeline/plTextGenerator.h"
#include "plPipeline.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIDynDisplayCtrl::pfGUIDynDisplayCtrl()
{
SetFlag( kIntangible );
}
pfGUIDynDisplayCtrl::~pfGUIDynDisplayCtrl()
{
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIDynDisplayCtrl::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIDynDisplayCtrl::MsgReceive( plMessage *msg )
{
plGenRefMsg *refMsg = plGenRefMsg::ConvertNoRef( msg );
if( refMsg != nil )
{
if( refMsg->fType == kRefTextMap )
{
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
fTextMaps[ refMsg->fWhich ] = plDynamicTextMap::ConvertNoRef( refMsg->GetRef() );
else
fTextMaps[ refMsg->fWhich ] = nil;
return true;
}
else if( refMsg->fType == kRefLayer )
{
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
fLayers[ refMsg->fWhich ] = plLayerInterface::ConvertNoRef( refMsg->GetRef() );
else
fLayers[ refMsg->fWhich ] = nil;
return true;
}
else if( refMsg->fType == kRefMaterial )
{
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
fMaterials[ refMsg->fWhich ] = hsGMaterial::ConvertNoRef( refMsg->GetRef() );
else
fMaterials[ refMsg->fWhich ] = nil;
}
}
return pfGUIControlMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIDynDisplayCtrl::Read( hsStream *s, hsResMgr *mgr )
{
UInt32 count, i;
pfGUIControlMod::Read(s, mgr);
count = s->ReadSwap32();
fTextMaps.SetCountAndZero( count );
for( i = 0; i < count; i++ )
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, i, kRefTextMap ), plRefFlags::kActiveRef );
count = s->ReadSwap32();
fLayers.SetCountAndZero( count );
for( i = 0; i < count; i++ )
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, i, kRefLayer ), plRefFlags::kActiveRef );
count = s->ReadSwap32();
fMaterials.SetCountAndZero( count );
for( i = 0; i < count; i++ )
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, i, kRefMaterial ), plRefFlags::kActiveRef );
}
void pfGUIDynDisplayCtrl::Write( hsStream *s, hsResMgr *mgr )
{
UInt32 i;
pfGUIControlMod::Write( s, mgr );
s->WriteSwap32( fTextMaps.GetCount() );
for( i = 0; i < fTextMaps.GetCount(); i++ )
mgr->WriteKey( s, fTextMaps[ i ]->GetKey() );
s->WriteSwap32( fLayers.GetCount() );
for( i = 0; i < fLayers.GetCount(); i++ )
mgr->WriteKey( s, fLayers[ i ]->GetKey() );
s->WriteSwap32( fMaterials.GetCount() );
for( i = 0; i < fMaterials.GetCount(); i++ )
mgr->WriteKey( s, fMaterials[ i ]->GetKey() );
}
//// AddMap //////////////////////////////////////////////////////////////////
// Export only
void pfGUIDynDisplayCtrl::AddMap( plDynamicTextMap *map )
{
fTextMaps.Append( map );
hsgResMgr::ResMgr()->AddViaNotify( map->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, fTextMaps.GetCount() - 1, kRefTextMap ), plRefFlags::kActiveRef );
}
//// AddLayer ////////////////////////////////////////////////////////////////
// Export only
void pfGUIDynDisplayCtrl::AddLayer( plLayerInterface *layer )
{
fLayers.Append( layer );
hsgResMgr::ResMgr()->AddViaNotify( layer->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, fLayers.GetCount() - 1, kRefLayer ), plRefFlags::kActiveRef );
}
//// AddMaterial /////////////////////////////////////////////////////////////
// Export only
void pfGUIDynDisplayCtrl::AddMaterial( hsGMaterial *material )
{
fMaterials.Append( material );
hsgResMgr::ResMgr()->AddViaNotify( material->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, fMaterials.GetCount() - 1, kRefMaterial ), plRefFlags::kActiveRef );
}

View File

@ -0,0 +1,113 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIDynDisplayCtrl Header //
// //
// Fun little helper control that just stores a pointer to a single //
// plDynamicTextMap, chosen in MAX. Note that we could also just search //
// for the right key name, but that requires a StupidSearch(tm), while //
// this way just requires an extra dummy control that automatically reads //
// in the right ref (and searching for controls by TagID is a lot faster //
// than searching for keys). //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIDynDisplayCtrl_h
#define _pfGUIDynDisplayCtrl_h
#include "pfGUIControlMod.h"
#include "hsTemplates.h"
class plMessage;
class plDynamicTextMap;
class plLayerInterface;
class hsGMaterial;
class pfGUIDynDisplayCtrl : public pfGUIControlMod
{
protected:
enum
{
kRefTextMap = kRefDerivedStart,
kRefLayer,
kRefMaterial
};
hsTArray<plDynamicTextMap *> fTextMaps;
hsTArray<plLayerInterface *> fLayers;
hsTArray<hsGMaterial *> fMaterials;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
public:
pfGUIDynDisplayCtrl();
virtual ~pfGUIDynDisplayCtrl();
CLASSNAME_REGISTER( pfGUIDynDisplayCtrl );
GETINTERFACE_ANY( pfGUIDynDisplayCtrl, pfGUIControlMod );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
UInt32 GetNumMaps( void ) const { return fTextMaps.GetCount(); }
plDynamicTextMap *GetMap( UInt32 i ) const { return fTextMaps[ i ]; }
UInt32 GetNumLayers( void ) const { return fLayers.GetCount(); }
plLayerInterface *GetLayer( UInt32 i ) const { return fLayers[ i ]; }
UInt32 GetNumMaterials( void ) const { return fMaterials.GetCount(); }
hsGMaterial *GetMaterial( UInt32 i ) const { return fMaterials[ i ]; }
// Export only
void AddMap( plDynamicTextMap *map );
void AddLayer( plLayerInterface *layer );
void AddMaterial( hsGMaterial *material );
};
#endif // _pfGUIDynDisplayCtrl_h

View File

@ -0,0 +1,710 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIEditBoxMod Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#ifdef PLASMA_EXTERNAL_RELEASE
//#define LIMIT_VOICE_CHAT 1
#endif
#include "hsTypes.h"
#include "pfGUIEditBoxMod.h"
#include "pfGameGUIMgr.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plAvatar/plAGModifier.h"
#include "../plGImage/plDynamicTextMap.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
#include "../pnInputCore/plKeyMap.h"
#include "../plClipboard/plClipboard.h"
#include <locale>
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIEditBoxMod::pfGUIEditBoxMod()
{
SetFlag( kWantsInterest );
SetFlag( kTakesSpecialKeys );
fIgnoreNextKey = false;
fEscapedFlag = false;
fFirstHalfExitKeyPushed = false;
fSpecialCaptureKeyEventMode = false;
fBuffer = 0;
fLastDeadKey = 0;
SetBufferSize( 128 );
SetupDeadKeyConverter();
}
pfGUIEditBoxMod::~pfGUIEditBoxMod()
{
delete [] fBuffer;
}
void pfGUIEditBoxMod::SetupDeadKeyConverter()
{
int i,j;
for (i=0; i<255; i++)
for (j=0; j<255; j++)
fDeadKeyConverter[i][j] = 0L;
// we are adding 100 to the indexes because some of these chars have a negative index for some reason
fDeadKeyConverter['^'+100]['a'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['e'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['i'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['o'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['u'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['A'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['E'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['I'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['O'] = L'<EFBFBD>';
fDeadKeyConverter['^'+100]['U'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['a'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['e'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['i'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['o'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['u'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['A'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['E'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['I'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['O'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['U'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['a'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['e'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['i'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['o'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['u'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['y'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['A'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['E'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['I'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['O'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['U'] = L'<EFBFBD>';
fDeadKeyConverter['<EFBFBD>'+100]['Y'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['a'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['e'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['i'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['o'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['u'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['A'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['E'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['I'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['O'] = L'<EFBFBD>';
fDeadKeyConverter['`'+100]['U'] = L'<EFBFBD>';
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIEditBoxMod::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIEditBoxMod::MsgReceive( plMessage *msg )
{
return pfGUIControlMod::MsgReceive( msg );
}
//// IPostSetUpDynTextMap ////////////////////////////////////////////////////
void pfGUIEditBoxMod::IPostSetUpDynTextMap( void )
{
pfGUIColorScheme *scheme = GetColorScheme();
fDynTextMap->SetFont( scheme->fFontFace, scheme->fFontSize, scheme->fFontFlags,
HasFlag( kXparentBgnd ) ? false : true );
}
//// IUpdate /////////////////////////////////////////////////////////////////
void pfGUIEditBoxMod::IUpdate( void )
{
hsColorRGBA c;
if( fDynTextMap == nil || !fDynTextMap->IsValid() )
return;
c.Set( 0.f, 0.f, 0.f, 1.f );
if ( fFocused && fSpecialCaptureKeyEventMode )
fDynTextMap->ClearToColor( GetColorScheme()->fSelBackColor );
else
fDynTextMap->ClearToColor( GetColorScheme()->fBackColor );
if( fBuffer != nil )
{
// First, calc the cursor position, so we can adjust the scrollPos as necessary
Int16 cursorPos, oldCursorPos;
if( fFocused && !fSpecialCaptureKeyEventMode )
{
// Really cheap hack here to figure out where to draw the cursor
wchar_t backup = fBuffer[ fCursorPos ];
fBuffer[ fCursorPos ] = 0;
cursorPos = fDynTextMap->CalcStringWidth( fBuffer );
fBuffer[ fCursorPos ] = backup;
oldCursorPos = cursorPos;
cursorPos -= (Int16)fScrollPos;
if( 4 + cursorPos > fDynTextMap->GetVisibleWidth() - 4 - 2 )
{
fScrollPos += ( 4 + cursorPos ) - ( fDynTextMap->GetVisibleWidth() - 4 - 2 );
}
else if( 4 + cursorPos < 4 )
{
fScrollPos -= 4 - ( 4 + cursorPos );
if( fScrollPos < 0 )
fScrollPos = 0;
}
cursorPos = (Int16)(oldCursorPos - fScrollPos);
}
if ( fFocused && fSpecialCaptureKeyEventMode )
// if special and has focus then use select
fDynTextMap->SetTextColor( GetColorScheme()->fSelForeColor, GetColorScheme()->fTransparent &&
GetColorScheme()->fSelBackColor.a == 0.f );
else
fDynTextMap->SetTextColor( GetColorScheme()->fForeColor, GetColorScheme()->fTransparent &&
GetColorScheme()->fBackColor.a == 0.f );
fDynTextMap->DrawClippedString( (Int16)(4 - fScrollPos), 4, fBuffer,
4, 4, fDynTextMap->GetVisibleWidth() - 8, fDynTextMap->GetVisibleHeight() - 8 );
if( fFocused && !fSpecialCaptureKeyEventMode )
{
fDynTextMap->FrameRect( 4 + cursorPos, 4, 2, fDynTextMap->GetVisibleHeight() - 8, GetColorScheme()->fSelForeColor );
}
}
fDynTextMap->FlushToHost();
}
void pfGUIEditBoxMod::PurgeDynaTextMapImage()
{
if ( fDynTextMap != nil )
fDynTextMap->PurgeImage();
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIEditBoxMod::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
}
void pfGUIEditBoxMod::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Write( s, mgr );
}
//// HandleMouseDown /////////////////////////////////////////////////////////
// What we do: normal click deselects all and selects the item clicked on
// (if any). Shift-click and ctrl-click avoids the deselect and toggles
// the item clicked on.
void pfGUIEditBoxMod::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
wchar_t backup;
UInt16 width;
if( fBuffer != nil && fDynTextMap != nil )
{
if( !fBounds.IsInside( &mousePt ) )
return;
IScreenToLocalPt( mousePt );
mousePt.fX *= fDynTextMap->GetVisibleWidth();
mousePt.fX += fScrollPos - 4;
for( fCursorPos = 0; fCursorPos < wcslen( fBuffer ); fCursorPos++ )
{
backup = fBuffer[ fCursorPos + 1 ];
fBuffer[ fCursorPos + 1 ] = 0;
width = fDynTextMap->CalcStringWidth( fBuffer );
fBuffer[ fCursorPos + 1 ] = backup;
if( width > mousePt.fX )
break;
}
IUpdate();
}
}
//// HandleMouseUp ///////////////////////////////////////////////////////////
void pfGUIEditBoxMod::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
}
//// HandleMouseDrag /////////////////////////////////////////////////////////
void pfGUIEditBoxMod::HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers )
{
}
hsBool pfGUIEditBoxMod::HandleKeyPress( char inKey, UInt8 modifiers )
{
wchar_t key = (wchar_t)inKey;
if( fBuffer == nil )
return false;
if( fIgnoreNextKey )
{
// So we don't process keys that already got handled by HandleKeyEvent()
fIgnoreNextKey = false;
return true;
}
if (plKeyboardDevice::KeyIsDeadKey())
{
if (fLastDeadKey != 0)
{
wchar_t temp = key; // we have two dead keys in a row, print out the old one and store the new one
key = fLastDeadKey;
fLastDeadKey = temp;
}
else
{
fLastDeadKey = key; // store the dead key and don't print it until we get the next char
return true;
}
}
int i = wcslen( fBuffer );
if (fLastDeadKey != 0) // we have a dead key that needs to be added in
{
wchar_t translatedKey = fDeadKeyConverter[(char)fLastDeadKey+100][(char)key];
if (translatedKey == 0) // no translation possible?
{
// so we need to print the dead key, followed by the typed key
// unless key is a space, then we just type the dead key
if (key == L' ')
{
if (i<fBufferSize - 1)
{
memmove(fBuffer+fCursorPos+1, fBuffer+fCursorPos, (i - fCursorPos + 1) * sizeof(wchar_t));
fBuffer[fCursorPos] = fLastDeadKey;
fCursorPos++;
HandleExtendedEvent(kValueChanging);
}
fLastDeadKey = 0L;
IUpdate();
return true;
}
// print two chars now
if (i<fBufferSize - 2 && key != 0L)
{
memmove(fBuffer+fCursorPos+2, fBuffer+fCursorPos, (i - fCursorPos + 2) * sizeof(wchar_t));
fBuffer[fCursorPos] = fLastDeadKey;
fCursorPos++;
fBuffer[fCursorPos] = key;
fCursorPos++;
HandleExtendedEvent( kValueChanging );
}
fLastDeadKey = 0L;
IUpdate();
return true;
}
// ok, so we have a translated key now, so assign it to our key and print it normally
key = translatedKey;
fLastDeadKey = 0;
}
// Insert character at the current cursor position, then inc the cursor by one
if( i < fBufferSize - 1 && key != 0 )
{
memmove( fBuffer + fCursorPos + 1, fBuffer + fCursorPos, (i - fCursorPos + 1) * sizeof(wchar_t) );
fBuffer[ fCursorPos ] = key;
fCursorPos++;
HandleExtendedEvent( kValueChanging );
}
IUpdate();
return true;
}
hsBool pfGUIEditBoxMod::HandleKeyEvent( pfGameGUIMgr::EventType event, plKeyDef key, UInt8 modifiers )
{
if ( fSpecialCaptureKeyEventMode)
{
// handle doing special caputre mode
if ( event == pfGameGUIMgr::kKeyDown )
{
#ifdef LIMIT_VOICE_CHAT
// don't allow them to map the TAB key to anything! 'cause we'll use it later
if ( key == KEY_TAB)
{
fIgnoreNextKey = true;
fFirstHalfExitKeyPushed = false;
return true;
}
#endif
// capture the key
fSavedKey = key;
fSavedModifiers = modifiers;
// turn key event into string
char keyStr[30];
if (plKeyMap::ConvertVKeyToChar( key ))
strcpy(keyStr, plKeyMap::ConvertVKeyToChar( key ));
else
memset(keyStr, 0, sizeof(keyStr));
static char shortKey[ 2 ];
if( strlen(keyStr) == 0 )
{
if( isalnum( key ) )
{
shortKey[ 0 ] = (char)key;
shortKey[ 1 ] = 0;
strcpy(keyStr, shortKey);
}
else
strcpy(keyStr, plKeyMap::GetStringUnmapped());
}
else
{
// check to see the buffer has ForewardSlash and change it to ForwardSlash
if ( strcmp(keyStr,"ForewardSlash") == 0)
{
strcpy(keyStr,"ForwardSlash");
}
}
static char newKey[ 16 ];
newKey[0] = 0;
if( modifiers & kShift )
strcat( newKey, plKeyMap::GetStringShift() );
if( modifiers & kCtrl )
strcat( newKey, plKeyMap::GetStringCtrl() );
strcat( newKey, keyStr );
// set something in the buffer to be displayed
wchar_t* temp = hsStringToWString(newKey);
wcsncpy( fBuffer, temp , fBufferSize - 1 );
delete [] temp;
fCursorPos = 0;
SetCursorToEnd();
IUpdate();
// done capturing... tell the handler
DoSomething();
}
fIgnoreNextKey = true;
fFirstHalfExitKeyPushed = false;
return true;
}
else
{
// HACK for now--pass through caps lock so the runlock stuff will work even while a GUI is up
if( key == KEY_CAPSLOCK )
return false;
if( event == pfGameGUIMgr::kKeyDown || event == pfGameGUIMgr::kKeyRepeat )
{
fFirstHalfExitKeyPushed = false;
// Use arrow keys to do our dirty work
if( key == KEY_HOME )
{
SetCursorToHome();
}
else if( key == KEY_END )
{
SetCursorToEnd();
}
else if( key == KEY_LEFT )
{
if( fCursorPos > 0 )
fCursorPos--;
}
else if( key == KEY_RIGHT && fBuffer != nil )
{
if( fCursorPos < wcslen( fBuffer ) )
fCursorPos++;
}
else if( key == KEY_BACKSPACE && fBuffer != nil )
{
if( fCursorPos > 0 )
{
fCursorPos--;
memmove( fBuffer + fCursorPos, fBuffer + fCursorPos + 1, (wcslen( fBuffer + fCursorPos + 1 ) + 1) * sizeof(wchar_t) );
}
}
else if( key == KEY_DELETE && fBuffer != nil )
{
if( fCursorPos < wcslen( fBuffer ) )
memmove( fBuffer + fCursorPos, fBuffer + fCursorPos + 1, (wcslen( fBuffer + fCursorPos + 1 ) + 1) * sizeof(wchar_t) );
}
else if( key == KEY_ENTER )
{
// do nothing here... wait for the keyup event
fFirstHalfExitKeyPushed = true;
}
else if( key == KEY_ESCAPE )
{
// // do nothing here... wait for the keyup event
// fFirstHalfExitKeyPushed = true;
fEscapedFlag = true;
DoSomething(); // Query WasEscaped() to see if it was escape vs enter
return true;
}
else if (key == KEY_TAB)
{
//Send notify for python scripts
HandleExtendedEvent(kWantAutocomplete);
}
else if (key == KEY_UP)
{
// Send notify for python scripts
HandleExtendedEvent(kWantMessageHistoryUp);
}
else if (key == KEY_DOWN)
{
// Send notify for python scripts
HandleExtendedEvent(kWantMessageHistoryDown);
}
else if (modifiers & pfGameGUIMgr::kCtrlDown)
{
if (key == KEY_C)
{
plClipboard::GetInstance().SetClipboardText(fBuffer);
}
else if (key == KEY_V)
{
wchar_t* contents = plClipboard::GetInstance().GetClipboardText();
if (contents != nil)
{
size_t len = wcslen(contents);
if (len > 0)
{
wchar_t* insertTarget = fBuffer + fCursorPos;
size_t bufferTailLen = wcslen(insertTarget) + 1; //include terminating \0
if (fCursorPos + len + bufferTailLen < fBufferSize)
{
memmove(insertTarget + len, insertTarget, bufferTailLen * sizeof(wchar_t));
memcpy(insertTarget, contents, len * sizeof(wchar_t));
fCursorPos += len;
HandleExtendedEvent( kValueChanging );
}
}
delete contents;
}
}
}
else
{
fIgnoreNextKey = false;
return true;
}
fIgnoreNextKey = true;
IUpdate();
return true;
}
// wait until the Key up for enter and escape to make sure we capture the whole key
// ...before we give on focus control
else if( event == pfGameGUIMgr::kKeyUp )
{
if( key == KEY_ENTER )
{
if (fFirstHalfExitKeyPushed)
{
// Do jack, just here to filter out it being added to the buffer
// Well, ok, actually do *something*. *cough*.
DoSomething();
fFirstHalfExitKeyPushed = false;
return true;
}
}
else if( key == KEY_ESCAPE )
{
if (fFirstHalfExitKeyPushed)
{
// fEscapedFlag = true;
// DoSomething(); // Query WasEscaped() to see if it was escape vs enter
fFirstHalfExitKeyPushed = false;
return true;
}
}
fFirstHalfExitKeyPushed = false;
return true;
}
else
{
// We don't process them, but we don't want anybody else processing them either
return true;
}
}
}
std::string pfGUIEditBoxMod::GetBuffer( void )
{
char* temp = hsWStringToString(fBuffer);
std::string retVal = temp;
delete [] temp;
return retVal;
}
void pfGUIEditBoxMod::ClearBuffer( void )
{
if( fBuffer != nil )
{
memset( fBuffer, 0, (fBufferSize + 1) * sizeof(wchar_t) );
fCursorPos = 0;
fScrollPos = 0;
IUpdate();
}
}
void pfGUIEditBoxMod::SetText( const char *str )
{
wchar_t* temp = hsStringToWString(str);
SetText(temp);
delete [] temp;
}
void pfGUIEditBoxMod::SetText( const wchar_t *str )
{
if( fBuffer != nil )
{
wcsncpy( fBuffer, str, fBufferSize - 1 );
fCursorPos = 0;
fScrollPos = 0;
IUpdate();
}
}
void pfGUIEditBoxMod::SetBufferSize( UInt32 size )
{
delete [] fBuffer;
fBufferSize = size;
if( size > 0 )
{
fBuffer = TRACKED_NEW wchar_t[ size + 1 ];
memset( fBuffer, 0, (size + 1) * sizeof(wchar_t) );
}
else
fBuffer = nil;
fCursorPos = 0;
fScrollPos = 0;
}
void pfGUIEditBoxMod::SetCursorToHome( void )
{
fCursorPos = 0;
}
void pfGUIEditBoxMod::SetCursorToEnd( void )
{
if( fBuffer != nil )
fCursorPos = wcslen( fBuffer );
}
void pfGUIEditBoxMod::SetLastKeyCapture(UInt32 key, UInt8 modifiers)
{
// capture the key
fSavedKey = (plKeyDef)key;
fSavedModifiers = modifiers;
// turn key event into string
char keyStr[30];
if (plKeyMap::ConvertVKeyToChar( key ))
strcpy(keyStr, plKeyMap::ConvertVKeyToChar( key ));
else
memset(keyStr, 0, sizeof(keyStr));
static char shortKey[ 2 ];
if( strlen(keyStr) == 0 )
{
if( isalnum( key ) )
{
shortKey[ 0 ] = (char)key;
shortKey[ 1 ] = 0;
strcpy(keyStr, shortKey);
}
else
strcpy(keyStr, plKeyMap::GetStringUnmapped());
}
else
{
// check to see the buffer has ForewardSlash and change it to ForwardSlash
if ( strcmp(keyStr,"ForewardSlash") == 0)
{
strcpy(keyStr,"ForwardSlash");
}
}
static char newKey[ 16 ];
newKey[0] = 0;
if( modifiers & kShift )
strcat( newKey, plKeyMap::GetStringShift() );
if( modifiers & kCtrl )
strcat( newKey, plKeyMap::GetStringCtrl() );
strcat( newKey, keyStr );
// set something in the buffer to be displayed
wchar_t* temp = hsStringToWString(newKey);
wcsncpy( fBuffer, temp , fBufferSize - 1 );
delete [] temp;
fCursorPos = 0;
SetCursorToEnd();
IUpdate();
}

View File

@ -0,0 +1,144 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIEditBoxMod Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIEditBoxMod_h
#define _pfGUIEditBoxMod_h
#include "hsStlUtils.h"
#include "pfGUIControlMod.h"
#include "../pnInputCore/plKeyDef.h"
#include "../plInputCore/plInputDevice.h"
class plMessage;
class hsGMaterial;
class plTextGenerator;
class pfGUIEditBoxMod : public pfGUIControlMod
{
protected:
wchar_t *fBuffer;
UInt32 fBufferSize, fCursorPos;
Int32 fScrollPos;
hsBool fIgnoreNextKey, fEscapedFlag;
hsBool fFirstHalfExitKeyPushed;
hsBool fSpecialCaptureKeyEventMode;
plKeyDef fSavedKey;
UInt8 fSavedModifiers;
wchar_t fLastDeadKey; // if the previous key was a dead key, its value goes here
wchar_t fDeadKeyConverter[256][256]; // first index is the dead key, second index is the char to combine it with
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual void IPostSetUpDynTextMap( void );
virtual void IUpdate( void );
void SetupDeadKeyConverter();
public:
enum
{
kShift = 0x01,
kCtrl = 0x02
};
pfGUIEditBoxMod();
virtual ~pfGUIEditBoxMod();
CLASSNAME_REGISTER( pfGUIEditBoxMod );
GETINTERFACE_ANY( pfGUIEditBoxMod, pfGUIControlMod );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual hsBool HandleKeyPress( char key, UInt8 modifiers );
virtual hsBool HandleKeyEvent( pfGameGUIMgr::EventType event, plKeyDef key, UInt8 modifiers );
virtual void PurgeDynaTextMapImage();
void SetBufferSize( UInt32 size );
std::string GetBuffer( void );
std::wstring GetBufferW( void ) { return fBuffer; }
void ClearBuffer( void );
void SetText( const char *str );
void SetText( const wchar_t *str );
void SetCursorToHome( void );
void SetCursorToEnd( void );
hsBool WasEscaped( void ) { hsBool e = fEscapedFlag; fEscapedFlag = false; return e; }
void SetSpecialCaptureKeyMode(hsBool state) { fSpecialCaptureKeyEventMode = state; }
UInt32 GetLastKeyCaptured() { return (UInt32)fSavedKey; }
UInt8 GetLastModifiersCaptured() { return fSavedModifiers; }
void SetLastKeyCapture(UInt32 key, UInt8 modifiers);
void SetChatMode(hsBool state) { plKeyboardDevice::IgnoreCapsLock(state); }
// Extended event types
enum ExtendedEvents
{
kValueChanging,
kWantAutocomplete,
kWantMessageHistoryUp,
kWantMessageHistoryDown
};
};
#endif // _pfGUIEditBoxMod_h

View File

@ -0,0 +1,384 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIKnobCtrl Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIKnobCtrl.h"
#include "pfGameGUIMgr.h"
#include "pfGUIDialogMod.h"
#include "../plInputCore/plInputInterface.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
// #include "../plAvatar/plAGModifier.h"
#include "../plAvatar/plAGMasterMod.h"
#include "../plAvatar/plAGAnimInstance.h"
#include "../plSurface/plLayerAnimation.h"
#include "../pnSceneObject/plSceneObject.h"
#include "../pnSceneObject/plCoordinateInterface.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIKnobCtrl::pfGUIKnobCtrl() :
fAnimName(nil),
fDragStart(0.f, 0.f, 0.f),
fDragging(false),
fAnimStartPos(0.f, 0.f, 0.f),
fAnimEndPos(0.f, 0.f, 0.f),
fDragRangeMin(0.f),
fDragRangeMax(0.f),
fAnimBegin(0.f),
fAnimEnd(0.f),
fAnimTimesCalced(false)
{
SetFlag( kWantsInterest );
}
pfGUIKnobCtrl::~pfGUIKnobCtrl()
{
delete [] fAnimName;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIKnobCtrl::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIValueCtrl::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIKnobCtrl::MsgReceive( plMessage *msg )
{
return pfGUIValueCtrl::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIKnobCtrl::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIValueCtrl::Read(s, mgr);
fAnimationKeys.Reset();
UInt32 i, count = s->ReadSwap32();
for( i = 0; i < count; i++ )
fAnimationKeys.Append( mgr->ReadKey( s ) );
fAnimName = s->ReadSafeString();
fAnimTimesCalced = false;
fAnimStartPos.Read( s );
fAnimEndPos.Read( s );
}
void pfGUIKnobCtrl::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIValueCtrl::Write( s, mgr );
UInt32 i, count = fAnimationKeys.GetCount();
s->WriteSwap32( count );
for( i = 0; i < count; i++ )
mgr->WriteKey( s, fAnimationKeys[ i ] );
s->WriteSafeString( fAnimName );
fAnimStartPos.Write( s );
fAnimEndPos.Write( s );
}
//// UpdateBounds ////////////////////////////////////////////////////////////
void pfGUIKnobCtrl::UpdateBounds( hsMatrix44 *invXformMatrix, hsBool force )
{
pfGUIValueCtrl::UpdateBounds( invXformMatrix, force );
if( fAnimationKeys.GetCount() > 0 )
fBoundsValid = false;
}
//// HandleMouseDown/Up //////////////////////////////////////////////////////
void pfGUIKnobCtrl::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
fDragStart = mousePt;
fDragValue = fValue;
fDragging = true;
if( HasFlag( kMapToAnimationRange ) )
{
hsPoint3 scrnStart, scrnEnd;
// At mouse-down, we take our local-space start and end points and
// translate them by our parent object's local-to-world to get the
// right points in world-space. We do this now because our parent
// might be animated, which could complicate matters a tad.
scrnStart = fAnimStartPos;
scrnEnd = fAnimEndPos;
plSceneObject *target = GetTarget();
if( target != nil )
{
const plCoordinateInterface *ci = target->GetCoordinateInterface();
if( ci != nil )
{
const plCoordinateInterface *parentCI = ci->GetParent();
if( parentCI != nil )
{
const hsMatrix44 &parentLocalToWorld = parentCI->GetLocalToWorld();
scrnStart = parentLocalToWorld * scrnStart;
scrnEnd = parentLocalToWorld * scrnEnd;
}
}
}
scrnStart = fDialog->WorldToScreenPoint( scrnStart );
scrnEnd = fDialog->WorldToScreenPoint( scrnEnd );
if( HasFlag( kLeftRightOrientation ) )
{
fDragRangeMin = scrnStart.fX;
fDragRangeMax = scrnEnd.fX;
}
else
{
fDragRangeMin = scrnStart.fY;
fDragRangeMax = scrnEnd.fY;
}
}
else if( HasFlag( kMapToScreenRange ) )
{
fDragRangeMin = 0.f;
fDragRangeMax = 1.f;
}
else
fDragRangeMin = -1;
}
void pfGUIKnobCtrl::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
fDragging = false;
HandleMouseDrag( mousePt, modifiers );
}
void pfGUIKnobCtrl::HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers )
{
hsScalar oldValue = fValue, newValue = fDragValue;
if( fDragRangeMin != -1 )
{
if( HasFlag( kLeftRightOrientation ) )
{
if( mousePt.fX < fDragRangeMin )
newValue = fMin;
else if( mousePt.fX > fDragRangeMax )
newValue = fMax;
else
newValue = ( ( mousePt.fX - fDragRangeMin ) / ( fDragRangeMax - fDragRangeMin ) ) *
( fMax - fMin ) + fMin;
}
else
{
if( mousePt.fY > fDragRangeMin )
newValue = fMin;
else if( mousePt.fY < fDragRangeMax )
newValue = fMax;
else
newValue = ( ( fDragRangeMin - mousePt.fY) / ( fDragRangeMin - fDragRangeMax ) ) *
( fMax - fMin ) + fMin;
}
if( HasFlag( kReverseValues ) )
SetCurrValue( fMax - ( newValue - fMin ) );
else
SetCurrValue( newValue );
}
else
{
hsScalar diff;
if( HasFlag( kLeftRightOrientation ) )
diff = ( mousePt.fX - fDragStart.fX ) * 20.f;
else
diff = ( fDragStart.fY - mousePt.fY ) * 20.f;
if( HasFlag( kReverseValues ) )
SetCurrValue( fDragValue - diff );
else
SetCurrValue( fDragValue + diff );
}
// !fDragging = We're mousing-up, so if we're still dragging, we need to not have the only-
// on-mouse-up flag set. Just FYI
if( !fDragging || !HasFlag( kTriggerOnlyOnMouseUp ) )
DoSomething();
}
//// SetAnimationKeys ////////////////////////////////////////////////////////
void pfGUIKnobCtrl::SetAnimationKeys( hsTArray<plKey> &keys, const char *name )
{
fAnimationKeys = keys;
delete [] fAnimName;
if( name != nil )
{
fAnimName = TRACKED_NEW char[ strlen( name ) + 1 ];
strcpy( fAnimName, name );
}
else
fAnimName = nil;
}
//// ICalcAnimTimes //////////////////////////////////////////////////////////
// Loops through and computes the max begin and end for our animations. If
// none of them are loaded and we're not already calced, returns false.
hsBool pfGUIKnobCtrl::ICalcAnimTimes( void )
{
if( fAnimTimesCalced )
return true;
hsScalar tBegin = 1e30, tEnd = -1e30;
bool foundOne = false;
for( int i = 0; i < fAnimationKeys.GetCount(); i++ )
{
// Handle AGMasterMods
plAGMasterMod *mod = plAGMasterMod::ConvertNoRef( fAnimationKeys[ i ]->ObjectIsLoaded() );
if( mod != nil )
{
for( int j = 0; j < mod->GetNumAnimations(); j++ )
{
hsScalar begin = mod->GetAnimInstance( j )->GetTimeConvert()->GetBegin();
hsScalar end = mod->GetAnimInstance( j )->GetTimeConvert()->GetEnd();
if( begin < tBegin )
tBegin = begin;
if( end > tEnd )
tEnd = end;
}
foundOne = true;
}
// Handle layer animations
plLayerAnimation *layer = plLayerAnimation::ConvertNoRef( fAnimationKeys[ i ]->ObjectIsLoaded() );
if( layer != nil )
{
hsScalar begin = layer->GetTimeConvert().GetBegin();
hsScalar end = layer->GetTimeConvert().GetEnd();
if( begin < tBegin )
tBegin = begin;
if( end > tEnd )
tEnd = end;
foundOne = true;
}
}
if( foundOne )
{
fAnimBegin = tBegin;
fAnimEnd = tEnd;
fAnimTimesCalced = true;
}
return fAnimTimesCalced;
}
//// SetCurrValue ////////////////////////////////////////////////////////////
void pfGUIKnobCtrl::SetCurrValue( hsScalar v )
{
int old = (int)fValue;
pfGUIValueCtrl::SetCurrValue( v );
// if( old == (int)fValue )
// return;
if( fAnimationKeys.GetCount() > 0 )
{
ICalcAnimTimes();
hsScalar tLength = fAnimEnd - fAnimBegin;
hsScalar newTime = fMin;
if (fMin != fMax) // Protect against div by zero
{
if( HasFlag( kReverseValues ) )
newTime = ( ( fMax - fValue ) / ( fMax - fMin ) ) * tLength + fAnimBegin;
else
newTime = ( ( fValue - fMin ) / ( fMax - fMin ) ) * tLength + fAnimBegin;
}
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
msg->SetCmd( plAnimCmdMsg::kGoToTime );
msg->SetAnimName( fAnimName );
msg->fTime = newTime;
msg->AddReceivers( fAnimationKeys );
plgDispatch::MsgSend( msg );
}
}
//// IGetDesiredCursor ///////////////////////////////////////////////////////
UInt32 pfGUIKnobCtrl::IGetDesiredCursor( void ) const
{
if( HasFlag( kLeftRightOrientation ) )
{
if( fDragging )
return plInputInterface::kCursorLeftRightDragging;
return plInputInterface::kCursorLeftRightDraggable;
}
else
{
if( fDragging )
return plInputInterface::kCursorUpDownDragging;
return plInputInterface::kCursorUpDownDraggable;
}
}

View File

@ -0,0 +1,116 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIKnobCtrl Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIKnobCtrl_h
#define _pfGUIKnobCtrl_h
#include "pfGUIValueCtrl.h"
class plMessage;
class plAGMasterMod;
class pfGUIKnobCtrl : public pfGUIValueCtrl
{
protected:
hsTArray<plKey> fAnimationKeys;
char *fAnimName;
hsPoint3 fDragStart;
hsScalar fDragValue;
hsBool fDragging;
hsPoint3 fAnimStartPos, fAnimEndPos; // Calculated at export time for kMapToScreenRange
hsScalar fDragRangeMin, fDragRangeMax;
// Computed once, once an anim is loaded that we can compute this with
hsScalar fAnimBegin, fAnimEnd;
hsBool fAnimTimesCalced;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual UInt32 IGetDesiredCursor( void ) const; // As specified in plInputInterface.h
hsBool ICalcAnimTimes( void );
public:
pfGUIKnobCtrl();
virtual ~pfGUIKnobCtrl();
CLASSNAME_REGISTER( pfGUIKnobCtrl );
GETINTERFACE_ANY( pfGUIKnobCtrl, pfGUIValueCtrl );
enum OurFlags
{
kReverseValues = kDerivedFlagsStart,
kLeftRightOrientation,
kMapToScreenRange,
kTriggerOnlyOnMouseUp,
kMapToAnimationRange
};
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual void UpdateBounds( hsMatrix44 *invXformMatrix = nil, hsBool force = false );
virtual void SetCurrValue( hsScalar v );
// Export only
void SetAnimationKeys( hsTArray<plKey> &keys, const char *name );
void SetScreenRange( const hsPoint3 &startPos, const hsPoint3 &endPos ) { fAnimStartPos = startPos; fAnimEndPos = endPos; }
};
#endif // _pfGUIKnobCtrl_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIListBoxMod Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIListBoxMod_h
#define _pfGUIListBoxMod_h
#include "pfGUIControlMod.h"
class plMessage;
class hsGMaterial;
class plTextGenerator;
class pfGUIListElement;
class pfScrollProc;
class pfGUIValueCtrl;
class pfGUIListBoxMod : public pfGUIControlMod
{
friend class pfScrollProc;
protected:
struct plSmallRect
{
Int16 fLeft, fTop, fRight, fBottom;
void Set( Int16 l, Int16 t, Int16 r, Int16 b );
hsBool Contains( Int16 x, Int16 y );
plSmallRect& operator=(const int zero) { fLeft = fTop = fRight = fBottom = 0; return *this; }
};
pfGUIValueCtrl *fScrollControl;
pfScrollProc *fScrollProc;
hsTArray<pfGUIListElement *> fElements;
Int32 fCurrClick, fScrollPos, fCurrHover;
UInt8 fModsAtDragTime;
Int32 fMinSel, fMaxSel;
hsBool fCheckScroll, fClicking;
Int32 fSingleSelElement;
hsBool fScrollRangeUpdateDeferred;
hsBool fLocked, fReadyToRoll;
hsTArray<plSmallRect> fElementBounds;
hsTArray<Int16> fWrapStartIdxs;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
void ICalcScrollRange( void );
void ICalcWrapStarts( void );
virtual void IUpdate( void );
virtual void IPostSetUpDynTextMap( void );
virtual UInt32 IGetDesiredCursor( void ) const;
Int32 IGetItemFromPoint( hsPoint3 &mousePt );
void IFindSelectionRange( Int32 *min, Int32 *max );
void ISelectRange( Int8 min, Int8 max, hsBool select );
public:
pfGUIListBoxMod();
virtual ~pfGUIListBoxMod();
CLASSNAME_REGISTER( pfGUIListBoxMod );
GETINTERFACE_ANY( pfGUIListBoxMod, pfGUIControlMod );
enum OurFlags
{
kSingleSelect = kDerivedFlagsStart,
kDragAndDropCapable,
kDisableSelection,
kDisableKeyActions,
kAllowMultipleElementsPerRow,
kScrollLeftToRight,
kAllowMousePassThrough,
kGrowLeavesAndProcessOxygen,
kHandsOffMultiSelect, // Do multiselect w/o needing ctrl or shift
kForbidNoSelection
};
// Extended event types
enum ExtendedEvents
{
kScrollPosChanged,
kItemAdded,
kItemRemoved,
kListCleared
};
enum
{
kRefScrollCtrl = kRefDerivedStart
};
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseHover( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDblClick( hsPoint3 &mousePt, UInt8 modifiers );
virtual hsBool HandleKeyPress( char key, UInt8 modifiers );
virtual hsBool HandleKeyEvent( pfGameGUIMgr::EventType event, plKeyDef key, UInt8 modifiers );
virtual hsBool FilterMousePosition( hsPoint3 &mousePt );
virtual void PurgeDynaTextMapImage();
// Returns selected element. Only valid for kSingleSelect list boxes
Int32 GetSelection( void ) { return fSingleSelElement; }
void SetSelection( Int32 item );
void RemoveSelection( Int32 item );
void AddSelection( Int32 item );
virtual void ScrollToBegin( void );
virtual void ScrollToEnd( void );
virtual void SetScrollPos( Int32 pos );
virtual Int32 GetScrollPos( void );
virtual Int32 GetScrollRange( void );
void Refresh( void ) { IUpdate(); }
virtual void SetColorScheme( pfGUIColorScheme *newScheme );
// Element manipulation
UInt16 AddElement( pfGUIListElement *el );
void RemoveElement( UInt16 index );
Int16 FindElement( pfGUIListElement *toCompareTo );
void ClearAllElements( void );
void LockList( void );
void UnlockList( void );
UInt16 GetNumElements( void );
pfGUIListElement *GetElement( UInt16 idx );
UInt16 AddString( const char *string );
UInt16 AddString( const wchar_t *string );
Int16 FindString( const char *toCompareTo );
Int16 FindString( const wchar_t *toCompareTo );
// Export only
void SetScrollCtrl( pfGUIValueCtrl *ctrl ) { fScrollControl = ctrl; }
void SetSingleSelect( hsBool yes ) { if( yes ) SetFlag( kSingleSelect ); else ClearFlag( kSingleSelect ); }
};
#endif // _pfGUIListBoxMod_h

View File

@ -0,0 +1,472 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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 );
}

View File

@ -0,0 +1,244 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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 Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIListElement_h
#define _pfGUIListElement_h
#include "pfGUIControlMod.h"
class plDynamicTextMap;
class pfGUISkin;
class pfGUIListElement
{
protected:
hsBool fSelected;
const UInt8 fType;
hsBool fCollapsed; // For tree view support
UInt8 fIndentLevel; // Ditto
pfGUIColorScheme *fColors;
pfGUISkin *fSkin;
public:
enum Types
{
kText,
kPicture,
kTreeRoot
};
pfGUIListElement( UInt8 type ) : fType( type ), fSelected( false ), fCollapsed( false ), fIndentLevel( 0 ) {}
virtual ~pfGUIListElement() {}
virtual void Read( hsStream *s, hsResMgr *mgr );
virtual void Write( hsStream *s, hsResMgr *mgr );
virtual hsBool Draw( plDynamicTextMap *textGen, UInt16 x, UInt16 y, UInt16 maxWidth, UInt16 maxHeight ) = 0;
virtual void GetSize( plDynamicTextMap *textGen, UInt16 *width, UInt16 *height ) = 0;
virtual int CompareTo( pfGUIListElement *rightSide ) = 0;
virtual void SetSelected( hsBool sel ) { fSelected = sel; }
virtual hsBool IsSelected( void ) { return fSelected; }
virtual hsBool CanBeDragged( void ) { return false; }
// Return true here if you need the list refreshed
virtual hsBool MouseClicked( UInt16 localX, UInt16 localY ) { return false; }
UInt8 GetType( void ) { return fType; }
void SetColorScheme( pfGUIColorScheme *scheme ) { fColors = scheme; }
void SetSkin( pfGUISkin *skin ) { fSkin = skin; }
hsBool IsCollapsed( void ) const { return fCollapsed; }
virtual void SetCollapsed( hsBool c ) { fCollapsed = c; }
UInt8 GetIndentLevel( void ) const { return fIndentLevel; }
void SetIndentLevel( UInt8 i ) { fIndentLevel = i; }
};
class pfGUIListText : public pfGUIListElement
{
public:
// these enums should at least agree with the plDynamicTextMap's version of the Justify types
enum JustifyTypes
{
kLeftJustify = 0,
kCenter,
kRightJustify
};
protected:
wchar_t *fText;
UInt8 fJustify; // This is not our JustifyTypes, but from plDynamicTextMap
public:
pfGUIListText();
pfGUIListText( const char *text );
pfGUIListText( const wchar_t *text );
virtual ~pfGUIListText();
virtual void Read( hsStream *s, hsResMgr *mgr );
virtual void Write( hsStream *s, hsResMgr *mgr );
virtual hsBool Draw( plDynamicTextMap *textGen, UInt16 x, UInt16 y, UInt16 maxWidth, UInt16 maxHeight );
virtual void GetSize( plDynamicTextMap *textGen, UInt16 *width, UInt16 *height );
virtual int CompareTo( pfGUIListElement *rightSide );
virtual hsBool CanBeDragged( void ) { return true; }
virtual void SetJustify( JustifyTypes justify );
// These two are virtual so we can derive and override them
virtual const wchar_t *GetText( void ) { return fText; }
virtual void SetText( const char *text );
virtual void SetText( const wchar_t *text );
};
class pfGUIListPicture : public pfGUIListElement
{
protected:
plKey fMipmapKey;
UInt8 fBorderSize; // Defaults to 2
hsBool fRespectAlpha;
public:
pfGUIListPicture();
pfGUIListPicture( plKey mipKey, hsBool respectAlpha );
virtual ~pfGUIListPicture();
virtual void Read( hsStream *s, hsResMgr *mgr );
virtual void Write( hsStream *s, hsResMgr *mgr );
virtual hsBool Draw( plDynamicTextMap *textGen, UInt16 x, UInt16 y, UInt16 maxWidth, UInt16 maxHeight );
virtual void GetSize( plDynamicTextMap *textGen, UInt16 *width, UInt16 *height );
virtual int CompareTo( pfGUIListElement *rightSide );
virtual hsBool CanBeDragged( void ) { return false; }
void SetBorderSize( UInt32 size ) { fBorderSize = (UInt8)size; }
void SetRespectAlpha( hsBool r ) { fRespectAlpha = r; }
};
class pfGUIListTreeRoot : public pfGUIListElement
{
protected:
wchar_t *fText;
hsBool fShowChildren;
hsTArray<pfGUIListElement *> fChildren;
public:
pfGUIListTreeRoot();
pfGUIListTreeRoot( const char *text );
pfGUIListTreeRoot( const wchar_t *text );
virtual ~pfGUIListTreeRoot();
virtual void Read( hsStream *s, hsResMgr *mgr );
virtual void Write( hsStream *s, hsResMgr *mgr );
virtual hsBool Draw( plDynamicTextMap *textGen, UInt16 x, UInt16 y, UInt16 maxWidth, UInt16 maxHeight );
virtual void GetSize( plDynamicTextMap *textGen, UInt16 *width, UInt16 *height );
virtual int CompareTo( pfGUIListElement *rightSide );
virtual hsBool MouseClicked( UInt16 localX, UInt16 localY );
const wchar_t *GetTitle( void ) { return fText; }
void SetTitle( const char *text );
void SetTitle( const wchar_t *text );
UInt32 GetNumChildren( void ) const { return fChildren.GetCount(); }
pfGUIListElement *GetChild( UInt32 i ) const { return fChildren[ i ]; }
void AddChild( pfGUIListElement *el );
void RemoveChild( UInt32 idx );
virtual void SetCollapsed( hsBool c );
void ShowChildren( hsBool s );
hsBool IsShowingChildren( void ) const { return fShowChildren; }
};
//// pfGUIDropTargetProc /////////////////////////////////////////////////////
// A little proc object you create if you want a control to be a potential
// target for drag & drop operations. It has two functions: one takes a
// listElement and returns whether it can accept that type, and the other
// actually gets called when a listElement is "dropped" onto the associated
// control. Any control can be a dropTarget; just attach the right proc
// to it!
// If you are dragging multiple elements, both CanEat() and Eat() will get
// called for each element that is being dragged.
class pfGUIDropTargetProc
{
protected:
UInt32 fRefCnt;
public:
pfGUIDropTargetProc() { fRefCnt = 0; }
virtual hsBool CanEat( pfGUIListElement *element, pfGUIControlMod *source ) = 0;
virtual void Eat( pfGUIListElement *element, pfGUIControlMod *source, pfGUIControlMod *parent ) = 0;
// ONLY THE GUI SYSTEM SHOULD CALL THESE
void IncRef( void ) { fRefCnt++; }
hsBool DecRef( void ) { fRefCnt--; return ( fRefCnt > 0 ) ? false : true; }
};
#endif // _pfGUIListElement_h

View File

@ -0,0 +1,479 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIMenuItem Definition //
// //
// The type of button that knows how to party. //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIMenuItem.h"
#include "pfGameGUIMgr.h"
#include "pfGUIControlHandlers.h"
#include "pfGUIDialogMod.h"
#include "pfGUIPopUpMenu.h"
#include "../plInputCore/plInputInterface.h"
#include "../pnMessage/plRefMsg.h"
#include "../plGImage/plDynamicTextMap.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIMenuItem::pfGUIMenuItem()
{
fName = nil;
fSkin = nil;
fReportingHover = false;
fSkinBuffersUpdated = true;
}
pfGUIMenuItem::~pfGUIMenuItem()
{
SetSkin( nil, kTop );
delete [] fName;
}
void pfGUIMenuItem::SetName( const char *name )
{
wchar_t *wName = hsStringToWString(name);
SetName(wName);
delete [] wName;
}
void pfGUIMenuItem::SetName( const wchar_t *name )
{
delete [] fName;
if (name != nil)
{
fName = TRACKED_NEW wchar_t[wcslen(name)+1];
wcscpy(fName,name);
}
else
fName = nil;
IUpdate();
}
//// SetSkin /////////////////////////////////////////////////////////////////
void pfGUIMenuItem::SetSkin( pfGUISkin *skin, HowToSkin s )
{
// Just a function wrapper for SendRef
if( fSkin != nil )
GetKey()->Release( fSkin->GetKey() );
if( skin != nil )
hsgResMgr::ResMgr()->SendRef( skin->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefSkin ), plRefFlags::kActiveRef );
fHowToSkin = s;
fSkinBuffersUpdated = false;
}
//// IPostSetUpDynTextMap ////////////////////////////////////////////////////
// Draw our initial image on the dynTextMap
void pfGUIMenuItem::IPostSetUpDynTextMap( void )
{
}
//// IGetDesiredExtraDTMRoom /////////////////////////////////////////////////
// Overridden so we can enlarge our DTMap by 3 vertically, to use the extra
// space as basically a double buffer for our skinning
void pfGUIMenuItem::IGrowDTMDimsToDesiredSize( UInt16 &width, UInt16 &height )
{
height *= 3;
}
//// IUpdateSkinBuffers //////////////////////////////////////////////////////
// Redraws the double buffers for the two skin images we keep hidden in the
// DTMap, so we don't have to re-composite them every time we draw the
// control.
void pfGUIMenuItem::IUpdateSkinBuffers( void )
{
if( fSkinBuffersUpdated )
return;
if( fSkin == nil )
return;
if( fDynTextMap == nil )
return;
if( fSkin->GetTexture() == nil )
return;
UInt16 y = fDynTextMap->GetVisibleHeight();
IUpdateSingleSkinBuffer( y, false );
IUpdateSingleSkinBuffer( y << 1, true );
fSkinBuffersUpdated = true;
}
//// IUpdateSingleSkinBuffer /////////////////////////////////////////////////
// Broken down functionality for the above function
void pfGUIMenuItem::IUpdateSingleSkinBuffer( UInt16 y, hsBool sel )
{
hsAssert( fSkin != nil && fDynTextMap != nil, "Invalid pointers in IUpdateSingleSkinBuffer()" );
// Note: add 1 to the visible height so we get enough overlap to take care of mipmapping issues
UInt16 x = 0, totWidth = fDynTextMap->GetVisibleWidth();
UInt16 totHeight = y + fDynTextMap->GetVisibleHeight();
pfGUISkin::pfSRect element;
totWidth -= fSkin->GetElement( pfGUISkin::kRightSpan ).fWidth;
if( fHowToSkin == kTop )
{
// Draw up-left corner
element = fSkin->GetElement( pfGUISkin::kUpLeftCorner );
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, element.fWidth, element.fHeight, plDynamicTextMap::kImgSprite );
x += element.fWidth;
element = fSkin->GetElement( pfGUISkin::kTopSpan );
for( ; x < totWidth; )
{
UInt16 wid = element.fWidth;
if( x + wid > totWidth )
wid = totWidth - x;
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, wid, element.fHeight, plDynamicTextMap::kImgSprite );
x += wid;
}
element = fSkin->GetElement( pfGUISkin::kUpRightCorner );
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, element.fWidth, element.fHeight, plDynamicTextMap::kImgSprite );
y += element.fHeight;
}
else if( fHowToSkin == kBottom )
{
// Clip some space for now
totHeight -= fSkin->GetElement( pfGUISkin::kLowerLeftCorner ).fHeight;
}
// Group drawing by skin elements for caching performance
UInt16 startY = y;
x = 0;
element = fSkin->GetElement( pfGUISkin::kLeftSpan );
for( ; y < totHeight; )
{
UInt16 ht = element.fHeight;
if( y + ht > totHeight )
ht = totHeight - y;
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, element.fWidth, ht, plDynamicTextMap::kImgSprite );
y += ht;
}
x += element.fWidth;
if( sel )
element = fSkin->GetElement( pfGUISkin::kSelectedFill );
else
element = fSkin->GetElement( pfGUISkin::kMiddleFill );
for( ; x < totWidth; )
{
UInt16 wid = element.fWidth;
if( x + wid > totWidth )
wid = totWidth - x;
for( y = startY; y < totHeight; )
{
UInt16 ht = element.fHeight;
if( y + ht > totHeight )
ht = totHeight - y;
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, wid, ht, plDynamicTextMap::kImgSprite );
y += ht;
}
x += wid;
}
element = fSkin->GetElement( pfGUISkin::kRightSpan );
for( y = startY; y < totHeight; )
{
UInt16 ht = element.fHeight;
if( y + ht > totHeight )
ht = totHeight - y;
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, element.fWidth, ht, plDynamicTextMap::kImgSprite );
y += ht;
}
if( fHowToSkin == kBottom )
{
x = 0;
// Draw lower-left corner
element = fSkin->GetElement( pfGUISkin::kLowerLeftCorner );
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, element.fWidth, element.fHeight, plDynamicTextMap::kImgSprite );
x += element.fWidth;
element = fSkin->GetElement( pfGUISkin::kBottomSpan );
for( ; x < totWidth; )
{
UInt16 wid = element.fWidth;
if( x + wid > totWidth )
wid = totWidth - x;
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, wid, element.fHeight, plDynamicTextMap::kImgSprite );
x += wid;
}
element = fSkin->GetElement( pfGUISkin::kLowerRightCorner );
fDynTextMap->DrawClippedImage( x, y, fSkin->GetTexture(), element.fX, element.fY, element.fWidth, element.fHeight, plDynamicTextMap::kImgSprite );
y += element.fHeight;
}
}
//// IUpdate /////////////////////////////////////////////////////////////////
void pfGUIMenuItem::IUpdate( void )
{
if( fDynTextMap == nil )
return;
if( fSkin != nil )
{
IUpdateSkinBuffers();
if( !fSkinBuffersUpdated )
return;
// Copy now from our skin buffer, plus set our text color
UInt16 y = fDynTextMap->GetVisibleHeight();
if( IsInteresting() )
{
fDynTextMap->DrawClippedImage( 0, 0, fDynTextMap, 0, y << 1, fDynTextMap->GetVisibleWidth(), y, plDynamicTextMap::kImgSprite );
fDynTextMap->SetTextColor( GetColorScheme()->fSelForeColor );
}
else
{
fDynTextMap->DrawClippedImage( 0, 0, fDynTextMap, 0, y, fDynTextMap->GetVisibleWidth(), y, plDynamicTextMap::kImgSprite );
fDynTextMap->SetTextColor( GetColorScheme()->fForeColor );
}
}
else
{
if( IsInteresting() )
{
fDynTextMap->ClearToColor( GetColorScheme()->fSelBackColor );
fDynTextMap->SetTextColor( GetColorScheme()->fSelForeColor );
}
else
{
fDynTextMap->ClearToColor( GetColorScheme()->fBackColor );
fDynTextMap->SetTextColor( GetColorScheme()->fForeColor );
}
}
fDynTextMap->SetJustify( plDynamicTextMap::kLeftJustify );
if( fName != nil )
{
UInt16 ht;
fDynTextMap->CalcStringWidth( fName, &ht );
Int16 x = 0, y = ( fDynTextMap->GetVisibleHeight() - ht ) >> 1;
if( fHowToSkin == kTop && fSkin != nil )
y += fSkin->GetElement( pfGUISkin::kTopSpan ).fHeight >> 1;
else if( fHowToSkin == kBottom && fSkin != nil )
y -= fSkin->GetElement( pfGUISkin::kTopSpan ).fHeight >> 1;
if( fSkin != nil )
x += fSkin->GetBorderMargin();
if( fClicking )
{
x += 2;
y += 2;
}
fDynTextMap->DrawClippedString( x, y, fName, fDynTextMap->GetVisibleWidth(), fDynTextMap->GetVisibleHeight() );
if( HasFlag( kDrawSubMenuArrow ) )
{
if( fSkin != nil )
{
pfGUISkin::pfSRect element;
if( IsInteresting() )
element = fSkin->GetElement( pfGUISkin::kSelectedSubMenuArrow );
else
element = fSkin->GetElement( pfGUISkin::kSubMenuArrow );
y += ( ht >> 1 ) - ( element.fHeight >> 1 );
if( y < 0 || y + element.fHeight >= fDynTextMap->GetHeight() )
y = 0;
fDynTextMap->DrawClippedImage( x + fDynTextMap->GetVisibleWidth() - 2 - element.fWidth
- fSkin->GetElement( pfGUISkin::kRightSpan ).fWidth,
y,
fSkin->GetTexture(), element.fX, element.fY, element.fWidth, element.fHeight, plDynamicTextMap::kImgBlend );
}
else
{
fDynTextMap->SetJustify( plDynamicTextMap::kRightJustify );
fDynTextMap->DrawString( x + fDynTextMap->GetVisibleWidth() - 2, y, ">>" );
}
}
}
fDynTextMap->FlushToHost();
}
void pfGUIMenuItem::PurgeDynaTextMapImage()
{
if ( fDynTextMap != nil )
fDynTextMap->PurgeImage();
}
//// GetTextExtents //////////////////////////////////////////////////////////
// Calculate the size of the drawn text.
void pfGUIMenuItem::GetTextExtents( UInt16 &width, UInt16 &height )
{
if( fName == nil )
width = height = 0;
else
width = fDynTextMap->CalcStringWidth( fName, &height );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIMenuItem::MsgReceive( plMessage *msg )
{
return pfGUIButtonMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIMenuItem::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIButtonMod::Read( s, mgr );
}
void pfGUIMenuItem::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIButtonMod::Write( s, mgr );
}
//// HandleMouseDown/Up //////////////////////////////////////////////////////
void pfGUIMenuItem::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
pfGUIButtonMod::HandleMouseDown( mousePt, modifiers );
IUpdate();
}
void pfGUIMenuItem::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
pfGUIButtonMod::HandleMouseUp( mousePt, modifiers );
IUpdate();
}
void pfGUIMenuItem::HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers )
{
/* if( !fClicking )
return;
if( fDraggable == nil )
return;
if( !fDraggable->IsVisible() )
{
// Are we outside ourselves?
if( !PointInBounds( mousePt ) )
{
// Yes, start dragging
StartDragging();
// Hand off our interest to the draggable
fDialog->SetControlOfInterest( fDraggable );
}
}
*/
pfGUIButtonMod::HandleMouseDrag( mousePt, modifiers );
}
void pfGUIMenuItem::HandleMouseHover( hsPoint3 &mousePt, UInt8 modifiers )
{
pfGUIButtonMod::HandleMouseHover( mousePt, modifiers );
if( HasFlag( kReportHovers ) )
{
if( PointInBounds( mousePt ) )
{
if( !fReportingHover && ( fDialog->GetControlOfInterest() == nil ||
fDialog->GetControlOfInterest() == this ) )
{
fReportingHover = true;
HandleExtendedEvent( kMouseHover );
fDialog->SetControlOfInterest( this );
}
}
else if( fReportingHover )
{
fReportingHover = false;
HandleExtendedEvent( kMouseExit );
fDialog->SetControlOfInterest( nil );
}
}
}
//// SetInteresting //////////////////////////////////////////////////////////
// Overridden to play mouse over animation when we're interesting
void pfGUIMenuItem::SetInteresting( hsBool i )
{
pfGUIButtonMod::SetInteresting( i );
IUpdate();
// Make sure we're not still thinking we're reporting hovers when we're not
if( !i )
fReportingHover = false;
}

View File

@ -0,0 +1,128 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIMenuItem Header //
// //
// The type of button that knows how to party. //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIMenuItem_h
#define _pfGUIMenuItem_h
#include "pfGUIButtonMod.h"
class plMessage;
class pfGUISkin;
class pfGUIMenuItem : public pfGUIButtonMod
{
public:
enum HowToSkin
{
kTop,
kMiddle,
kBottom
};
protected:
wchar_t *fName;
hsBool fReportingHover;
HowToSkin fHowToSkin;
hsBool fSkinBuffersUpdated;
virtual void IGrowDTMDimsToDesiredSize( UInt16 &width, UInt16 &height );
virtual void IPostSetUpDynTextMap( void );
virtual void IUpdate( void );
void IUpdateSkinBuffers( void );
void IUpdateSingleSkinBuffer( UInt16 y, hsBool sel );
public:
pfGUIMenuItem();
virtual ~pfGUIMenuItem();
CLASSNAME_REGISTER( pfGUIMenuItem );
GETINTERFACE_ANY( pfGUIMenuItem, pfGUIButtonMod );
enum ItemFlags
{
kDrawSubMenuArrow = kDerivedFlagsStart,
kReportHovers
};
// Extended event types
enum ExtendedEvents
{
kMouseHover,
kMouseExit
};
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void SetInteresting( hsBool i );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseHover( hsPoint3 &mousePt, UInt8 modifiers );
virtual void PurgeDynaTextMapImage();
void SetName( const char *name );
void SetName( const wchar_t *name );
const wchar_t *GetName( void ) const { return fName; }
void GetTextExtents( UInt16 &width, UInt16 &height );
void SetSkin( pfGUISkin *skin, HowToSkin s );
};
#endif // _pfGUIMenuItem_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,292 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIMultiLineEditCtrl Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIMultiLineEditCtrl_h
#define _pfGUIMultiLineEditCtrl_h
#include "pfGUIControlMod.h"
#include "hsTemplates.h"
#include "../plInputCore/plInputDevice.h"
class plMessage;
class hsGMaterial;
class plTextGenerator;
class pfMLScrollProc;
class pfGUIValueCtrl;
struct plUndoAction;
class pfGUIMultiLineEditProc
{
public:
pfGUIMultiLineEditProc() {}
virtual ~pfGUIMultiLineEditProc() {}
// we've hit the end of the control list (by moving the cursor)
virtual void OnEndOfControlList(Int32 cursorPos) {}
// we've hit the beginning of the control ist (by moving the cursor)
virtual void OnBeginningOfControlList(Int32 cursorPos) {}
};
class pfGUIMultiLineEditCtrl : public pfGUIControlMod
{
public:
enum Direction
{
kLineStart = 1,
kLineEnd,
kBufferStart,
kBufferEnd,
kOneBack,
kOneForward,
kOneWordBack,
kOneWordForward,
kOneLineUp,
kOneLineDown,
kPageUp,
kPageDown
};
protected:
mutable hsTArray<wchar_t> fBuffer; // Because AcquireArray() isn't const
hsTArray<Int32> fLineStarts;
UInt16 fLineHeight, fCurrCursorX, fCurrCursorY;
Int32 fCursorPos, fLastCursorLine;
hsBool fIgnoreNextKey, fReadyToRender;
hsBounds3Ext fLastP2PArea;
Int8 fLockCount;
UInt8 fCalcedFontSize; // The font size that we calced our line height at
UInt8 fLastKeyModifiers;
wchar_t fLastKeyPressed;
static wchar_t fColorCodeChar, fStyleCodeChar;
static UInt32 fColorCodeSize, fStyleCodeSize;
wchar_t fLastDeadKey; // if the previous key was a dead key, its value goes here
wchar_t fDeadKeyConverter[256][256]; // first index is the dead key, second index is the char to combine it with
void SetupDeadKeyConverter();
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual void IPostSetUpDynTextMap( void );
virtual void IUpdate( void );
void IUpdate( Int32 startLine, Int32 endLine );
friend class pfMLScrollProc;
pfGUIValueCtrl *fScrollControl;
pfMLScrollProc *fScrollProc;
Int32 fScrollPos;
Int32 fBufferLimit;
pfGUIMultiLineEditCtrl *fNextCtrl; // used for linking multiple controls together to share a buffer
pfGUIMultiLineEditCtrl *fPrevCtrl;
pfGUIMultiLineEditProc *fEventProc; // where we send events to
std::string fFontFace;
hsColorRGBA fFontColor;
UInt8 fFontSize;
UInt8 fFontStyle;
enum flagsSet
{
kFontFaceSet = 1,
kFontColorSet = 2,
kFontSizeSet = 4,
kFontStyleSet = 8
};
UInt8 fFontFlagsSet;
int fTopMargin,fLeftMargin,fBottomMargin,fRightMargin;
void IMoveCursor( Direction dir );
void IMoveCursorTo( Int32 position ); // Updates selection
void ISetCursor( Int32 newPosition ); // Doesn't update selection
Int32 IRecalcLineStarts( Int32 startingLine, hsBool force, hsBool dontUpdate = false );
void IRecalcFromCursor( hsBool forceUpdate = false );
Int32 IFindCursorLine( Int32 cursorPos = -1 ) const;
hsBool IStoreLineStart( UInt32 line, Int32 start );
void IOffsetLineStarts( UInt32 position, Int32 offset, hsBool offsetSelectionEnd = false );
Int32 IPointToPosition( Int16 x, Int16 y, hsBool searchOutsideBounds = false );
Int32 ICalcNumVisibleLines( void ) const;
void IReadColorCode( Int32 &pos, hsColorRGBA &color ) const;
void IReadStyleCode( Int32 &pos, UInt8 &fontStyle ) const;
UInt32 IRenderLine( UInt16 x, UInt16 y, Int32 start, Int32 end, hsBool dontRender = false );
hsBool IFindLastColorCode( Int32 pos, hsColorRGBA &color, hsBool ignoreFirstCharacter = false ) const;
hsBool IFindLastStyleCode( Int32 pos, UInt8 &style, hsBool ignoreFirstCharacter = false ) const;
inline static bool IIsCodeChar( const wchar_t c );
inline static bool IIsRenderable( const wchar_t c );
inline static Int32 IOffsetToNextChar( wchar_t stringChar );
inline Int32 IOffsetToNextCharFromPos( Int32 pos ) const;
void IActuallyInsertColor( Int32 pos, hsColorRGBA &color );
void IActuallyInsertStyle( Int32 pos, UInt8 style );
void IUpdateScrollRange( void );
wchar_t *ICopyRange( Int32 start, Int32 end ) const;
Int32 ICharPosToBufferPos( Int32 charPos ) const;
void IUpdateBuffer();
void IUpdateLineStarts();
void ISetGlobalBuffer();
void ISetLineStarts(hsTArray<Int32> lineStarts);
void IHitEndOfControlList(Int32 cursorPos);
void IHitBeginningOfControlList(Int32 cursorPos);
public:
enum
{
kRefScrollCtrl = kRefDerivedStart
};
pfGUIMultiLineEditCtrl();
virtual ~pfGUIMultiLineEditCtrl();
CLASSNAME_REGISTER( pfGUIMultiLineEditCtrl );
GETINTERFACE_ANY( pfGUIMultiLineEditCtrl, pfGUIControlMod );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual hsBool HandleKeyPress( char key, UInt8 modifiers );
virtual hsBool HandleKeyEvent( pfGameGUIMgr::EventType event, plKeyDef key, UInt8 modifiers );
virtual void PurgeDynaTextMapImage();
virtual void UpdateColorScheme() { fFontFlagsSet = 0; pfGUIControlMod::UpdateColorScheme(); }
// Extended event types
enum ExtendedEvents
{
kValueChanging,
kScrollPosChanged,
kKeyPressedEvent
};
void SetScrollPosition( Int32 topLine );
Int32 GetScrollPosition();
void MoveCursor( Direction dir );
void InsertChar( char c );
void InsertChar( wchar_t c);
void InsertString( const char *string );
void InsertString( const wchar_t *string );
void InsertColor( hsColorRGBA &color );
void InsertStyle( UInt8 fontStyle );
void DeleteChar( void );
void ClearBuffer( void );
void SetBuffer( const char *asciiText );
void SetBuffer( const wchar_t *asciiText );
void SetBuffer( const UInt8 *codedText, UInt32 length );
void SetBuffer( const UInt16 *codedText, UInt32 length );
char *GetNonCodedBuffer( void ) const;
wchar_t *GetNonCodedBufferW( void ) const;
UInt8 *GetCodedBuffer( UInt32 &length ) const;
UInt16 *GetCodedBufferW( UInt32 &length ) const;
UInt32 GetBufferSize();
void SetBufferLimit(Int32 limit) { fBufferLimit = limit; }
Int32 GetBufferLimit() { return fBufferLimit; }
void GetThisKeyPressed( char &key, UInt8 &modifiers ) const { key = (char)fLastKeyPressed; modifiers = fLastKeyModifiers; }
void Lock( void );
void Unlock( void );
hsBool IsLocked( void ) const { return ( fLockCount > 0 ) ? true : false; }
void SetScrollEnable( hsBool state );
void ForceUpdate() {/*IRecalcLineStarts(0,true);*/IUpdateLineStarts(); IUpdate();}
void SetNext( pfGUIMultiLineEditCtrl *newNext );
void ClearNext();
void SetPrev( pfGUIMultiLineEditCtrl *newPrev );
void ClearPrev();
void SetEventProc( pfGUIMultiLineEditProc *eventProc );
void ClearEventProc();
Int32 GetFirstVisibleLine();
Int32 GetLastVisibleLine();
Int32 GetNumVisibleLines() {return ICalcNumVisibleLines();}
void SetGlobalStartLine(Int32 line);
void SetCursorToLoc(Int32 loc) {ISetCursor(loc);}
void SetMargins(int top, int left, int bottom, int right);
UInt8 GetFontSize() {return fFontSize;} // because we're too cool to use the color scheme crap
void SetFontFace(std::string fontFace);
void SetFontColor(hsColorRGBA fontColor) {fFontColor = fontColor; fFontFlagsSet |= kFontColorSet;}
void SetFontSize(UInt8 fontSize);
void SetFontStyle(UInt8 fontStyle) {fFontStyle = fontStyle; fFontFlagsSet |= kFontStyleSet;}
hsBool ShowingBeginningOfBuffer();
hsBool ShowingEndOfBuffer();
void DeleteLinesFromTop(int numLines); // cursor and scroll position might be off after this call, not valid on connected controls
};
#endif // _pfGUIMultiLineEditCtrl_h

View File

@ -0,0 +1,956 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIPopUpMenu Header //
// //
// Pop-up menus are really just dialogs that know how to create themselves //
// and create buttons on themselves to simulate a menu (after all, that's //
// all a menu really is anyway). //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGameGUIMgr.h"
#include "pfGUIPopUpMenu.h"
#include "pfGUIMenuItem.h"
#include "pfGUIButtonMod.h"
#include "pfGUIDialogHandlers.h"
#include "pfGUIDialogNotifyProc.h"
#include "pfGUIControlHandlers.h"
#include "pfGUICtrlGenerator.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
#include "../plSurface/hsGMaterial.h"
#include "../plSurface/plLayer.h"
#include "../plGImage/plDynamicTextMap.h"
#include "../plMessage/plLayRefMsg.h"
#include "../pnSceneObject/plSceneObject.h"
#include "../pnSceneObject/plDrawInterface.h"
#include "../pnSceneObject/plCoordinateInterface.h"
#include "../pnMessage/plIntRefMsg.h"
#include "../pnMessage/plObjRefMsg.h"
#include "../pnMessage/plNodeRefMsg.h"
#include "../plScene/plPostEffectMod.h"
#include "../plScene/plSceneNode.h"
#include "../pnMessage/plClientMsg.h"
#include "plViewTransform.h"
#include "../plPipeline/plDebugText.h"
class pfPopUpKeyGenerator
{
public:
char fPrefix[ 128 ];
UInt32 fKeyCount;
plLocation fLoc;
pfPopUpKeyGenerator( const char *p, const plLocation &loc )
{
strcpy( fPrefix, p );
fLoc = loc;
}
plKey CreateKey( hsKeyedObject *ko )
{
char name[ 256 ];
sprintf( name, "%s-%d", fPrefix, fKeyCount++ );
return hsgResMgr::ResMgr()->NewKey( name, ko, fLoc );
}
};
//// Router Proc So The Parent Can Handle Click Events ///////////////////////
class pfGUIMenuItemProc : public pfGUICtrlProcObject
{
protected:
pfGUIPopUpMenu *fParent;
UInt32 fIndex;
public:
pfGUIMenuItemProc( pfGUIPopUpMenu *parent, UInt32 idx )
{
fParent = parent;
fIndex = idx;
}
virtual void DoSomething( pfGUIControlMod *ctrl )
{
fParent->IHandleMenuSomething( fIndex, ctrl );
}
virtual void HandleExtendedEvent( pfGUIControlMod *ctrl, UInt32 event )
{
fParent->IHandleMenuSomething( fIndex, ctrl, (Int32)event );
}
};
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIPopUpMenu::pfGUIPopUpMenu()
{
fNeedsRebuilding = false;
fParent = nil;
fKeyGen = nil;
fSubMenuOpen = -1;
SetFlag( kModalOutsideMenus );
fMargin = 4;
fSkin = nil;
fWaitingForSkin = false;
fParentNode = nil;
fOriginX = fOriginY = 0.f;
fOriginAnchor = nil;
fOriginContext = nil;
fAlignment = kAlignDownRight;
}
pfGUIPopUpMenu::~pfGUIPopUpMenu()
{
SetSkin( nil );
// if( fParentNode != nil )
// fParentNode->GetKey()->UnRefObject();
ITearDownMenu();
ClearItems();
delete fKeyGen;
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIPopUpMenu::MsgReceive( plMessage *msg )
{
plGenRefMsg *ref = plGenRefMsg::ConvertNoRef( msg );
if( ref != nil )
{
if( ref->fType == kRefSkin )
{
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
{
fSkin = pfGUISkin::ConvertNoRef( ref->GetRef() );
fWaitingForSkin = false;
}
else
fSkin = nil;
fNeedsRebuilding = true;
if( IsVisible() )
{
// Rebuild NOW
ITearDownMenu();
IBuildMenu();
}
return true;
}
else if( ref->fType == kRefSubMenu )
{
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
fMenuItems[ ref->fWhich ].fSubMenu = pfGUIPopUpMenu::ConvertNoRef( ref->GetRef() );
else
fMenuItems[ ref->fWhich ].fSubMenu = nil;
return true;
}
else if( ref->fType == kRefOriginAnchor )
{
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
fOriginAnchor = plSceneObject::ConvertNoRef( ref->GetRef() );
else
fOriginAnchor = nil;
return true;
}
else if( ref->fType == kRefOriginContext )
{
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
fOriginContext = pfGUIDialogMod::ConvertNoRef( ref->GetRef() );
else
fOriginContext = nil;
return true;
}
else if( ref->fType == kRefParentNode )
{
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
fParentNode = plSceneNode::ConvertNoRef( ref->GetRef() );
else
fParentNode = nil;
return true;
}
}
return pfGUIDialogMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIPopUpMenu::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIDialogMod::Read( s, mgr );
// In case we need it...
fKeyGen = TRACKED_NEW pfPopUpKeyGenerator( GetName(), GetKey()->GetUoid().GetLocation() );
fOriginX = fOriginY = -1.f;
fMargin = s->ReadSwap16();
UInt32 i, count = s->ReadSwap32();
fMenuItems.SetCountAndZero( count );
for( i = 0; i < count; i++ )
{
char readTemp[ 256 ];
s->Read( sizeof( readTemp ), readTemp );
wchar_t *wReadTemp = hsStringToWString( readTemp );
fMenuItems[ i ].fName = wReadTemp;
delete [] wReadTemp;
fMenuItems[ i ].fHandler = pfGUICtrlProcWriteableObject::Read( s );
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, i, kRefSubMenu ), plRefFlags::kActiveRef );
}
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefSkin ), plRefFlags::kActiveRef );
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefOriginAnchor ), plRefFlags::kPassiveRef );
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefOriginContext ), plRefFlags::kPassiveRef );
fAlignment = (Alignment)s->ReadByte();
fNeedsRebuilding = true;
}
void pfGUIPopUpMenu::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIDialogMod::Write( s, mgr );
s->WriteSwap16( fMargin );
s->WriteSwap32( fMenuItems.GetCount() );
UInt32 i;
for( i = 0; i < fMenuItems.GetCount(); i++ )
{
char writeTemp[ 256 ];
char *sName = hsWStringToString( fMenuItems[ i ].fName.c_str() );
strncpy( writeTemp, sName, sizeof( writeTemp ) );
delete [] sName;
s->Write( sizeof( writeTemp ), writeTemp );
// Write the handler out (if it's not a writeable, damn you)
pfGUICtrlProcWriteableObject::Write( (pfGUICtrlProcWriteableObject *)fMenuItems[ i ].fHandler, s );
mgr->WriteKey( s, fMenuItems[ i ].fSubMenu );
}
// Note: we force parentNode to nil here because we only use it when we dynamically
// create nodes at runtime and need to unref and destroy them later. Since we're
// reading from disk, we'll already have a sceneNode somewhere, so we don't need
// this.
fParentNode = nil;
mgr->WriteKey( s, fSkin );
mgr->WriteKey( s, fOriginAnchor );
mgr->WriteKey( s, fOriginContext );
s->WriteByte( (UInt8)fAlignment );
}
void pfGUIPopUpMenu::SetOriginAnchor( plSceneObject *anchor, pfGUIDialogMod *context )
{
fOriginAnchor = anchor;
fOriginContext = context;
hsgResMgr::ResMgr()->AddViaNotify( fOriginAnchor->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefOriginAnchor ), plRefFlags::kPassiveRef );
hsgResMgr::ResMgr()->AddViaNotify( fOriginContext->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefOriginContext ), plRefFlags::kPassiveRef );
}
//// SetEnabled //////////////////////////////////////////////////////////////
void pfGUIPopUpMenu::SetEnabled( hsBool e )
{
if( e && fNeedsRebuilding )
{
// Make sure our menu is rebuilt before enabling
ITearDownMenu();
IBuildMenu();
}
else if( !e )
{
if( fParent != nil )
pfGUIPopUpMenu::ConvertNoRef( fParent )->fSubMenuOpen = -1;
// Hide our submenus if we have any open
if( fSubMenuOpen != -1 )
{
fMenuItems[ fSubMenuOpen ].fSubMenu->Hide();
fSubMenuOpen = -1;
}
}
pfGUIDialogMod::SetEnabled( e );
}
void pfGUIPopUpMenu::Show( hsScalar x, hsScalar y )
{
fOriginX = x;
fOriginY = y;
pfGUIDialogMod::Show(); // C++ is kinda stupid if it can't find this naturally
ISeekToOrigin();
}
void pfGUIPopUpMenu::ISeekToOrigin( void )
{
#if 0
UInt32 i;
float x = 0.5f/*fOriginX*/, y = fOriginY;
for( i = 0; i < fControls.GetCount(); i++ )
{
if( fControls[ i ] != nil )
{
fControls[ i ]->SetObjectCenter( x, y );
// const hsBounds3 &bnds = fControls[ i ]->GetBounds();
y += fMenuItems[ i ].fYOffsetToNext;//bnds.GetMaxs().fY - bnds.GetMins().fY;
/* hsMatrix44 p2l, l2p = GetTarget()->GetLocalToWorld();
hsPoint3 center, origin;
ScreenToWorldPoint( fOriginX, fOriginY, 100.f, center );
ScreenToWorldPoint( 0.f, 0.f, 100.f, origin );
center = origin - center;
center.fZ = 0.f;
l2p.SetTranslate( &center );
l2p.GetInverse( &p2l );
GetTarget()->SetTransform( l2p, p2l );
*/ }
}
#endif
}
//// IHandleMenuSomething ////////////////////////////////////////////////////
// Handles a normal event from one of the item controls.
void pfGUIPopUpMenu::IHandleMenuSomething( UInt32 idx, pfGUIControlMod *ctrl, Int32 extended )
{
if( extended != -1 )
{
if( fSubMenuOpen != -1 && fSubMenuOpen != idx )
{
// Better close the submenu(s)
fMenuItems[ fSubMenuOpen ].fSubMenu->Hide();
fSubMenuOpen = -1;
}
if( extended == pfGUIMenuItem::kMouseHover && fMenuItems[ idx ].fSubMenu != nil )
{
// Open new submenu
const hsBounds3 &bnds = ctrl->GetBounds();
fMenuItems[ idx ].fSubMenu->Show( bnds.GetMaxs().fX, bnds.GetMins().fY );
fSubMenuOpen = idx;
}
}
else
{
if( fMenuItems[ idx ].fHandler != nil )
fMenuItems[ idx ].fHandler->DoSomething( ctrl );
// If item isn't a sub-menu, close this menu. Else add to list of menus to close
// once the smallest submenu goes away
if( fMenuItems[ idx ].fSubMenu == nil )
{
// Basically, we want to hide ourselves and as many up in the chain of command as
// can be hidden
pfGUIPopUpMenu *menu = this;
while( menu != nil && !menu->HasFlag( kStayOpenAfterClick ) )
{
menu->Hide();
menu = pfGUIPopUpMenu::ConvertNoRef( menu->fParent );
}
}
else
{
// Show relative to the corner of our current item
const hsBounds3 &bnds = ctrl->GetBounds();
fMenuItems[ idx ].fSubMenu->Show( bnds.GetMaxs().fX, bnds.GetMins().fY );
fSubMenuOpen = idx;
}
}
}
//// IBuildMenu //////////////////////////////////////////////////////////////
// Given the list of menu items, builds our set of dynamic buttons
hsBool pfGUIPopUpMenu::IBuildMenu( void )
{
int i;
if( fWaitingForSkin && fSkin == nil )
return false; // Still waiting to get our skin before building
pfGUIColorScheme *scheme = TRACKED_NEW pfGUIColorScheme();
scheme->fForeColor.Set( 0, 0, 0, 1 );
scheme->fBackColor.Set( 1, 1, 1, 1 );
// If we don't have origin points, get them from translating our anchor
if( fOriginX == -1 || fOriginY == -1 && fOriginAnchor != nil )
{
hsPoint3 scrnPt;
const plDrawInterface *di = fOriginAnchor->GetDrawInterface();
if( di != nil )
{
scrnPt = di->GetLocalBounds().GetCenter();
scrnPt = fOriginAnchor->GetLocalToWorld() * scrnPt;
}
else
scrnPt = fOriginAnchor->GetLocalToWorld().GetTranslate();
if( fOriginContext != nil )
scrnPt = fOriginContext->WorldToScreenPoint( scrnPt );
else
scrnPt = WorldToScreenPoint( scrnPt );
if( fOriginX == -1 )
fOriginX = scrnPt.fX;
if( fOriginY == -1 )
fOriginY = scrnPt.fY;
}
float x = fOriginX, y = fOriginY;
float width = 0.f, height = 0.f;
float topMargin = ( fSkin != nil ) ? fSkin->GetBorderMargin() : 0.f;
// First step: loop through and calculate the size of our menu
// The PROBLEM is that we can't do that unless we have a friggin surface on
// which to calculate the text extents! So sadly, we're going to have to create
// a whole new DTMap and use it to calculate some stuff
plDynamicTextMap *scratch = TRACKED_NEW plDynamicTextMap( 8, 8, false );
scratch->SetFont( scheme->fFontFace, scheme->fFontSize, scheme->fFontFlags, true );
for( i = 0; i < fMenuItems.GetCount(); i++ )
{
UInt16 thisW, thisH;
thisW = scratch->CalcStringWidth( fMenuItems[ i ].fName.c_str(), &thisH );
if( fMenuItems[ i ].fSubMenu != nil )
{
if( fSkin != nil )
thisW += 4 + ( fSkin->GetElement( pfGUISkin::kSubMenuArrow ).fWidth << 1 );
else
thisW += scratch->CalcStringWidth( " >>", nil );
}
thisH += 2; // Give us at least one pixel on each side
int margin = fMargin;
if( fSkin != nil )
margin = fSkin->GetBorderMargin() << 1;
if( width < thisW + margin )
width = (float)(thisW + margin);
if( fSkin != nil )
margin = fSkin->GetItemMargin() << 1;
if( height < thisH + margin )
height = (float)(thisH + margin);
}
delete scratch;
width += 4; // give us a little space, just in case
UInt32 scrnWidth, scrnHeight;
// A cheat here, I know, but I'm lazy
plDebugText::Instance().GetScreenSize( &scrnWidth, &scrnHeight );
// Use the same base res calc that dtMaps use
if( !HasFlag( kScaleWithResolution ) )
{
// Just use what we were passed in
}
else
{
// Scale with the resolution so that we take up the same % of screen space no matter what resolution
// Assume a base "resolution" of 1024xX, where X is such that the ratio "1024/X = scrnWidth/scrnHt" holds
const int kBaseScaleRes = 1024;
scrnHeight = ( scrnHeight * kBaseScaleRes ) / scrnWidth;
scrnWidth = kBaseScaleRes;
}
width /= (float)scrnWidth;
height /= (float)scrnHeight;
topMargin /= (float)scrnHeight;
switch( fAlignment )
{
case kAlignUpLeft: x -= width; y -= height * fMenuItems.GetCount(); break;
case kAlignUpRight: y -= height * fMenuItems.GetCount(); break;
case kAlignDownLeft: x -= width; break;
case kAlignDownRight: break;
}
if( y + height * fMenuItems.GetCount() > 1.f )
{
// Make sure we don't go off the bottom
y = 1.f - height * fMenuItems.GetCount();
}
// And the top (takes precedence)
if( y < 0.f )
y = 0.f;
// Control positions are in the lower left corner, so increment Y by 1 control height first
y += height;// + topMargin;
hsTArray<pfGUIPopUpMenu *> buildList;
for( i = 0; i < fMenuItems.GetCount(); i++ )
{
hsGMaterial *mat = ICreateDynMaterial();
float thisMargin = ( i == 0 || i == fMenuItems.GetCount() - 1 ) ? topMargin : 0.f;
float thisOffset = ( i == fMenuItems.GetCount() - 1 ) ? topMargin : 0.f;
pfGUIMenuItem *button = pfGUIMenuItem::ConvertNoRef( pfGUICtrlGenerator::Instance().CreateRectButton( this, fMenuItems[ i ].fName.c_str(), x, y + thisOffset, width, height + thisMargin, mat, true ) );
if( button != nil )
{
button->SetColorScheme( scheme );
button->SetName( fMenuItems[ i ].fName.c_str() );
button->SetHandler( TRACKED_NEW pfGUIMenuItemProc( this, i ) );
// make the tag ID the position in the menu list
button->SetTagID(i);
button->SetDynTextMap( mat->GetLayer( 0 ), plDynamicTextMap::ConvertNoRef( mat->GetLayer( 0 )->GetTexture() ) );
button->SetFlag( pfGUIMenuItem::kReportHovers );
button->SetSkin( fSkin, ( i == 0 ) ? pfGUIMenuItem::kTop : ( i == fMenuItems.GetCount() - 1 ) ? pfGUIMenuItem::kBottom : pfGUIMenuItem::kMiddle );
if( fMenuItems[ i ].fSubMenu != nil )
{
button->SetFlag( pfGUIMenuItem::kDrawSubMenuArrow );
buildList.Append( pfGUIPopUpMenu::ConvertNoRef( fMenuItems[ i ].fSubMenu ) );
}
}
// Tiny bit of overlap to prevent gaps
fMenuItems[ i ].fYOffsetToNext = height + thisOffset;
y += height + thisOffset;// - ( 1.f / kBaseScaleResY );
}
fNeedsRebuilding = false;
#if 0
// Finally, go down our list of submenus and rebuild them, since they'll need to be rebuilt soon anyway,
// and at least this way it's all in one pass
// Also, we need to bump the tag ID used, such as adding parent menuItem TagID * 100.. or something
// Disabled because right now we can't move menus, which is required for this to work
for( i = 0; i < buildList.GetCount(); i++ )
buildList[ i ]->IBuildMenu();
#endif
return true;
}
//// ITearDownMenu ///////////////////////////////////////////////////////////
// Destroys all of our dynamic controls representing the menu
void pfGUIPopUpMenu::ITearDownMenu( void )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
{
if( fControls[ i ] != nil )
{
// It's not enough to release the key, we have to have the sceneNode release the key, too.
// Easy enough to do by just setting it's sn to nil
if( fControls[ i ]->GetTarget() != nil )
fControls[ i ]->GetTarget()->SetSceneNode( nil );
// Now release it from us
GetKey()->Release( fControls[ i ]->GetKey() );
}
}
fNeedsRebuilding = true;
}
//// HandleMouseEvent ////////////////////////////////////////////////////////
hsBool pfGUIPopUpMenu::HandleMouseEvent( pfGameGUIMgr::EventType event, hsScalar mouseX, hsScalar mouseY,
UInt8 modifiers )
{
hsBool r = pfGUIDialogMod::HandleMouseEvent( event, mouseX, mouseY, modifiers );
if( r == false && event == pfGameGUIMgr::kMouseUp )
{
// We don't want to be active anymore!
if( !HasFlag( kStayOpenAfterClick ) )
{
Hide();
// Now we pass the click to our parent. Why? Because it's possible that someone above us
// will either a) also want to hide (cancel the entire menu selection) or b) select
// another option
if( fParent != nil )
return fParent->HandleMouseEvent( event, mouseX, mouseY, modifiers );
}
}
return ( fParent != nil ) ? r : ( HasFlag( kModalOutsideMenus ) || ( fSubMenuOpen != -1 ) );
}
//// ClearItems //////////////////////////////////////////////////////////////
// Clears the list of template items
void pfGUIPopUpMenu::ClearItems( void )
{
int i;
for( i = 0; i < fMenuItems.GetCount(); i++ )
{
if( fMenuItems[ i ].fHandler != nil )
{
if( fMenuItems[ i ].fHandler->DecRef() )
delete fMenuItems[ i ].fHandler;
}
}
fMenuItems.Reset();
fNeedsRebuilding = true;
}
//// AddItem /////////////////////////////////////////////////////////////////
// Append a new item to the list of things to build the menu from
void pfGUIPopUpMenu::AddItem( const char *name, pfGUICtrlProcObject *handler, pfGUIPopUpMenu *subMenu )
{
wchar_t *wName = hsStringToWString(name);
AddItem(wName,handler,subMenu);
delete [] wName;
}
void pfGUIPopUpMenu::AddItem( const wchar_t *name, pfGUICtrlProcObject *handler, pfGUIPopUpMenu *subMenu )
{
pfMenuItem newItem;
newItem.fName = name;
newItem.fHandler = handler;
if( newItem.fHandler != nil )
newItem.fHandler->IncRef();
newItem.fSubMenu = subMenu;
if( subMenu != nil )
subMenu->fParent = this;
fMenuItems.Append( newItem );
fNeedsRebuilding = true;
}
//// ICreateDynMaterial //////////////////////////////////////////////////////
// Creates the hsGMaterial tree for a single layer with a plDynamicTextMap.
hsGMaterial *pfGUIPopUpMenu::ICreateDynMaterial( void )
{
hsColorRGBA black, white;
// Create the new dynTextMap
plDynamicTextMap *textMap = TRACKED_NEW plDynamicTextMap();
fKeyGen->CreateKey( textMap );
// Create the material
hsGMaterial *material = TRACKED_NEW hsGMaterial;
fKeyGen->CreateKey( material );
// Create the layer and attach
plLayer *lay = material->MakeBaseLayer();
white.Set( 1.f,1.f,1.f,1.f );
black.Set( 0.f,0.f,0.f,1.f );
lay->SetRuntimeColor( black );
lay->SetPreshadeColor( black );
lay->SetAmbientColor( white );
lay->SetClampFlags( hsGMatState::kClampTexture );
// Do sendRef here, since we're going to need it set pretty darned quick
hsgResMgr::ResMgr()->SendRef( textMap->GetKey(), TRACKED_NEW plLayRefMsg( lay->GetKey(), plRefMsg::kOnCreate, 0, plLayRefMsg::kTexture ), plRefFlags::kActiveRef );
return material;
}
//// Build ///////////////////////////////////////////////////////////////////
// Constructs a shiny new pop-up menu at runtime, complete with trimmings
#include "../plJPEG/plJPEG.h"
pfGUIPopUpMenu *pfGUIPopUpMenu::Build( const char *name, pfGUIDialogMod *parent, hsScalar x, hsScalar y, const plLocation &destLoc )
{
float fovX, fovY;
// Create the menu and give it a key gen
pfGUIPopUpMenu *menu = TRACKED_NEW pfGUIPopUpMenu();
menu->fKeyGen = TRACKED_NEW pfPopUpKeyGenerator( name, destLoc );
menu->fKeyGen->CreateKey( menu );
menu->fOriginX = x;
menu->fOriginY = y;
// By default, share the same skin as the parent
if( parent != nil && ( (pfGUIPopUpMenu *)parent )->fSkin != nil )
{
menu->fWaitingForSkin = true;
hsgResMgr::ResMgr()->SendRef( ( (pfGUIPopUpMenu *)parent )->fSkin->GetKey(), TRACKED_NEW plGenRefMsg( menu->GetKey(), plRefMsg::kOnCreate, -1, pfGUIPopUpMenu::kRefSkin ), plRefFlags::kActiveRef );
}
// HACK for now: create us a temp skin to use
/* static pfGUISkin *skin = nil;
if( skin == nil )
{
plLocation loc;
loc.Set( 0x1425 );
plKey skinKey = hsgResMgr::ResMgr()->FindKey( plUoid( loc, pfGUISkin::Index(), "GUISkin01_GUISkin" ) );
menu->fWaitingForSkin = true;
hsgResMgr::ResMgr()->AddViaNotify( skinKey, TRACKED_NEW plGenRefMsg( menu->GetKey(), plRefMsg::kOnCreate, -1, pfGUIPopUpMenu::kRefSkin ), plRefFlags::kActiveRef );
}
*/
// Create the rendermod
plPostEffectMod *renderMod = TRACKED_NEW plPostEffectMod;
menu->fKeyGen->CreateKey( renderMod );
renderMod->SetHither( 0.5f );
renderMod->SetYon( 200.f );
float scrnWidth = 20.f;
// fovX should be such that scrnWidth is the projected width at z=100
fovX = atan( scrnWidth / ( 2.f * 100.f ) ) * 2.f;
fovY = fovX;// * 3.f / 4.f;
renderMod->SetFovX( fovX * 180.f / hsScalarPI );
renderMod->SetFovY( fovY * 180.f / hsScalarPI );
// Create the sceneNode to go with it
menu->fParentNode= TRACKED_NEW plSceneNode;
menu->fKeyGen->CreateKey( menu->fParentNode );
// menu->fParentNode->GetKey()->RefObject();
hsgResMgr::ResMgr()->SendRef( menu->fParentNode->GetKey(), TRACKED_NEW plGenRefMsg( menu->GetKey(), plRefMsg::kOnCreate, 0, kRefParentNode ), plRefFlags::kActiveRef );
hsgResMgr::ResMgr()->AddViaNotify( menu->fParentNode->GetKey(), TRACKED_NEW plGenRefMsg( renderMod->GetKey(), plRefMsg::kOnCreate, 0, plPostEffectMod::kNodeRef ), plRefFlags::kPassiveRef );
menu->SetRenderMod( renderMod );
menu->SetName( name );
// Create the dummy scene object to hold the menu
plSceneObject *newObj = TRACKED_NEW plSceneObject;
menu->fKeyGen->CreateKey( newObj );
// *#&$(*@&#$ need a coordIface...
plCoordinateInterface *newCI = TRACKED_NEW plCoordinateInterface;
menu->fKeyGen->CreateKey( newCI );
hsMatrix44 l2w, w2l;
l2w.Reset();
l2w.GetInverse( &w2l );
// Using SendRef here because AddViaNotify will queue the messages up, which doesn't do us any good
// if we need these refs right away
hsgResMgr::ResMgr()->SendRef( newCI->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface ), plRefFlags::kActiveRef );
hsgResMgr::ResMgr()->SendRef( renderMod->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kModifier ), plRefFlags::kActiveRef );
newObj->SetSceneNode( menu->fParentNode->GetKey() );
newObj->SetTransform( l2w, w2l );
hsgResMgr::ResMgr()->SendRef( menu->GetKey(), TRACKED_NEW plObjRefMsg( newObj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kModifier ), plRefFlags::kActiveRef );
// Add the menu to the GUI mgr
plGenRefMsg *refMsg = TRACKED_NEW plGenRefMsg( pfGameGUIMgr::GetInstance()->GetKey(),
plRefMsg::kOnCreate, 0, pfGameGUIMgr::kDlgModRef );
hsgResMgr::ResMgr()->AddViaNotify( menu->GetKey(), refMsg, plRefFlags::kActiveRef );
menu->ISeekToOrigin();
return menu;
}
//// SetSkin /////////////////////////////////////////////////////////////////
void pfGUIPopUpMenu::SetSkin( pfGUISkin *skin )
{
// Just a function wrapper for SendRef
if( fSkin != nil )
GetKey()->Release( fSkin->GetKey() );
if( skin != nil )
{
hsgResMgr::ResMgr()->SendRef( skin->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefSkin ), plRefFlags::kActiveRef );
fWaitingForSkin = true;
}
else
fWaitingForSkin = false;
}
//////////////////////////////////////////////////////////////////////////////
//// pfGUISkin Implementation ////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
pfGUISkin::pfGUISkin()
{
fTexture = nil;
memset( fElements, 0, sizeof( pfSRect ) * kNumElements );
}
pfGUISkin::pfGUISkin( plMipmap *texture )
{
fTexture = texture;
if( fTexture != nil )
{
hsAssert( fTexture->GetKey() != nil, "Creating a GUI skin via a mipmap with no key!" );
fTexture->GetKey()->RefObject();
}
memset( fElements, 0, sizeof( pfSRect ) * kNumElements );
}
pfGUISkin::~pfGUISkin()
{
SetTexture( nil );
}
void pfGUISkin::SetTexture( plMipmap *tex )
{
if( fTexture != nil && fTexture->GetKey() != nil )
fTexture->GetKey()->UnRefObject();
fTexture = tex;
if( fTexture != nil )
{
hsAssert( fTexture->GetKey() != nil, "Creating a GUI skin via a mipmap with no key!" );
fTexture->GetKey()->RefObject();
}
}
void pfGUISkin::SetElement( UInt32 idx, UInt16 x, UInt16 y, UInt16 w, UInt16 h )
{
fElements[ idx ].fX = x;
fElements[ idx ].fY = y;
fElements[ idx ].fWidth = w;
fElements[ idx ].fHeight = h;
}
void pfGUISkin::Read( hsStream *s, hsResMgr *mgr )
{
hsKeyedObject::Read( s, mgr );
s->ReadSwap( &fItemMargin );
s->ReadSwap( &fBorderMargin );
UInt32 i, count;
s->ReadSwap( &count );
for( i = 0; i < count; i++ )
fElements[ i ].Read( s );
for( ; i < kNumElements; i++ )
fElements[ i ].Empty();
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefMipmap ), plRefFlags::kActiveRef );
}
void pfGUISkin::Write( hsStream *s, hsResMgr *mgr )
{
hsKeyedObject::Write( s, mgr );
s->WriteSwap( fItemMargin );
s->WriteSwap( fBorderMargin );
UInt32 i = kNumElements;
s->WriteSwap( i );
for( i = 0; i < kNumElements; i++ )
fElements[ i ].Write( s );
mgr->WriteKey( s, fTexture );
}
hsBool pfGUISkin::MsgReceive( plMessage *msg )
{
plGenRefMsg *ref = plGenRefMsg::ConvertNoRef( msg );
if( ref != nil )
{
if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
fTexture = plMipmap::ConvertNoRef( ref->GetRef() );
else
fTexture = nil;
return true;
}
return hsKeyedObject::MsgReceive( msg );
}
void pfGUISkin::pfSRect::Read( hsStream *s )
{
s->ReadSwap( &fX );
s->ReadSwap( &fY );
s->ReadSwap( &fWidth );
s->ReadSwap( &fHeight );
}
void pfGUISkin::pfSRect::Write( hsStream *s )
{
s->WriteSwap( fX );
s->WriteSwap( fY );
s->WriteSwap( fWidth );
s->WriteSwap( fHeight );
}

View File

@ -0,0 +1,241 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIPopUpMenu Header //
// //
// Pop-up menus are really just dialogs that know how to create themselves //
// and create buttons on themselves to simulate a menu (after all, that's //
// all a menu really is anyway). //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIPopUpMenu_h
#define _pfGUIPopUpMenu_h
#include "pfGUIDialogMod.h"
#include "hsBounds.h"
class plMessage;
class pfGUIButtonMod;
class pfPopUpKeyGenerator;
class pfGUICtrlProcObject;
class hsGMaterial;
class plSceneNode;
class pfGUIMenuItemProc;
class pfGUISkin;
class pfGUIPopUpMenu : public pfGUIDialogMod
{
public:
enum Alignment
{
kAlignUpLeft,
kAlignUpRight,
kAlignDownLeft,
kAlignDownRight // Default
};
protected:
friend class pfGUIMenuItemProc;
pfGUIDialogMod *fParent; // Pop-up menus also have a sense of who owns them
plSceneNode *fParentNode;
pfPopUpKeyGenerator *fKeyGen; // Generates keys for our dynamic objects
class pfMenuItem
{
// Simple wrapper class that tells us how to build our menu
public:
std::wstring fName;
pfGUICtrlProcObject *fHandler;
pfGUIPopUpMenu *fSubMenu;
float fYOffsetToNext; // Filled in by IBuildMenu()
pfMenuItem& operator=(const int zero) { fName = L""; fHandler = nil; fSubMenu = nil; fYOffsetToNext = 0; return *this; }
};
// Array of info to rebuild our menu from. Note that this is ONLY used when rebuilding
hsBool fNeedsRebuilding, fWaitingForSkin;
hsScalar fOriginX, fOriginY;
UInt16 fMargin;
hsTArray<pfMenuItem> fMenuItems;
Int32 fSubMenuOpen;
pfGUISkin *fSkin;
plSceneObject *fOriginAnchor;
pfGUIDialogMod *fOriginContext;
Alignment fAlignment;
hsBool IBuildMenu( void );
void ITearDownMenu( void );
hsGMaterial *ICreateDynMaterial( void );
void IHandleMenuSomething( UInt32 idx, pfGUIControlMod *ctrl, Int32 extended = -1 );
void ISeekToOrigin( void );
public:
pfGUIPopUpMenu();
virtual ~pfGUIPopUpMenu();
CLASSNAME_REGISTER( pfGUIPopUpMenu );
GETINTERFACE_ANY( pfGUIPopUpMenu, pfGUIDialogMod );
enum MenuFlags
{
kStayOpenAfterClick = kDerivedFlagsStart,
kModalOutsideMenus,
kOpenSubMenusOnHover,
kScaleWithResolution
};
enum Refs
{
kRefSkin = kRefDerviedStart,
kRefSubMenu,
kRefOriginAnchor,
kRefOriginContext,
kRefParentNode
};
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void SetEnabled( hsBool e );
virtual hsBool HandleMouseEvent( pfGameGUIMgr::EventType event, hsScalar mouseX, hsScalar mouseY, UInt8 modifiers );
void Show( hsScalar x, hsScalar y );
void SetOriginAnchor( plSceneObject *anchor, pfGUIDialogMod *context );
void SetAlignment( Alignment a ) { fAlignment = a; }
void ClearItems( void );
void AddItem( const char *name, pfGUICtrlProcObject *handler, pfGUIPopUpMenu *subMenu = nil );
void AddItem( const wchar_t *name, pfGUICtrlProcObject *handler, pfGUIPopUpMenu *subMenu = nil );
void SetSkin( pfGUISkin *skin );
static pfGUIPopUpMenu *Build( const char *name, pfGUIDialogMod *parent, hsScalar x, hsScalar y, const plLocation &destLoc = plLocation::kGlobalFixedLoc );
};
// Skin definition. Here for now 'cause only the menus use it, but might move it later
class plMipmap;
class pfGUISkin : public hsKeyedObject
{
public:
enum Elements
{
kUpLeftCorner = 0,
kTopSpan,
kUpRightCorner,
kRightSpan,
kLowerRightCorner,
kBottomSpan,
kLowerLeftCorner,
kLeftSpan,
kMiddleFill,
kSelectedFill,
kSubMenuArrow,
kSelectedSubMenuArrow,
kTreeButtonClosed,
kTreeButtonOpen,
kNumElements
};
class pfSRect
{
public:
UInt16 fX, fY, fWidth, fHeight;
void Empty( void ) { fX = fY = fWidth = fHeight = 0; }
void Read( hsStream *s );
void Write( hsStream *s );
};
protected:
plMipmap *fTexture;
pfSRect fElements[ kNumElements ];
UInt16 fItemMargin, fBorderMargin;
public:
pfGUISkin();
pfGUISkin( plMipmap *texture );
virtual ~pfGUISkin();
CLASSNAME_REGISTER( pfGUISkin );
GETINTERFACE_ANY( pfGUISkin, hsKeyedObject );
enum Refs
{
kRefMipmap
};
virtual void Read( hsStream *s, hsResMgr *mgr );
virtual void Write( hsStream *s, hsResMgr *mgr );
virtual hsBool MsgReceive( plMessage *msg );
plMipmap *GetTexture( void ) const { return fTexture; }
void SetTexture( plMipmap *tex );
const pfSRect &GetElement( UInt32 idx ) const { return fElements[ idx ]; }
hsBool IsElementSet( UInt32 idx ) const { return ( fElements[ idx ].fWidth > 0 && fElements[ idx ].fHeight > 0 ); }
void SetElement( UInt32 idx, UInt16 x, UInt16 y, UInt16 w, UInt16 h );
void SetMargins( UInt16 item, UInt16 border ) { fItemMargin = item; fBorderMargin = border; }
UInt16 GetItemMargin( void ) const { return fItemMargin; }
UInt16 GetBorderMargin( void ) const { return fBorderMargin; }
};
#endif // _pfGUIPopUpMenu_h

View File

@ -0,0 +1,271 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIProgressCtrl Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIProgressCtrl.h"
#include "pfGameGUIMgr.h"
#include "pfGUIDialogMod.h"
#include "../plInputCore/plInputInterface.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plMessage/plTimerCallbackMsg.h"
// #include "../plAvatar/plAGModifier.h"
#include "../plAvatar/plAGMasterMod.h"
#include "../plAvatar/plAGAnimInstance.h"
#include "../plSurface/plLayerAnimation.h"
#include "../pnSceneObject/plSceneObject.h"
#include "../pnSceneObject/plCoordinateInterface.h"
#include "../pnTimer/plTimerCallbackManager.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIProgressCtrl::pfGUIProgressCtrl() : fStopSoundTimer(99)
{
fAnimTimesCalced = false;
fAnimName = nil;
fPlaySound = true;
}
pfGUIProgressCtrl::~pfGUIProgressCtrl()
{
delete [] fAnimName;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIProgressCtrl::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIValueCtrl::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIProgressCtrl::MsgReceive( plMessage *msg )
{
plTimerCallbackMsg *timerMsg = plTimerCallbackMsg::ConvertNoRef(msg);
if (timerMsg)
{
if (timerMsg->fID == fStopSoundTimer)
{
// we've finished animating, stop the sound that's playing
StopSound(kAnimateSound);
}
}
return pfGUIValueCtrl::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIProgressCtrl::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIValueCtrl::Read(s, mgr);
fAnimationKeys.Reset();
UInt32 i, count = s->ReadSwap32();
for( i = 0; i < count; i++ )
fAnimationKeys.Append( mgr->ReadKey( s ) );
fAnimName = s->ReadSafeString();
fAnimTimesCalced = false;
}
void pfGUIProgressCtrl::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIValueCtrl::Write( s, mgr );
UInt32 i, count = fAnimationKeys.GetCount();
s->WriteSwap32( count );
for( i = 0; i < count; i++ )
mgr->WriteKey( s, fAnimationKeys[ i ] );
s->WriteSafeString( fAnimName );
}
//// UpdateBounds ////////////////////////////////////////////////////////////
void pfGUIProgressCtrl::UpdateBounds( hsMatrix44 *invXformMatrix, hsBool force )
{
pfGUIValueCtrl::UpdateBounds( invXformMatrix, force );
if( fAnimationKeys.GetCount() > 0 )
fBoundsValid = false;
}
//// SetAnimationKeys ////////////////////////////////////////////////////////
void pfGUIProgressCtrl::SetAnimationKeys( hsTArray<plKey> &keys, const char *name )
{
fAnimationKeys = keys;
delete [] fAnimName;
if( name != nil )
{
fAnimName = TRACKED_NEW char[ strlen( name ) + 1 ];
strcpy( fAnimName, name );
}
else
fAnimName = nil;
}
//// ICalcAnimTimes //////////////////////////////////////////////////////////
// Loops through and computes the max begin and end for our animations. If
// none of them are loaded and we're not already calced, returns false.
hsBool pfGUIProgressCtrl::ICalcAnimTimes( void )
{
if( fAnimTimesCalced )
return true;
hsScalar tBegin = 1e30, tEnd = -1e30;
bool foundOne = false;
for( int i = 0; i < fAnimationKeys.GetCount(); i++ )
{
// Handle AGMasterMods
plAGMasterMod *mod = plAGMasterMod::ConvertNoRef( fAnimationKeys[ i ]->ObjectIsLoaded() );
if( mod != nil )
{
for( int j = 0; j < mod->GetNumAnimations(); j++ )
{
hsScalar begin = mod->GetAnimInstance( j )->GetTimeConvert()->GetBegin();
hsScalar end = mod->GetAnimInstance( j )->GetTimeConvert()->GetEnd();
if( begin < tBegin )
tBegin = begin;
if( end > tEnd )
tEnd = end;
}
foundOne = true;
}
// Handle layer animations
plLayerAnimation *layer = plLayerAnimation::ConvertNoRef( fAnimationKeys[ i ]->ObjectIsLoaded() );
if( layer != nil )
{
hsScalar begin = layer->GetTimeConvert().GetBegin();
hsScalar end = layer->GetTimeConvert().GetEnd();
if( begin < tBegin )
tBegin = begin;
if( end > tEnd )
tEnd = end;
foundOne = true;
}
}
if( foundOne )
{
fAnimBegin = tBegin;
fAnimEnd = tEnd;
fAnimTimesCalced = true;
}
return fAnimTimesCalced;
}
//// SetCurrValue ////////////////////////////////////////////////////////////
void pfGUIProgressCtrl::SetCurrValue( hsScalar v )
{
int old = (int)fValue;
pfGUIValueCtrl::SetCurrValue( v );
// if( old == (int)fValue )
// return;
if( fAnimationKeys.GetCount() > 0 )
{
ICalcAnimTimes();
hsScalar tLength = fAnimEnd - fAnimBegin;
hsScalar newTime;
if( HasFlag( kReverseValues ) )
newTime = ( ( fMax - fValue ) / ( fMax - fMin ) ) * tLength + fAnimBegin;
else
newTime = ( ( fValue - fMin ) / ( fMax - fMin ) ) * tLength + fAnimBegin;
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
msg->SetCmd( plAnimCmdMsg::kGoToTime );
msg->SetAnimName( fAnimName );
msg->fTime = newTime;
msg->AddReceivers( fAnimationKeys );
plgDispatch::MsgSend( msg );
}
}
void pfGUIProgressCtrl::AnimateToPercentage( hsScalar percent )
{
// percent should be a value in range 0.0 to 1.0
if (percent >= 0.0f && percent <= 1.0f)
{
pfGUIValueCtrl::SetCurrValue( (fMax - fMin) * percent + fMin );
if( fAnimationKeys.GetCount() > 0 )
{
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
msg->SetCmd( plAnimCmdMsg::kPlayToPercentage );
msg->SetAnimName( fAnimName );
msg->fTime = percent;
msg->AddReceivers( fAnimationKeys );
plgDispatch::MsgSend( msg );
if (fPlaySound)
{
// play the sound, looping
PlaySound(kAnimateSound, true);
// setup a timer to call back when we finish animating
hsScalar elapsedTime = (fAnimEnd - fAnimBegin) * percent;
plTimerCallbackMsg *timerMsg = TRACKED_NEW plTimerCallbackMsg(GetKey(), fStopSoundTimer);
plgTimerCallbackMgr::NewTimer(elapsedTime, timerMsg);
}
}
}
}

View File

@ -0,0 +1,109 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIProgressCtrl Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIProgressCtrl_h
#define _pfGUIProgressCtrl_h
#include "pfGUIValueCtrl.h"
class plMessage;
class plAGMasterMod;
class pfGUIProgressCtrl : public pfGUIValueCtrl
{
protected:
hsTArray<plKey> fAnimationKeys;
char *fAnimName;
// Computed once, once an anim is loaded that we can compute this with
hsScalar fAnimBegin, fAnimEnd;
hsBool fAnimTimesCalced;
hsBool fPlaySound;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
hsBool ICalcAnimTimes( void );
const UInt32 fStopSoundTimer;
public:
pfGUIProgressCtrl();
virtual ~pfGUIProgressCtrl();
CLASSNAME_REGISTER( pfGUIProgressCtrl );
GETINTERFACE_ANY( pfGUIProgressCtrl, pfGUIValueCtrl );
enum OurFlags
{
kReverseValues = kDerivedFlagsStart
};
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void UpdateBounds( hsMatrix44 *invXformMatrix = nil, hsBool force = false );
virtual void SetCurrValue( hsScalar v );
virtual void AnimateToPercentage( hsScalar percent );
enum SoundEvents
{
kAnimateSound
};
void DontPlaySounds() { fPlaySound = false; }
// Export only
void SetAnimationKeys( hsTArray<plKey> &keys, const char *name );
};
#endif // _pfGUIProgressCtrl_h

View File

@ -0,0 +1,273 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIRadioGroupCtrl Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIRadioGroupCtrl.h"
#include "pfGameGUIMgr.h"
#include "pfGUICheckBoxCtrl.h"
#include "pfGUIControlHandlers.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Wee Little Control Proc for our buttons /////////////////////////////////
class pfGroupProc : public pfGUICtrlProcObject
{
protected:
pfGUIRadioGroupCtrl *fParent;
public:
pfGroupProc( pfGUIRadioGroupCtrl *parent )
{
fParent = parent;
}
virtual void DoSomething( pfGUIControlMod *ctrl )
{
Int32 newIdx;
// So one of our controls got clicked. That means that we change our value
// to the proper index
pfGUICheckBoxCtrl *check = pfGUICheckBoxCtrl::ConvertNoRef( ctrl );
// Are we unselecting? And do we allow this?
if( !check->IsChecked() && !fParent->HasFlag( pfGUIRadioGroupCtrl::kAllowNoSelection ) )
{
// Boo on you. Re-check
check->SetChecked( true );
return;
}
for( newIdx = 0; newIdx < fParent->fControls.GetCount(); newIdx++ )
{
if( fParent->fControls[ newIdx ] == check )
break;
}
if( newIdx == fParent->fControls.GetCount() )
newIdx = -1;
if( newIdx != fParent->fValue )
{
if( fParent->fValue != -1 )
fParent->fControls[ fParent->fValue ]->SetChecked( false );
fParent->fValue = newIdx;
if( newIdx != -1 )
fParent->fControls[ newIdx ]->SetChecked( true );
}
else
{
if( !check->IsChecked() && fParent->HasFlag( pfGUIRadioGroupCtrl::kAllowNoSelection ) )
{
// nobody is checked!
fParent->fValue = -1;
}
}
fParent->DoSomething();
}
};
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIRadioGroupCtrl::pfGUIRadioGroupCtrl()
{
fButtonProc = TRACKED_NEW pfGroupProc( this );
fButtonProc->IncRef();
SetFlag( kIntangible );
}
pfGUIRadioGroupCtrl::~pfGUIRadioGroupCtrl()
{
if( fButtonProc->DecRef() )
delete fButtonProc;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIRadioGroupCtrl::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIRadioGroupCtrl::MsgReceive( plMessage *msg )
{
plGenRefMsg *refMsg = plGenRefMsg::ConvertNoRef( msg );
if( refMsg != nil )
{
if( refMsg->fType == kRefControl )
{
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
{
fControls[ refMsg->fWhich ] = pfGUICheckBoxCtrl::ConvertNoRef( refMsg->GetRef() );
fControls[ refMsg->fWhich ]->SetHandler( fButtonProc );
if( fValue == refMsg->fWhich )
fControls[ refMsg->fWhich ]->SetChecked( true );
}
else
{
fControls[ refMsg->fWhich ] = nil;
}
return true;
}
}
return pfGUIControlMod::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIRadioGroupCtrl::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
UInt32 i, count = s->ReadSwap32();
fControls.SetCountAndZero( count );
for( i = 0; i < count; i++ )
{
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, i, kRefControl ), plRefFlags::kActiveRef );
}
fValue = fDefaultValue = s->ReadSwap16();
if( fValue != -1 && fControls[ fValue ] != nil )
fControls[ fValue ]->SetChecked( true );
}
void pfGUIRadioGroupCtrl::Write( hsStream *s, hsResMgr *mgr )
{
UInt32 i;
pfGUIControlMod::Write( s, mgr );
s->WriteSwap32( fControls.GetCount() );
for( i = 0; i < fControls.GetCount(); i++ )
mgr->WriteKey( s, fControls[ i ]->GetKey() );
s->WriteSwap16( (UInt16)fDefaultValue );
}
//// SetValue ////////////////////////////////////////////////////////////////
void pfGUIRadioGroupCtrl::SetValue( Int32 value )
{
if( value != fValue && ( value != -1 || HasFlag( kAllowNoSelection ) ) )
{
if( fValue != -1 )
fControls[ fValue ]->SetChecked( false );
fValue = value;
if( value != -1 )
fControls[ value ]->SetChecked( true );
DoSomething();
}
}
///// Setting to be trickled down to the underlings
void pfGUIRadioGroupCtrl::SetEnabled( hsBool e )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
fControls[ i ]->SetEnabled(e);
}
void pfGUIRadioGroupCtrl::SetInteresting( hsBool e )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
fControls[ i ]->SetInteresting(e);
}
void pfGUIRadioGroupCtrl::SetVisible( hsBool vis )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
fControls[ i ]->SetVisible(vis);
}
void pfGUIRadioGroupCtrl::SetControlsFlag( int flag )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
fControls[ i ]->SetFlag(flag);
}
void pfGUIRadioGroupCtrl::ClearControlsFlag( int flag )
{
int i;
for( i = 0; i < fControls.GetCount(); i++ )
fControls[ i ]->ClearFlag(flag);
}
//// Export Functions ////////////////////////////////////////////////////////
void pfGUIRadioGroupCtrl::ClearControlList( void )
{
fControls.Reset();
fValue = -1;
}
void pfGUIRadioGroupCtrl::AddControl( pfGUICheckBoxCtrl *ctrl )
{
fControls.Append( ctrl );
}

View File

@ -0,0 +1,110 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIRadioGroupCtrl Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIRadioGroupCtrl_h
#define _pfGUIRadioGroupCtrl_h
#include "pfGUIValueCtrl.h"
#include "hsTemplates.h"
class plMessage;
class pfGUICheckBoxCtrl;
class pfGroupProc;
class pfGUIRadioGroupCtrl : public pfGUIControlMod
{
friend class pfGroupProc;
protected:
enum
{
kRefControl = kRefDerivedStart
};
hsTArray<pfGUICheckBoxCtrl *> fControls;
pfGroupProc *fButtonProc;
Int32 fValue, fDefaultValue;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
public:
pfGUIRadioGroupCtrl();
virtual ~pfGUIRadioGroupCtrl();
CLASSNAME_REGISTER( pfGUIRadioGroupCtrl );
GETINTERFACE_ANY( pfGUIRadioGroupCtrl, pfGUIControlMod );
enum OurFlags
{
kAllowNoSelection = kDerivedFlagsStart
};
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
Int32 GetValue( void ) { return fValue; }
void SetValue( Int32 value );
virtual void SetEnabled( hsBool e );
virtual void SetInteresting( hsBool e );
virtual void SetVisible( hsBool vis );
virtual void SetControlsFlag( int flag );
virtual void ClearControlsFlag( int flag );
/// Export ONLY
void ClearControlList( void );
void AddControl( pfGUICheckBoxCtrl *ctrl );
void SetDefaultValue( Int32 value ) { fDefaultValue = value; }
};
#endif // _pfGUIRadioGroupCtrl_h

View File

@ -0,0 +1,98 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUITagDefs.cpp //
// List of Tag IDs for the GameGUIMgr //
// //
//////////////////////////////////////////////////////////////////////////////
#include "pfGameGUIMgr.h"
#include "pfGUITagDefs.h"
//// Tag List ////////////////////////////////////////////////////////////////
// Here's the actual list of tags. It's basically a list of konstants, but
// they get translated into two things:
// 1. An enum, to send as a UInt32 to the GetDialogFromTag() and
// GetControlFromTag() functions.
// 2. A string, which gets put in a dropdown box in the appropriate
// MAX component, which sets the given control's tag ID to the
// right konstant.
// Step 1: add your konstant to the end of the .h file list
// Step 2: Add the string here
pfGUITag gGUITags[] = {
{ kKIMainDialog, "KI Main Dialog" },
{ kKITestEditBox, "KI Test Control" },
{ kKIEntryDlg, "KI Entry Dlg" },
{ kKICloseButton, "KI Close Dlg Button" },
{ kKITestControl2, "KI Test Control 2" },
{ kKIAddButton, "KI Add Button" },
{ kKIEditButton, "KI Edit Button" },
{ kKIRemoveButton, "KI Remove Button" },
{ kKIYesNoDlg, "KI Yes/No Dialog" },
{ kKIYesBtn, "KI Yes Button" },
{ kKINoBtn, "KI No Button" },
{ kKIStaticText, "KI Static Text" },
{ kKITestControl3, "KI Test Control 3" },
{ kKIMiniDialog, "KI Mini Dialog" },
{ kPlayerBook, "PB Dialog" },
{ kPBLinkToBtn, "PB Link To Button" },
{ kPBSaveLinkBtn, "PB Save Link Button" },
{ kPBSaveSlotRadio, "PB Save Slot Radio" },
{ kPBSaveSlotPrev1, "PB Save Slot Preview 1" },
{ kPBSaveSlotPrev2, "PB Save Slot Preview 2" },
{ kPBSaveSlotPrev3, "PB Save Slot Preview 3" },
{ kPBSaveSlotPrev4, "PB Save Slot Preview 4" },
{ kPBSaveSlotPrev5, "PB Save Slot Preview 5" },
{ kPBSaveSlotPrev6, "PB Save Slot Preview 6" },
{ kKICurrPlayerText, "KI Current Player Label" },
{ kKIPlayerList, "KI Mini Friends List" },
{ kKIChatModeBtn, "KI Toggle Chat Mode Btn" },
{ kBlackBarDlg, "Black Bar Dialog" },
{ kBlackBarKIButtons, "Black Bar KI Radio Group" },
{ kKILogoutButton, "KI Logout Button" },
{ 0, "" } // Ending tag, MUST ALWAYS BE HERE
};

View File

@ -0,0 +1,104 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUITagDefs.cpp //
// List of Tag IDs for the GameGUIMgr //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUITagDefs_h
#define _pfGUITagDefs_h
#include "pfGameGUIMgr.h"
//// Tag List ////////////////////////////////////////////////////////////////
// Here's the actual list of tags. It's basically a list of konstants, but
// they get translated into two things:
// 1. An enum, to send as a UInt32 to the GetDialogFromTag() and
// GetControlFromTag() functions.
// 2. A string, which gets put in a dropdown box in the appropriate
// MAX component, which sets the given control's tag ID to the
// right konstant.
// Step 1: Add your konstant to the end of this list
enum
{
kKIMainDialog = 1,
kKITestEditBox,
kKIEntryDlg,
kKICloseButton,
kKITestControl2,
kKIAddButton,
kKIEditButton,
kKIRemoveButton,
kKIYesNoDlg,
kKIYesBtn,
kKINoBtn,
kKIStaticText,
kKITestControl3,
kKIMiniDialog,
kPlayerBook,
kPBLinkToBtn,
kPBSaveLinkBtn,
kPBSaveSlotRadio,
kPBSaveSlotPrev1,
kPBSaveSlotPrev2,
kPBSaveSlotPrev3,
kPBSaveSlotPrev4,
kPBSaveSlotPrev5,
kPBSaveSlotPrev6,
kKICurrPlayerText = 30,
kKIPlayerList = 31,
kKIChatModeBtn = 32,
kBlackBarDlg = 33,
kBlackBarKIButtons = 34,
kKILogoutButton = 35,
};
// Step 2: Add the string to the .cpp file
#endif

View File

@ -0,0 +1,262 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUITextBoxMod Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "hsStlUtils.h"
#include "pfGUITextBoxMod.h"
#include "pfGameGUIMgr.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plAvatar/plAGModifier.h"
#include "../plGImage/plDynamicTextMap.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
#include "../plResMgr/plLocalization.h"
#include "../pfLocalizationMgr/pfLocalizationMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUITextBoxMod::pfGUITextBoxMod()
{
// SetFlag( kWantsInterest );
SetFlag( kIntangible );
fText = nil;
fUseLocalizationPath = false;
}
pfGUITextBoxMod::~pfGUITextBoxMod()
{
delete [] fText;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUITextBoxMod::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIControlMod::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUITextBoxMod::MsgReceive( plMessage *msg )
{
return pfGUIControlMod::MsgReceive( msg );
}
//// IPostSetUpDynTextMap ////////////////////////////////////////////////////
void pfGUITextBoxMod::IPostSetUpDynTextMap( void )
{
pfGUIColorScheme *scheme = GetColorScheme();
fDynTextMap->SetFont( scheme->fFontFace, scheme->fFontSize, scheme->fFontFlags,
HasFlag( kXparentBgnd ) ? false : true );
fDynTextMap->SetTextColor( scheme->fForeColor,
( HasFlag( kXparentBgnd ) && scheme->fBackColor.a == 0.f ) ? true : false );
}
//// IUpdate /////////////////////////////////////////////////////////////////
void pfGUITextBoxMod::IUpdate( void )
{
if( fDynTextMap == nil || !fDynTextMap->IsValid() )
return;
if( HasFlag( kCenterJustify ) )
fDynTextMap->SetJustify( plDynamicTextMap::kCenter );
else if( HasFlag( kRightJustify ) )
fDynTextMap->SetJustify( plDynamicTextMap::kRightJustify );
else
fDynTextMap->SetJustify( plDynamicTextMap::kLeftJustify );
fDynTextMap->ClearToColor( GetColorScheme()->fBackColor );
std::wstring drawStr;
if (fUseLocalizationPath && !fLocalizationPath.empty() && pfLocalizationMgr::InstanceValid())
drawStr = pfLocalizationMgr::Instance().GetString(fLocalizationPath.c_str());
else
{
if( fText != nil )
{
int lang = plLocalization::GetLanguage();
std::vector<std::wstring> translations = plLocalization::StringToLocal(fText);
if (translations[lang] == L"") // if the translations doesn't exist, draw English
drawStr = translations[0].c_str();
else
drawStr = translations[lang].c_str();
}
}
if (!drawStr.empty())
fDynTextMap->DrawWrappedString( 4, 4, drawStr.c_str(), fDynTextMap->GetVisibleWidth() - 8, fDynTextMap->GetVisibleHeight() - 8 );
fDynTextMap->FlushToHost();
}
void pfGUITextBoxMod::PurgeDynaTextMapImage()
{
if ( fDynTextMap != nil )
fDynTextMap->PurgeImage();
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUITextBoxMod::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
UInt32 len = s->ReadSwap32();
if( len > 0 )
{
char *text = TRACKED_NEW char[ len + 1 ];
s->Read( len, text );
text[ len ] = 0;
fText = hsStringToWString(text);
delete [] text;
}
else
fText = nil;
fUseLocalizationPath = (s->ReadBool() != 0);
if (fUseLocalizationPath)
{
wchar_t* temp = s->ReadSafeWString();
fLocalizationPath = temp;
delete [] temp;
}
}
void pfGUITextBoxMod::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Write( s, mgr );
if( fText == nil )
s->WriteSwap32( 0 );
else
{
char *text = hsWStringToString(fText);
s->WriteSwap32( strlen( text ) );
s->Write( strlen( text ), text );
delete [] text;
}
// Make sure we only write out to use localization path if the box is checked
// and the path isn't empty
bool useLoc = fUseLocalizationPath && !fLocalizationPath.empty();
s->WriteBool(useLoc);
if (useLoc)
s->WriteSafeWString(fLocalizationPath.c_str());
}
//// HandleMouseDown/Up //////////////////////////////////////////////////////
void pfGUITextBoxMod::HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers )
{
}
void pfGUITextBoxMod::HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers )
{
}
void pfGUITextBoxMod::HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers )
{
}
//// SetText /////////////////////////////////////////////////////////////////
void pfGUITextBoxMod::SetText( const char *text )
{
delete [] fText;
if (text)
{
fText = hsStringToWString(text);
}
else
fText = nil;
IUpdate();
}
void pfGUITextBoxMod::SetText( const wchar_t *text )
{
delete [] fText;
if (text)
{
fText = TRACKED_NEW wchar_t[wcslen(text)+1];
wcscpy(fText,text);
}
else
fText = nil;
IUpdate();
}
void pfGUITextBoxMod::SetLocalizationPath(const wchar_t* path)
{
if (path)
fLocalizationPath = path;
}
void pfGUITextBoxMod::SetLocalizationPath(const char* path)
{
if (path)
{
wchar_t* wPath = hsStringToWString(path);
fLocalizationPath = wPath;
delete [] wPath;
}
}
void pfGUITextBoxMod::SetUseLocalizationPath(bool use)
{
fUseLocalizationPath = use;
}

View File

@ -0,0 +1,107 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUITextBoxMod Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUITextBoxMod_h
#define _pfGUITextBoxMod_h
#include "pfGUIControlMod.h"
class plMessage;
class hsGMaterial;
class plTextGenerator;
class pfGUITextBoxMod : public pfGUIControlMod
{
protected:
wchar_t *fText;
std::wstring fLocalizationPath;
bool fUseLocalizationPath;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual void IUpdate( void );
virtual void IPostSetUpDynTextMap( void );
public:
pfGUITextBoxMod();
virtual ~pfGUITextBoxMod();
CLASSNAME_REGISTER( pfGUITextBoxMod );
GETINTERFACE_ANY( pfGUITextBoxMod, pfGUIControlMod );
enum OurFlags
{
kCenterJustify = kDerivedFlagsStart,
kRightJustify
};
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void HandleMouseDown( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseUp( hsPoint3 &mousePt, UInt8 modifiers );
virtual void HandleMouseDrag( hsPoint3 &mousePt, UInt8 modifiers );
virtual void PurgeDynaTextMapImage();
virtual const wchar_t* GetText() { return fText; }
// Export only
void SetText( const char *text );
void SetText( const wchar_t *text );
void SetLocalizationPath(const wchar_t* path);
void SetLocalizationPath(const char* path);
void SetUseLocalizationPath(bool use);
};
#endif // _pfGUITextBoxMod_h

View File

@ -0,0 +1,241 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIUpDownPairMod Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIUpDownPairMod.h"
#include "pfGameGUIMgr.h"
#include "pfGUIButtonMod.h"
#include "pfGUIControlHandlers.h"
#include "../pnMessage/plRefMsg.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plAnimCmdMsg.h"
#include "../plAvatar/plAGModifier.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Wee Little Control Proc for our buttons /////////////////////////////////
class pfUpDownBtnProc : public pfGUICtrlProcObject
{
protected:
pfGUIButtonMod *fUp, *fDown;
pfGUIUpDownPairMod *fParent;
public:
pfUpDownBtnProc( pfGUIButtonMod *up, pfGUIButtonMod *down, pfGUIUpDownPairMod *parent )
{
fUp = up;
fDown = down;
fParent = parent;
}
void SetUp( pfGUIButtonMod *up ) { fUp = up; }
void SetDown( pfGUIButtonMod *down ) { fDown = down; }
virtual void DoSomething( pfGUIControlMod *ctrl )
{
if( (pfGUIButtonMod *)ctrl == fUp )
{
fParent->fValue += fParent->fStep;
if( fParent->fValue > fParent->fMax )
fParent->fValue = fParent->fMax;
}
else
{
fParent->fValue -= fParent->fStep;
if( fParent->fValue < fParent->fMin )
fParent->fValue = fParent->fMin;
}
fParent->Update();
fParent->DoSomething();
}
};
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIUpDownPairMod::pfGUIUpDownPairMod()
{
fUpControl = nil;
fDownControl = nil;
fValue = fMin = fMax = fStep = 0.f;
fButtonProc = TRACKED_NEW pfUpDownBtnProc( nil, nil, this );
fButtonProc->IncRef();
SetFlag( kIntangible );
}
pfGUIUpDownPairMod::~pfGUIUpDownPairMod()
{
if( fButtonProc->DecRef() )
delete fButtonProc;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIUpDownPairMod::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIValueCtrl::IEval( secs, del, dirty );
}
void pfGUIUpDownPairMod::IUpdate( void )
{
if (fEnabled)
{
if (fUpControl)
{
if ( fValue >= fMax)
fUpControl->SetVisible(false);
else
fUpControl->SetVisible(true);
}
if (fDownControl)
{
if ( fValue <= fMin )
fDownControl->SetVisible(false);
else
fDownControl->SetVisible(true);
}
}
else
{
fUpControl->SetVisible(false);
fDownControl->SetVisible(false);
}
}
void pfGUIUpDownPairMod::Update( void )
{
IUpdate();
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIUpDownPairMod::MsgReceive( plMessage *msg )
{
plGenRefMsg *refMsg = plGenRefMsg::ConvertNoRef( msg );
if( refMsg != nil )
{
if( refMsg->fType == kRefUpControl )
{
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
{
fUpControl = pfGUIButtonMod::ConvertNoRef( refMsg->GetRef() );
fUpControl->SetHandler( fButtonProc );
fButtonProc->SetUp( fUpControl );
}
else
{
fUpControl = nil;
fButtonProc->SetUp( nil );
}
return true;
}
else if( refMsg->fType == kRefDownControl )
{
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
{
fDownControl = pfGUIButtonMod::ConvertNoRef( refMsg->GetRef() );
fDownControl->SetHandler( fButtonProc );
fButtonProc->SetDown( fDownControl );
}
else
{
fDownControl = nil;
fButtonProc->SetDown( nil );
}
return true;
}
}
return pfGUIValueCtrl::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIUpDownPairMod::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIValueCtrl::Read(s, mgr);
fUpControl = nil;
fDownControl = nil;
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefUpControl ), plRefFlags::kActiveRef );
mgr->ReadKeyNotifyMe( s, TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, -1, kRefDownControl ), plRefFlags::kActiveRef );
s->ReadSwap( &fMin );
s->ReadSwap( &fMax );
s->ReadSwap( &fStep );
fValue = fMin;
}
void pfGUIUpDownPairMod::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIValueCtrl::Write( s, mgr );
mgr->WriteKey( s, fUpControl->GetKey() );
mgr->WriteKey( s, fDownControl->GetKey() );
s->WriteSwap( fMin );
s->WriteSwap( fMax );
s->WriteSwap( fStep );
}
void pfGUIUpDownPairMod::SetRange( hsScalar min, hsScalar max )
{
pfGUIValueCtrl::SetRange( min, max );
IUpdate();
}
void pfGUIUpDownPairMod::SetCurrValue( hsScalar v )
{
pfGUIValueCtrl::SetCurrValue( v );
IUpdate();
}

View File

@ -0,0 +1,100 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIUpDownPairMod Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIUpDownPairMod_h
#define _pfGUIUpDownPairMod_h
#include "pfGUIValueCtrl.h"
class plMessage;
class pfGUIButtonMod;
class pfUpDownBtnProc;
class pfGUIUpDownPairMod : public pfGUIValueCtrl
{
friend class pfUpDownBtnProc;
protected:
enum
{
kRefUpControl = kRefDerivedStart,
kRefDownControl
};
pfGUIButtonMod *fUpControl, *fDownControl;
pfUpDownBtnProc *fButtonProc;
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // called only by owner object's Eval()
virtual void IUpdate( void );
public:
pfGUIUpDownPairMod();
virtual ~pfGUIUpDownPairMod();
CLASSNAME_REGISTER( pfGUIUpDownPairMod );
GETINTERFACE_ANY( pfGUIUpDownPairMod, pfGUIValueCtrl );
virtual hsBool MsgReceive( plMessage* pMsg );
virtual void Update( void );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual void SetRange( hsScalar min, hsScalar max );
virtual void SetCurrValue( hsScalar v );
/// Export ONLY
void SetControls( pfGUIButtonMod *up, pfGUIButtonMod *down ) { fUpControl = up; fDownControl = down; }
};
#endif // _pfGUIUpDownPairMod_h

View File

@ -0,0 +1,111 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIValueCtrl Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIValueCtrl.h"
#include "pfGameGUIMgr.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIValueCtrl::pfGUIValueCtrl()
{
fValue = fMin = fMax = fStep = 0.f;
}
pfGUIValueCtrl::~pfGUIValueCtrl()
{
}
//// SetCurrValue ////////////////////////////////////////////////////////////
void pfGUIValueCtrl::SetCurrValue( hsScalar v )
{
fValue = v;
if( fValue < fMin )
fValue = fMin;
else if( fValue > fMax )
fValue = fMax;
}
//// SetRange ////////////////////////////////////////////////////////////////
void pfGUIValueCtrl::SetRange( hsScalar min, hsScalar max )
{
fMin = min;
fMax = max;
if( fValue < fMin )
SetCurrValue( fMin );
else if( fValue > fMax )
SetCurrValue( fMax );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIValueCtrl::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Read(s, mgr);
s->ReadSwap( &fMin );
s->ReadSwap( &fMax );
s->ReadSwap( &fStep );
fValue = fMin;
}
void pfGUIValueCtrl::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIControlMod::Write( s, mgr );
s->WriteSwap( fMin );
s->WriteSwap( fMax );
s->WriteSwap( fStep );
}

View File

@ -0,0 +1,84 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIValueCtrl Header //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGUIValueCtrl_h
#define _pfGUIValueCtrl_h
#include "pfGUIControlMod.h"
class pfGUIValueCtrl : public pfGUIControlMod
{
protected:
hsScalar fValue, fMin, fMax, fStep;
public:
pfGUIValueCtrl();
virtual ~pfGUIValueCtrl();
CLASSNAME_REGISTER( pfGUIValueCtrl );
GETINTERFACE_ANY( pfGUIValueCtrl, pfGUIControlMod );
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
virtual hsScalar GetCurrValue( void ) { return fValue; }
virtual void SetCurrValue( hsScalar v );
virtual hsScalar GetMin( void ) { return fMin; }
virtual hsScalar GetMax( void ) { return fMax; }
virtual hsScalar GetStep( void ) { return fStep; }
virtual void SetRange( hsScalar min, hsScalar max );
virtual void SetStep( hsScalar step ) { fStep = step; }
};
#endif // _pfGUIValueCtrl_h

View File

@ -0,0 +1,959 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGameGUIMgr //
// //
//// History /////////////////////////////////////////////////////////////////
// //
// 11.13.2001 mcn - Created //
// //
//////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include "hsTimer.h"
#include "hsTypes.h"
#include "pfGameGUIMgr.h"
#include "pfGUIDialogMod.h"
#include "pfGUIDialogHandlers.h"
#include "pfGUIDialogNotifyProc.h"
#include "pfGUIControlMod.h"
#include "pfGUIPopUpMenu.h"
#include "../pfMessage/pfGameGUIMsg.h"
#include "../plMessage/plInputEventMsg.h"
#include "../plMessage/plInputIfaceMgrMsg.h"
#include "../pnMessage/plClientMsg.h"
#include "../pnNetCommon/plSynchedObject.h"
#include "../plInputCore/plInputInterface.h"
#include "../plInputCore/plInputDevice.h"
#include "../plInputCore/plInputInterfaceMgr.h"
#include "../pnInputCore/plKeyMap.h"
#include "../pnKeyedObject/plFixedKey.h"
#include "../pnSceneObject/plSceneObject.h" // So we can get the target sceneNode of a dialog
#include "../plMessage/plConsoleMsg.h"
#include "plgDispatch.h"
#include "../plResMgr/plKeyFinder.h"
#include "pfGUITagDefs.h"
//////////////////////////////////////////////////////////////////////////////
//// pfGameUIInputInterface Definition ///////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
class pfGameUIInputInterface : public plInputInterface
{
protected:
pfGameGUIMgr * const fGUIManager;
UInt8 fModifiers;
UInt8 fButtonState;
hsBool fHaveInterestingCursor;
UInt32 fCurrentCursor;
virtual hsBool IHandleCtrlCmd( plCtrlCmd *cmd );
virtual hsBool IControlCodeEnabled( ControlEventCode code );
public:
pfGameUIInputInterface( pfGameGUIMgr * const mgr );
virtual UInt32 GetPriorityLevel( void ) const { return kGUISystemPriority; }
virtual hsBool InterpretInputEvent( plInputEventMsg *pMsg );
virtual UInt32 GetCurrentCursorID( void ) const;
virtual hsScalar GetCurrentCursorOpacity( void ) const;
virtual hsBool HasInterestingCursorID( void ) const { return fHaveInterestingCursor; }
virtual hsBool SwitchInterpretOrder( void ) const { return true; }
virtual void RestoreDefaultKeyMappings( void )
{
if( fControlMap != nil )
{
fControlMap->UnmapAllBindings();
fControlMap->BindKey( KEY_BACKSPACE, B_CONTROL_EXIT_GUI_MODE, plKeyMap::kFirstAlways );
fControlMap->BindKey( KEY_ESCAPE, B_CONTROL_EXIT_GUI_MODE, plKeyMap::kSecondAlways );
}
}
};
//////////////////////////////////////////////////////////////////////////////
//// pfGameGUIMgr Functions //////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
pfGameGUIMgr *pfGameGUIMgr::fInstance = nil;
//// Constructor & Destructor ////////////////////////////////////////////////
pfGameGUIMgr::pfGameGUIMgr()
{
fActivated = false;
fInputCtlIndex = 0;
fActiveDialogs = nil;
fInputConfig = nil;
fInstance = this;
fDefaultCursor = plInputInterface::kCursorUp;
fCursorOpacity = 1.f;
fAspectRatio = 0;
}
pfGameGUIMgr::~pfGameGUIMgr()
{
int i;
// the GUIMgr is dead!
fInstance = nil;
for( i = 0; i < fDialogs.GetCount(); i++ )
UnloadDialog( fDialogs[ i ] );
for( i = 0; i < fDialogToSetKeyOf.GetCount(); i++ )
delete fDialogToSetKeyOf[i];
if( fActivated )
IActivateGUI( false );
delete fInputConfig;
}
//// Init ////////////////////////////////////////////////////////////////////
hsBool pfGameGUIMgr::Init( void )
{
return true;
}
//// Draw ////////////////////////////////////////////////////////////////////
void pfGameGUIMgr::Draw( plPipeline *p )
{
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGameGUIMgr::MsgReceive( plMessage* pMsg )
{
pfGameGUIMsg *guiMsg = pfGameGUIMsg::ConvertNoRef( pMsg );
if( guiMsg != nil )
{
if( guiMsg->GetCommand() == pfGameGUIMsg::kLoadDialog )
LoadDialog( guiMsg->GetString(), nil, guiMsg->GetAge() );
else if( guiMsg->GetCommand() == pfGameGUIMsg::kShowDialog )
IShowDialog( guiMsg->GetString() );
else if( guiMsg->GetCommand() == pfGameGUIMsg::kHideDialog )
IHideDialog( guiMsg->GetString() );
return true;
}
plGenRefMsg *refMsg = plGenRefMsg::ConvertNoRef( pMsg );
if( refMsg != nil )
{
if( refMsg->fType == kDlgModRef )
{
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest ) )
{
IAddDlgToList( refMsg->GetRef() );
}
else if( refMsg->GetContext() & plRefMsg::kOnReplace )
{
IRemoveDlgFromList( refMsg->GetOldRef() );
IAddDlgToList( refMsg->GetRef() );
}
else if( refMsg->GetContext() & ( plRefMsg::kOnRemove | plRefMsg::kOnDestroy ) )
{
IRemoveDlgFromList( refMsg->GetRef() );
}
}
return true;
}
return hsKeyedObject::MsgReceive( pMsg );
}
//// IAddDlgToList ///////////////////////////////////////////////////////////
void pfGameGUIMgr::IAddDlgToList( hsKeyedObject *obj )
{
int i;
if( fDialogs.Find( (pfGUIDialogMod *)obj ) == fDialogs.kMissingIndex )
{
pfGUIDialogMod *mod = pfGUIDialogMod::ConvertNoRef( obj );
if( mod != nil )
{
mod->UpdateAspectRatio(); // adding a new dialog, make sure the correct aspect ratio is set
fDialogs.Append( mod );
// check to see if it is the dialog we are waiting for to be loaded
for ( i=0 ; i<fDialogToSetKeyOf.Count() ; i++ )
{
if ( hsStrEQ(fDialogToSetKeyOf[i]->GetName(), mod->GetName()) )
{
SetDialogToNotify(mod,fDialogToSetKeyOf[i]->GetKey());
// now remove this entry... we did it
delete fDialogToSetKeyOf[i];
fDialogToSetKeyOf.Remove(i);
// that's all the damage we can do for now...
break;
}
}
}
}
/* // It's now officially "loaded"; take it off the pending list
for( i = 0; i < fDlgsPendingLoad.GetCount(); i++ )
{
if( stricmp( fDlgsPendingLoad[ i ]->GetName(), ( (pfGUIDialogMod *)obj )->GetName() ) == 0 )
{
// Here it is
delete fDlgsPendingLoad[ i ];
fDlgsPendingLoad.Remove( i );
break;
}
}
*/
}
//// IRemoveDlgFromList //////////////////////////////////////////////////////
void pfGameGUIMgr::IRemoveDlgFromList( hsKeyedObject *obj )
{
int idx = fDialogs.Find( (pfGUIDialogMod *)obj );
if( idx != fDialogs.kMissingIndex )
{
pfGUIDialogMod *mod = pfGUIDialogMod::ConvertNoRef( obj );
hsAssert( mod != nil, "Non-dialog sent to gameGUIMgr::IRemoveDlg()" );
if( mod != nil )
{
if( mod->IsEnabled() )
{
mod->SetEnabled( false );
mod->Unlink();
if( fActiveDialogs == nil )
IActivateGUI( false );
}
// Needed?
// GetKey()->Release( mod->GetKey() );
fDialogs.Remove( idx );
}
}
// It's now officially "unloaded"; take it off the pending list
/* int i;
for( i = 0; i < fDlgsPendingUnload.GetCount(); i++ )
{
if( stricmp( fDlgsPendingUnload[ i ]->GetName(), ( (pfGUIDialogMod *)obj )->GetName() ) == 0 )
{
// Here it is
delete fDlgsPendingUnload[ i ];
fDlgsPendingUnload.Remove( i );
break;
}
}
*/
}
//// LoadDialog //////////////////////////////////////////////////////////////
void pfGameGUIMgr::LoadDialog( const char *name, plKey recvrKey, const char *ageName )
{
// see if they want to set the receiver key once the dialog is loaded
if ( recvrKey != nil )
{
// first see if we are loading a dialog that is already being loaded
bool alreadyLoaded = false;
int i;
for ( i=0 ; i<fDialogToSetKeyOf.Count() ; i++ )
{
if ( hsStrEQ(fDialogToSetKeyOf[i]->GetName(), name) )
{
alreadyLoaded = true;
break;
}
}
if (!alreadyLoaded)
{
pfDialogNameSetKey* pDNSK = TRACKED_NEW pfDialogNameSetKey(name,recvrKey);
fDialogToSetKeyOf.Append(pDNSK);
}
}
hsStatusMessageF("\nLoading Dialog %s %s ... %f\n", name, ( ageName != nil ) ? ageName : "GUI", hsTimer::GetSeconds() );
plKey clientKey = hsgResMgr::ResMgr()->FindKey( kClient_KEY );
plClientMsg *msg = TRACKED_NEW plClientMsg( plClientMsg::kLoadRoomHold );
msg->AddReceiver( clientKey );
msg->AddRoomLoc(plKeyFinder::Instance().FindLocation(ageName ? ageName : "GUI", name));
msg->Send();
// Now add this dialog to a list of pending loads (will remove it once it's fully loaded)
// fDlgsPendingLoad.Append( TRACKED_NEW pfDialogNameSetKey( name, nil ) );
}
//// IShowDialog /////////////////////////////////////////////////////////////
void pfGameGUIMgr::IShowDialog( const char *name )
{
int i;
for( i = 0; i < fDialogs.GetCount(); i++ )
{
if( stricmp( fDialogs[ i ]->GetName(), name ) == 0 )
{
ShowDialog( fDialogs[ i ] );
fDialogs[i]->RefreshAllControls();
break;
}
}
}
//// IHideDialog /////////////////////////////////////////////////////////////
void pfGameGUIMgr::IHideDialog( const char *name )
{
int i;
for( i = 0; i < fDialogs.GetCount(); i++ )
{
if( stricmp( fDialogs[ i ]->GetName(), name ) == 0 )
{
HideDialog( fDialogs[ i ] );
break;
}
}
}
//// ShowDialog //////////////////////////////////////////////////////////////
void pfGameGUIMgr::ShowDialog( pfGUIDialogMod *dlg, bool resetClickables /* = true */ )
{
if ( resetClickables )
plInputInterfaceMgr::GetInstance()->ResetClickableState();
if( !dlg->IsEnabled() )
{
dlg->SetEnabled( true );
// Add to active list
if( fActiveDialogs == nil )
IActivateGUI( true );
dlg->LinkToList( &fActiveDialogs );
return;
}
}
//// HideDialog //////////////////////////////////////////////////////////////
void pfGameGUIMgr::HideDialog( pfGUIDialogMod *dlg )
{
if( dlg->IsEnabled() )
{
dlg->SetEnabled( false );
dlg->Unlink();
if( fActiveDialogs == nil )
IActivateGUI( false );
}
}
//// UnloadDialog ////////////////////////////////////////////////////////////
// Destroy the dialog and all the things associated with it. Fun fun.
void pfGameGUIMgr::UnloadDialog( const char *name )
{
int i;
for( i = 0; i < fDialogs.GetCount(); i++ )
{
if( stricmp( fDialogs[ i ]->GetName(), name ) == 0 )
{
UnloadDialog( fDialogs[ i ] );
break;
}
}
}
void pfGameGUIMgr::UnloadDialog( pfGUIDialogMod *dlg )
{
// IRemoveDlgFromList( dlg );
// Add the name to our list of dialogs pending unload
// fDlgsPendingUnload.Append( TRACKED_NEW pfDialogNameSetKey( dlg->GetName(), nil ) );
plKey sceneNodeKey = dlg->GetSceneNodeKey();
if( sceneNodeKey == nil )
{
hsStatusMessageF( "Warning: Unable to grab sceneNodeKey to unload dialog %s; searching for it...", dlg->GetName() );
sceneNodeKey = plKeyFinder::Instance().FindSceneNodeKey( dlg->GetKey()->GetUoid().GetLocation() );
}
// if( dlg->GetTarget() )
if( sceneNodeKey != nil )
{
plKey clientKey = hsgResMgr::ResMgr()->FindKey( kClient_KEY );
plClientMsg *msg = TRACKED_NEW plClientMsg( plClientMsg::kUnloadRoom );
msg->AddReceiver( clientKey );
// msg->SetProgressBarSuppression( true );
msg->AddRoomLoc(sceneNodeKey->GetUoid().GetLocation());
msg->Send();
}
// GetKey()->Release( dlg->GetKey() );
}
//// IsDialogLoaded ////// see if the dialog is in our list of loaded dialogs
hsBool pfGameGUIMgr::IsDialogLoaded( const char *name )
{
// search through all the dialogs we've loaded
int i;
for( i = 0; i < fDialogs.GetCount(); i++ )
{
if( stricmp( fDialogs[ i ]->GetName(), name ) == 0 )
{
// found 'em
return true;
}
}
// nota
return false;
}
pfGUIPopUpMenu *pfGameGUIMgr::FindPopUpMenu( const char *name )
{
int i;
for( i = 0; i < fDialogs.GetCount(); i++ )
{
pfGUIPopUpMenu *menu = pfGUIPopUpMenu::ConvertNoRef( fDialogs[ i ] );
if( menu != nil && stricmp( menu->GetName(), name ) == 0 )
return menu;
}
return nil;
}
std::vector<plPostEffectMod*> pfGameGUIMgr::GetDlgRenderMods( void ) const
{
std::vector<plPostEffectMod*> retVal;
pfGUIDialogMod* curDialog = fActiveDialogs;
while (curDialog)
{
retVal.push_back(curDialog->GetRenderMod());
curDialog = curDialog->GetNext();
}
return retVal;
}
///// SetDialogToNotify - based on name
// This will Set the handler to a Notify Handler that will send a GUINotifyMsg to the receiver
//
void pfGameGUIMgr::SetDialogToNotify(const char *name, plKey recvrKey)
{
int i;
for( i = 0; i < fDialogs.GetCount(); i++ )
{
if( stricmp( fDialogs[ i ]->GetName(), name ) == 0 )
{
SetDialogToNotify( fDialogs[ i ], recvrKey );
break;
}
}
}
///// SetDialogToNotify - pfGUIDialogMod*
// This will Set the handler to a Notify Handler that will send a GUINotifyMsg to the receiver
//
void pfGameGUIMgr::SetDialogToNotify(pfGUIDialogMod *dlg, plKey recvrKey)
{
pfGUIDialogNotifyProc* handler = TRACKED_NEW pfGUIDialogNotifyProc(recvrKey);
dlg->SetHandler(handler);
handler->OnInit();
}
//// IActivateGUI ////////////////////////////////////////////////////////////
// "Activates" the GUI manager. This means enabling the drawing of GUI
// elements on the screen as well as rerouting input to us.
void pfGameGUIMgr::IActivateGUI( hsBool activate )
{
if( fActivated == activate )
return;
if( activate )
{
fInputConfig = TRACKED_NEW pfGameUIInputInterface( this );
plInputIfaceMgrMsg *msg = TRACKED_NEW plInputIfaceMgrMsg( plInputIfaceMgrMsg::kAddInterface );
msg->SetIFace( fInputConfig );
plgDispatch::MsgSend( msg );
}
else
{
plInputIfaceMgrMsg *msg = TRACKED_NEW plInputIfaceMgrMsg( plInputIfaceMgrMsg::kRemoveInterface );
msg->SetIFace( fInputConfig );
plgDispatch::MsgSend( msg );
hsRefCnt_SafeUnRef( fInputConfig );
fInputConfig = nil;
}
fActivated = activate;
}
//// IHandleMouse ////////////////////////////////////////////////////////////
// Distributes mouse events to the dialogs currently active
hsBool pfGameGUIMgr::IHandleMouse( EventType event, hsScalar mouseX, hsScalar mouseY, UInt8 modifiers, UInt32 *desiredCursor )
{
pfGUIDialogMod *dlg;
// Update interesting things first, no matter what, for ALL dialogs
hsBool modalPresent = false;
for( dlg = fActiveDialogs; dlg != nil; dlg = dlg->GetNext() )
{
dlg->UpdateInterestingThings( mouseX, mouseY, modifiers, modalPresent );
if (dlg->HasFlag( pfGUIDialogMod::kModal ))
modalPresent = true;
}
for( dlg = fActiveDialogs; dlg != nil; dlg = dlg->GetNext() )
{
if( dlg->HandleMouseEvent( event, mouseX, mouseY, modifiers ) ||
( dlg->HasFlag( pfGUIDialogMod::kModal ) && event != pfGameGUIMgr::kMouseUp ) )
{
// If this dialog handled it, also get the cursor it wants
*desiredCursor = dlg->GetDesiredCursor();
return true;
}
}
return false;
}
//// IHandleKeyEvt ///////////////////////////////////////////////////////////
// Distributes mouse events to the dialogs currently active
hsBool pfGameGUIMgr::IHandleKeyEvt( EventType event, plKeyDef key, UInt8 modifiers )
{
pfGUIDialogMod *dlg;
for( dlg = fActiveDialogs; dlg != nil; dlg = dlg->GetNext() )
{
if( dlg->HandleKeyEvent( event, key, modifiers ) )
return true;
}
return false;
}
//// IHandleKeyPress /////////////////////////////////////////////////////////
// Like IHandleKeyPress, but takes in a char for distributing actual
// characters typed.
hsBool pfGameGUIMgr::IHandleKeyPress( char key, UInt8 modifiers )
{
pfGUIDialogMod *dlg;
for( dlg = fActiveDialogs; dlg != nil; dlg = dlg->GetNext() )
{
if( dlg->HandleKeyPress( key, modifiers ) )
return true;
}
return false;
}
//// IModalBlocking //////////////////////////////////////////////////////////
// Looks at the chain of active dialogs and determines if there's any modals
// blocking input. Returns true if so.
hsBool pfGameGUIMgr::IModalBlocking( void )
{
return ( IGetTopModal() != nil ) ? true : false;
}
//// IGetTopModal ////////////////////////////////////////////////////////////
// Returns the topmost (visible) modal dialog, nil if none.
pfGUIDialogMod *pfGameGUIMgr::IGetTopModal( void ) const
{
pfGUIDialogMod *dlg;
for( dlg = fActiveDialogs; dlg != nil; dlg = dlg->GetNext() )
{
if( dlg->HasFlag( pfGUIDialogMod::kModal ) )
return dlg;
}
return nil;
}
//////////////////////////////////////////////////////////////////////////////
//// Control Config Class ////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
pfGameUIInputInterface::pfGameUIInputInterface( pfGameGUIMgr * const mgr ) : plInputInterface(), fGUIManager( mgr )
{
fModifiers = pfGameGUIMgr::kNoModifiers;
fButtonState = 0;
fHaveInterestingCursor = false;
SetEnabled( true ); // Always enabled
fCurrentCursor = kCursorUp;
// Add our control codes to our control map. Do NOT add the key bindings yet.
// Note: HERE is where you specify the actions for each command, i.e. net propagate and so forth.
// This part basically declares us master of the bindings for these commands.
// IF YOU ARE LOOKING TO CHANGE THE DEFAULT KEY BINDINGS, DO NOT LOOK HERE. GO TO
// RestoreDefaultKeyMappings()!!!!
fControlMap->AddCode( B_CONTROL_EXIT_GUI_MODE, kControlFlagNormal | kControlFlagNoRepeat );
// IF YOU ARE LOOKING TO CHANGE THE DEFAULT KEY BINDINGS, DO NOT LOOK HERE. GO TO
// RestoreDefaultKeyMappings()!!!!
}
hsBool pfGameUIInputInterface::IControlCodeEnabled( ControlEventCode code )
{
if( code == B_CONTROL_EXIT_GUI_MODE )
{
// Disable the exitGUIMode key binding if we don't have a modal dialog up or if
// the cursor is inside an edit or multiline edit control
if( !fGUIManager->IModalBlocking() )
return false;
pfGUIDialogMod *dlg = fGUIManager->IGetTopModal();
if( dlg != nil )
{
pfGUIControlMod *ctrl = dlg->GetFocus();
if( ctrl != nil && ctrl->HasFlag( pfGUIControlMod::kTakesSpecialKeys ) )
return false;
}
}
return true; // Enable all other codes
}
hsBool pfGameUIInputInterface::IHandleCtrlCmd( plCtrlCmd *cmd )
{
if( cmd->fControlCode == B_CONTROL_EXIT_GUI_MODE )
{
if( cmd->fControlActivated )
{
pfGUIDialogMod *dlg = fGUIManager->IGetTopModal();
if( dlg != nil && dlg->GetHandler() != nil )
dlg->GetHandler()->OnControlEvent( pfGUIDialogProc::kExitMode );
}
return true;
}
return false;
}
hsBool pfGameUIInputInterface::InterpretInputEvent( plInputEventMsg *pMsg )
{
hsBool handled = false;
/// The in-game UI has to do far more complicated control handling, so we just overload this entirely
plKeyEventMsg *pKeyMsg = plKeyEventMsg::ConvertNoRef( pMsg );
if( pKeyMsg )
{
// By default, we don't want the modifier keys treated as "handled", 'cause
// we want the other interfaces to get them as well (unless we have a modal
// as the top dialog).
if( pKeyMsg->GetKeyCode() == KEY_SHIFT )
{
if( pKeyMsg->GetKeyDown() )
fModifiers |= pfGameGUIMgr::kShiftDown;
else
fModifiers &= ~pfGameGUIMgr::kShiftDown;
}
else if( pKeyMsg->GetKeyCode() == KEY_CTRL )
{
if( pKeyMsg->GetKeyDown() )
fModifiers |= pfGameGUIMgr::kCtrlDown;
else
fModifiers &= ~pfGameGUIMgr::kCtrlDown;
}
else if( pKeyMsg->GetKeyCode() == KEY_CAPSLOCK )
{
if( pKeyMsg->GetKeyDown() )
fModifiers |= pfGameGUIMgr::kCapsDown;
else
fModifiers &= ~pfGameGUIMgr::kCapsDown;
}
else
{
// Sometimes I can't explain why Mathew does some of the things he does.
// I going to replace his modifier flags (which I don't know why he thought he had to have his own)
// with the ones that are in the keymsg since they seem to be more accurate!
fModifiers = 0;
if ( pKeyMsg->GetShiftKeyDown() )
fModifiers |= pfGameGUIMgr::kShiftDown;
if ( pKeyMsg->GetCtrlKeyDown() )
fModifiers |= pfGameGUIMgr::kCtrlDown;
if ( pKeyMsg->GetCapsLockKeyDown() )
fModifiers |= pfGameGUIMgr::kCapsDown;
if( pKeyMsg->GetKeyDown() )
{
if( !pKeyMsg->GetRepeat() )
handled = fGUIManager->IHandleKeyEvt( pfGameGUIMgr::kKeyDown, pKeyMsg->GetKeyCode(), fModifiers );
else
handled = fGUIManager->IHandleKeyEvt( pfGameGUIMgr::kKeyRepeat, pKeyMsg->GetKeyCode(), fModifiers );
handled |= fGUIManager->IHandleKeyPress( plKeyboardDevice::KeyEventToChar( pKeyMsg ), fModifiers );
}
else
handled = fGUIManager->IHandleKeyEvt( pfGameGUIMgr::kKeyUp, pKeyMsg->GetKeyCode(), fModifiers );
}
// We need to do early interception of a screenshot request, since they want
// us to be able to take screen shots while in a modal GUI... whee
// Also, this should only be run if the dialog didn't handle the command in
// the first place (taking screenshots while the user is typing would be
// awkward) and we must do it on key down because the key binding routines
// also trigger on key-down and we don't want to be taking screen shots when
// the user re-binds the screenshot command.
// HACK HACK HACK
if ((!handled) && (pKeyMsg->GetKeyDown()))
{
const plKeyBinding* keymap = plInputInterfaceMgr::GetInstance()->FindBindingByConsoleCmd("Game.KITakePicture");
if (keymap)
{
unsigned keyFlags = 0;
if (pKeyMsg->GetCtrlKeyDown())
keyFlags |= plKeyCombo::kCtrl;
if (pKeyMsg->GetShiftKeyDown())
keyFlags |= plKeyCombo::kShift;
plKeyCombo combo(pKeyMsg->GetKeyCode(), keyFlags);
if ((keymap->GetKey1().IsSatisfiedBy(combo)) || (keymap->GetKey2().IsSatisfiedBy(combo)))
{
// tell the KI to take the shot
plConsoleMsg * consoleMsg = NEWZERO(plConsoleMsg);
consoleMsg->SetCmd(plConsoleMsg::kExecuteLine);
consoleMsg->SetString("Game.KITakePicture");
consoleMsg->Send(nil, true);
}
}
}
bool modal = fGUIManager->IModalBlocking();
return handled || modal; // we "handle" it if we are modal, even if it didn't do anything
}
plMouseEventMsg *pMouseMsg = plMouseEventMsg::ConvertNoRef( pMsg );
if( pMouseMsg && fManager->IsClickEnabled() )
{
if( pMouseMsg->GetButton() == kLeftButtonDown )
{
handled = fGUIManager->IHandleMouse( pfGameGUIMgr::kMouseDown, pMouseMsg->GetXPos(), pMouseMsg->GetYPos(), fModifiers, &fCurrentCursor );
if (handled)
fButtonState |= kLeftButtonDown;
}
else if( pMouseMsg->GetButton() == kLeftButtonUp )
{
handled = fGUIManager->IHandleMouse( pfGameGUIMgr::kMouseUp, pMouseMsg->GetXPos(), pMouseMsg->GetYPos(), fModifiers, &fCurrentCursor );
if ((handled) || (fButtonState & kLeftButtonDown)) // even if we didn't handle the mouse up, if we think the button is still down, we should clear our flag
fButtonState &= ~kLeftButtonDown;
}
else if( pMouseMsg->GetButton() == kLeftButtonDblClk )
handled = fGUIManager->IHandleMouse( pfGameGUIMgr::kMouseDblClick, pMouseMsg->GetXPos(), pMouseMsg->GetYPos(), fModifiers, &fCurrentCursor );
else if( fButtonState & kLeftButtonDown )
handled = fGUIManager->IHandleMouse( pfGameGUIMgr::kMouseDrag, pMouseMsg->GetXPos(), pMouseMsg->GetYPos(), fModifiers, &fCurrentCursor );
else
handled = fGUIManager->IHandleMouse( pfGameGUIMgr::kMouseMove, pMouseMsg->GetXPos(), pMouseMsg->GetYPos(), fModifiers, &fCurrentCursor );
fHaveInterestingCursor = handled;
return handled;
}
return false;
}
UInt32 pfGameUIInputInterface::GetCurrentCursorID( void ) const
{
if( fCurrentCursor == 0 )
{
if ( pfGameGUIMgr::GetInstance() )
return pfGameGUIMgr::GetInstance()->GetDefaultCursor();
else
return kCursorUp;
}
return fCurrentCursor;
}
hsScalar pfGameUIInputInterface::GetCurrentCursorOpacity( void ) const
{
if ( pfGameGUIMgr::GetInstance() )
return pfGameGUIMgr::GetInstance()->GetCursorOpacity();
else
return 1.f;
}
//////////////////////////////////////////////////////////////////////////////
//// Tag Stuff ///////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
extern pfGUITag gGUITags[]; // From pfGUITagDefs.cpp
//// GetDialogFromTag ////////////////////////////////////////////////////////
pfGUIDialogMod *pfGameGUIMgr::GetDialogFromTag( UInt32 tagID )
{
int i;
for( i = 0; i < fDialogs.GetCount(); i++ )
{
if( fDialogs[ i ]->GetTagID() == tagID )
return fDialogs[ i ];
}
return nil;
}
//// GetDialogFromString ////////////////////////////////////////////////////////
pfGUIDialogMod *pfGameGUIMgr::GetDialogFromString( const char *name )
{
int i;
for( i = 0; i < fDialogs.GetCount(); i++ )
{
if( stricmp( fDialogs[ i ]->GetName(), name ) == 0 )
return fDialogs[ i ];
}
return nil;
}
//// GetControlFromTag ///////////////////////////////////////////////////////
pfGUIControlMod *pfGameGUIMgr::GetControlFromTag( pfGUIDialogMod *dlg, UInt32 tagID )
{
return dlg->GetControlFromTag( tagID );
}
//// GetNumTags //////////////////////////////////////////////////////////////
UInt32 pfGameGUIMgr::GetNumTags( void )
{
UInt32 count;
for( count = 0; gGUITags[ count ].fID != 0; count++ );
return count;
}
//// GetTag //////////////////////////////////////////////////////////////////
pfGUITag *pfGameGUIMgr::GetTag( UInt32 tagIndex )
{
UInt32 count;
for( count = 0; gGUITags[ count ].fID != 0; count++ );
hsAssert( tagIndex < count, "Bad index to GetTag()" );
return &gGUITags[ tagIndex ];
}
UInt32 pfGameGUIMgr::GetHighestTag( void )
{
UInt32 i, id = 1;
for( i = 0; gGUITags[ i ].fID != 0; i++ )
{
if( id < gGUITags[ i ].fID )
id = gGUITags[ i ].fID;
}
return id;
}
void pfGameGUIMgr::SetAspectRatio(hsScalar aspectratio)
{
hsScalar oldAspectRatio = fAspectRatio;
// don't allow the aspectratio below 4:3
hsScalar fourThree = 4.0f/3.0f;
fAspectRatio = aspectratio < fourThree ? fourThree : aspectratio;
if (fAspectRatio != oldAspectRatio)
{
// need to tell dialogs to update
int i;
for (i = 0; i < fDialogs.GetCount(); i++)
{
if (fDialogs[i])
fDialogs[i]->UpdateAspectRatio();
}
}
}

View File

@ -0,0 +1,237 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGameGUIMgr Header //
// A.K.A. "Ooh, we get a GUI!" //
// //
//// Description /////////////////////////////////////////////////////////////
// //
// The in-game GUI manager. Handles reading, creation, and input for //
// dialog boxes at runtime. //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _pfGameGUIMgr_h
#define _pfGameGUIMgr_h
#include "hsTypes.h"
#include "hsTemplates.h"
#include "../pnInputCore/plKeyDef.h"
#include "../pnKeyedObject/hsKeyedObject.h"
#include <vector>
class plPipeline;
class plMessage;
class pfGUIDialogMod;
class pfGUIControlMod;
class pfGameUIInputInterface;
class plPostEffectMod;
//// Tag Definitions /////////////////////////////////////////////////////////
// Each dialog/control gets an optional tag ID number. This is the link
// between MAX and C++. You attach a Tag component to a control or dialog
// in MAX and assign it an ID (supplied by a list of konstants that are
// hard-coded). Then, in code, you ask the gameGUIMgr for the dialog (or
// control) with that ID, and pop, you get it back. Then you run with it.
//
// Easy, huh?
class pfGUITag
{
public:
UInt32 fID;
char fName[ 128 ];
};
//
// This class just holds a name and the key to set the receiver to
// after the dialog gets loaded.
class pfDialogNameSetKey
{
private:
char *fName;
plKey fKey;
public:
pfDialogNameSetKey(const char *name, plKey key) { fName = hsStrcpy(name); fKey=key; }
~pfDialogNameSetKey() { delete [] fName; }
const char *GetName() { return fName; }
plKey GetKey() { return fKey; }
};
//// Manager Class Definition ////////////////////////////////////////////////
class pfGUIPopUpMenu;
class pfGameGUIMgr : public hsKeyedObject
{
friend class pfGameUIInputInterface;
public:
enum EventType
{
kMouseDown,
kMouseUp,
kMouseMove,
kMouseDrag,
kKeyDown,
kKeyUp,
kKeyRepeat,
kMouseDblClick
};
enum
{
kNoModifiers = 0,
kShiftDown = 0x01,
kCtrlDown = 0x02,
kCapsDown = 0x04
};
private:
static pfGameGUIMgr *fInstance;
protected:
hsTArray<pfGUIDialogMod *> fDialogs;
pfGUIDialogMod *fActiveDialogs;
// These two lists help us manage when dialogs get told to load or unload versus when they actually *do*
hsTArray<pfDialogNameSetKey *> fDlgsPendingLoad;
hsTArray<pfDialogNameSetKey *> fDlgsPendingUnload;
hsBool fActivated;
UInt32 fActiveDlgCount;
pfGameUIInputInterface *fInputConfig;
UInt32 fInputCtlIndex;
UInt32 fDefaultCursor;
hsScalar fCursorOpacity;
hsScalar fAspectRatio;
// This is an array of the dialogs (by name) that need their
// receiver key set once they are loaded.
// This array shouldn't get more than one entry... but
// it could be more....
// LoadDialog adds an entry and MsgReceive removes it
hsTArray<pfDialogNameSetKey *> fDialogToSetKeyOf;
void ILoadDialog( const char *name );
void IShowDialog( const char *name );
void IHideDialog( const char *name );
void IAddDlgToList( hsKeyedObject *obj );
void IRemoveDlgFromList( hsKeyedObject *obj );
void IActivateGUI( hsBool activate );
hsBool IHandleMouse( EventType event, hsScalar mouseX, hsScalar mouseY, UInt8 modifiers, UInt32 *desiredCursor );
hsBool IHandleKeyEvt( EventType event, plKeyDef key, UInt8 modifiers );
hsBool IHandleKeyPress( char key, UInt8 modifiers );
hsBool IModalBlocking( void );
pfGUIDialogMod *IGetTopModal( void ) const;
public:
enum
{
kDlgModRef = 0
};
pfGameGUIMgr();
~pfGameGUIMgr();
CLASSNAME_REGISTER( pfGameGUIMgr );
GETINTERFACE_ANY( pfGameGUIMgr, hsKeyedObject );
void Draw( plPipeline *p );
hsBool Init( void );
virtual hsBool MsgReceive( plMessage* pMsg );
void LoadDialog( const char *name, plKey recvrKey=nil, const char *ageName = nil ); // AgeName = nil defaults to "GUI"
void ShowDialog( const char *name ) { IShowDialog(name); }
void HideDialog( const char *name ) { IHideDialog(name); }
void UnloadDialog( const char *name );
void UnloadDialog( pfGUIDialogMod *dlg );
void ShowDialog( pfGUIDialogMod *dlg, bool resetClickables=true );
void HideDialog( pfGUIDialogMod *dlg );
hsBool IsDialogLoaded( const char *name );
pfGUIDialogMod *GetDialogFromString( const char *name );
void SetDialogToNotify(const char *name, plKey recvrKey);
void SetDialogToNotify(pfGUIDialogMod *dlg, plKey recvrKey);
void SetDefaultCursor(UInt32 defaultCursor) { fDefaultCursor = defaultCursor; }
UInt32 GetDefaultCursor() { return fDefaultCursor; }
void SetCursorOpacity(hsScalar opacity) { fCursorOpacity = opacity; }
hsScalar GetCursorOpacity() { return fCursorOpacity; }
pfGUIPopUpMenu *FindPopUpMenu( const char *name );
std::vector<plPostEffectMod*> GetDlgRenderMods( void ) const;
hsBool IsModalBlocking( void ) {return IModalBlocking();}
// Tag ID stuff
pfGUIDialogMod *GetDialogFromTag( UInt32 tagID );
pfGUIControlMod *GetControlFromTag( pfGUIDialogMod *dlg, UInt32 tagID );
static UInt32 GetNumTags( void );
static pfGUITag *GetTag( UInt32 tagIndex );
static UInt32 GetHighestTag( void );
void SetAspectRatio(hsScalar aspectratio);
hsScalar GetAspectRatio() { return fAspectRatio; }
static pfGameGUIMgr *GetInstance( void ) { return fInstance; }
};
#endif //_pfGameGUIMgr_h

View File

@ -0,0 +1,93 @@
/*==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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
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==*/
#ifndef _pfGameGUIMgrCreatable_inc
#define _pfGameGUIMgrCreatable_inc
#include "../pnFactory/plCreator.h"
#include "pfGameGUIMgr.h"
REGISTER_CREATABLE( pfGameGUIMgr );
#include "pfGUIDialogMod.h"
#include "pfGUIControlMod.h"
#include "pfGUIButtonMod.h"
#include "pfGUIDraggableMod.h"
#include "pfGUIListBoxMod.h"
#include "pfGUITextBoxMod.h"
#include "pfGUIEditBoxMod.h"
#include "pfGUIUpDownPairMod.h"
#include "pfGUIValueCtrl.h"
#include "pfGUIKnobCtrl.h"
#include "pfGUIDragBarCtrl.h"
#include "pfGUICheckBoxCtrl.h"
#include "pfGUIRadioGroupCtrl.h"
#include "pfGUIDynDisplayCtrl.h"
#include "pfGUIMultiLineEditCtrl.h"
#include "pfGUIProgressCtrl.h"
#include "pfGUIClickMapCtrl.h"
#include "pfGUIPopUpMenu.h"
#include "pfGUIMenuItem.h"
REGISTER_CREATABLE( pfGUIDialogMod );
REGISTER_NONCREATABLE( pfGUIControlMod );
REGISTER_CREATABLE( pfGUIButtonMod );
REGISTER_CREATABLE( pfGUIDraggableMod );
REGISTER_CREATABLE( pfGUIListBoxMod );
REGISTER_CREATABLE( pfGUITextBoxMod );
REGISTER_CREATABLE( pfGUIEditBoxMod );
REGISTER_NONCREATABLE( pfGUIValueCtrl );
REGISTER_CREATABLE( pfGUIUpDownPairMod );
REGISTER_CREATABLE( pfGUIKnobCtrl );
REGISTER_CREATABLE( pfGUIDragBarCtrl );
REGISTER_CREATABLE( pfGUICheckBoxCtrl );
REGISTER_CREATABLE( pfGUIRadioGroupCtrl );
REGISTER_CREATABLE( pfGUIDynDisplayCtrl );
REGISTER_CREATABLE( pfGUIMultiLineEditCtrl );
REGISTER_CREATABLE( pfGUIProgressCtrl );
REGISTER_CREATABLE( pfGUIClickMapCtrl );
REGISTER_CREATABLE( pfGUIPopUpMenu );
REGISTER_CREATABLE( pfGUIMenuItem );
REGISTER_CREATABLE( pfGUISkin );
#endif // _pfGameGUIMgrCreatable_inc