You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
8.8 KiB

/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plInputInterface.cpp - A single layer on the input interface stack //
// //
//// History /////////////////////////////////////////////////////////////////
// //
// 2.20.02 mcn - Created. //
// //
//// Note on GetPriorityLevel() //////////////////////////////////////////////
// //
// The inputInterfaceMgr uses GetPriorityLevel() to place each interface //
// into the stack relative to the other interfaces. Current priority //
// levels are: //
// Console - 100 //
// GUI system - 75 //
// Avatar input - 50 //
// Scene interaction - 25 //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef _plInputInterface_h
#define _plInputInterface_h
#include "hsRefCnt.h"
#include "hsTemplates.h"
#include "hsBitVector.h"
// Needed for UNIX Build
// only windows will let you predeclare an enum
#include "pnInputCore/plKeyDef.h"
#include "pnInputCore/plControlEventCodes.h"
//// Class Definition ////////////////////////////////////////////////////////
class hsStream;
class hsResMgr;
class plInputEventMsg;
class plInputInterfaceMgr;
class plMessage;
class plKeyMap;
class plCtrlCmd;
class plKeyBinding;
class plInputInterface : public hsRefCnt
{
friend class plInputInterfaceMgr;
protected:
enum Priorities
{
kConsolePriority = 100,
kGUISystemPriority = 75,
kDebugCmdPrioity = 60,
kSceneInteractionPriority = 50,
kTelescopeInputPriority = 26,
kAvatarInputPriority = 25,
};
plInputInterfaceMgr *fManager;
plKeyMap *fControlMap;
hsTArray<plCtrlCmd *> *fMessageQueue;
hsBitVector fKeyControlFlags;
hsBitVector fKeyControlsFrom2ndKeyFlags;
hsBitVector fDisabledControls;
hsBool fEnabled;
void ISetMessageQueue( hsTArray<plCtrlCmd *> *queue ) { fMessageQueue = queue; }
plKeyMap *IGetControlMap( void ) const { return fControlMap; }
hsBool IOwnsControlCode( ControlEventCode code );
hsBool IVerifyShiftKey( plKeyDef key, int index );
hsBool IHasKeyControlFlag(int f) const { return fKeyControlFlags.IsBitSet(f); }
void ISetKeyControlFlag(int f) { fKeyControlFlags.SetBit(f); }
void IClearKeyControlFlag(int which) { fKeyControlFlags.ClearBit( which ); }
void IDisableControl(int which) { fDisabledControls.SetBit(which); }
void IEnableControl(int which) { fDisabledControls.ClearBit(which); }
// The binding lost focus/priority. Behave as though they released the key and send
// a deactivate message for the control code.
void IDeactivateBinding(const plKeyBinding *binding);
// Gets called once per IUpdate(), just like normal IEval()s
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ) { return false; }
// Override to handle special-cased control messages of your own (same as receiving them via a message, but if you process them, nobody else gets them). Return false if you don't handle it.
virtual hsBool IHandleCtrlCmd( plCtrlCmd *cmd ) { return false; }
// Override to let the input interfaces control when a binding is truly active. If this function returns false,
// ProcessKeyBindings will ignore the keypress for the given control. This way, the interfaces can be selective
// about which bindings are active when. By default, always returns true, since there are very few and rare
// cases where you'd want to return false
virtual hsBool IControlCodeEnabled( ControlEventCode code );
// Some helpers for derived classes to avoid including the manager unnecessariliy
public:
plInputInterface();
virtual ~plInputInterface();
enum Cursors
{
kNullCursor = 0,
kCursorUp,
kCursorLeft,
kCursorRight,
kCursorDown,
kCursorPoised,
kCursorClicked,
kCursorUnClicked,
kCursorHidden,
kCursorOpen,
kCursorGrab,
kCursorArrow,
kCursor4WayDraggable,
kCursor4WayDragging,
kCursorUpDownDraggable,
kCursorUpDownDragging,
kCursorLeftRightDraggable,
kCursorLeftRightDragging,
kCursorOfferBook,
kCursorOfferBookHilite,
kCursorOfferBookClicked,
kCursorClickDisabled,
kCursorHand,
kCursorUpward,
};
virtual void Read( hsStream* s, hsResMgr* mgr );
virtual void Write( hsStream* s, hsResMgr* mgr );
// Returns the priority of this interface layer, based on the Priorities enum
virtual UInt32 GetPriorityLevel( void ) const = 0;
// Returns true if the message was handled, false if not and we want to pass it on to others in the stack
virtual hsBool InterpretInputEvent( plInputEventMsg *pMsg ) = 0;
// Returns the currently active mouse cursor for this layer, as defined in pnMessage/plCursorChangeMsg.h
virtual UInt32 GetCurrentCursorID( void ) const = 0;
// Returns the current opacity that this layer wants the cursor to be, from 0 (xparent) to 1 (opaque)
virtual hsScalar GetCurrentCursorOpacity( void ) const { return 1.f; }
// Returns true if this layer is wanting to change the mouse, false if it isn't interested
virtual hsBool HasInterestingCursorID( void ) const = 0;
// Gets called by the manager. If you want a message to come to you, set your manager as the destination
virtual hsBool MsgReceive( plMessage *msg ) { return false; }
// Any initialization that requires a pointer to the manager needs to be done on Init()/Shutdown()
virtual void Init( plInputInterfaceMgr *manager ) { fManager = manager; RestoreDefaultKeyMappings(); }
virtual void Shutdown( void ) {}
// Gets called when any of the key mappings are changed, so that the interface layer can refresh the ones its interested in
virtual void RefreshKeyMap( void ) {}
// Called when the interface manager is setting all key mappings to default
virtual void RestoreDefaultKeyMappings( void ) {}
// Called on each interface layer that gets missed when processing inputEvents in the manager (i.e. you either get this call or InterpretInputEvent)
virtual void MissedInputEvent( plInputEventMsg *pMsg ) {}
// Non-virtual, can't override--processes an inputEventMsg to see if we can handle it via a key binding (if so, InterpretInputEvent won't be called)
hsBool ProcessKeyBindings( plInputEventMsg *keyMsg );
void SetEnabled( hsBool e ) { fEnabled = e; }
hsBool IsEnabled( void ) const { return fEnabled; }
// clear all keys from map
virtual void ClearKeyMap();
// reset clickable state
virtual void ResetClickableState() {;}
};
#endif // _plInputInterface_h