mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-20 12:19:10 +00:00
Hoist MOULOpenSourceClientPlugin/Plasma20/* to top level
to match H'uru layout and make patching/cherry-picking easier.
This commit is contained in:
848
Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIDialogMod.cpp
Normal file
848
Sources/Plasma/FeatureLib/pfGameGUIMgr/pfGUIDialogMod.cpp
Normal 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user