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