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.
 
 
 
 
 

225 lines
7.3 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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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