summaryrefslogtreecommitdiff
path: root/public/panorama
diff options
context:
space:
mode:
Diffstat (limited to 'public/panorama')
-rw-r--r--public/panorama/controls/animatedimagestrip.h69
-rw-r--r--public/panorama/controls/button.h113
-rw-r--r--public/panorama/controls/carousel.h232
-rw-r--r--public/panorama/controls/contextmenu.h78
-rw-r--r--public/panorama/controls/dropdown.h137
-rw-r--r--public/panorama/controls/edgescroller.h63
-rw-r--r--public/panorama/controls/fileopendialog.h224
-rw-r--r--public/panorama/controls/grid.h189
-rw-r--r--public/panorama/controls/html.h768
-rw-r--r--public/panorama/controls/image.h121
-rw-r--r--public/panorama/controls/label.h232
-rw-r--r--public/panorama/controls/listsegmentview.h84
-rw-r--r--public/panorama/controls/mousescroll.h53
-rw-r--r--public/panorama/controls/movieplayer.h320
-rw-r--r--public/panorama/controls/panel2d.h1109
-rw-r--r--public/panorama/controls/panelhandle.h56
-rw-r--r--public/panorama/controls/panelptr.h153
-rw-r--r--public/panorama/controls/progressbar.h51
-rw-r--r--public/panorama/controls/slider.h123
-rw-r--r--public/panorama/controls/slideshow.h114
-rw-r--r--public/panorama/controls/source2/renderpanel.h45
-rw-r--r--public/panorama/controls/textentry.h361
-rw-r--r--public/panorama/controls/tooltip.h81
-rw-r--r--public/panorama/controls/verticalscrolllist.h38
-rw-r--r--public/panorama/controls/vumeter.h86
-rw-r--r--public/panorama/data/iimagesource.h93
-rw-r--r--public/panorama/data/imageloader.h229
-rw-r--r--public/panorama/data/panoramavideoplayer.h196
-rw-r--r--public/panorama/input/gamepadcodes.h109
-rw-r--r--public/panorama/input/iuiinput.h543
-rw-r--r--public/panorama/input/keycodes.h158
-rw-r--r--public/panorama/input/mousecodes.h29
-rw-r--r--public/panorama/input/mousecursors.h28
-rw-r--r--public/panorama/iuiengine.h746
-rw-r--r--public/panorama/iuifilesystem.h51
-rw-r--r--public/panorama/iuilayoutmanager.h64
-rw-r--r--public/panorama/iuipanel.h578
-rw-r--r--public/panorama/iuipanelclient.h192
-rw-r--r--public/panorama/iuipanelstyle.h242
-rw-r--r--public/panorama/iuirenderengine.h165
-rw-r--r--public/panorama/iuisoundsystem.h91
-rw-r--r--public/panorama/iuistylefactory.h52
-rw-r--r--public/panorama/iuiwindow.h205
-rw-r--r--public/panorama/layout/backgroundimage.h263
-rw-r--r--public/panorama/layout/csshelpers.h195
-rw-r--r--public/panorama/layout/fillbrush.h993
-rw-r--r--public/panorama/layout/panel2dfactory.h111
-rw-r--r--public/panorama/layout/stylefiletypes.h61
-rw-r--r--public/panorama/layout/stylesymbol.h73
-rw-r--r--public/panorama/layout/uilength.h147
-rw-r--r--public/panorama/localization/ilocalize.h406
-rw-r--r--public/panorama/panorama.h76
-rw-r--r--public/panorama/panoramacurves.h22
-rw-r--r--public/panorama/panoramacxx.h131
-rw-r--r--public/panorama/panoramasymbol.h56
-rw-r--r--public/panorama/panoramatypes.h594
-rw-r--r--public/panorama/renderer/styleproperties.h8025
-rw-r--r--public/panorama/source2/ipanoramaui.h62
-rw-r--r--public/panorama/text/iuitextlayout.h69
-rw-r--r--public/panorama/textinput/textinput.h109
-rw-r--r--public/panorama/textinput/textinput_daisywheel.h377
-rw-r--r--public/panorama/textinput/textinput_dualtouch.h228
-rw-r--r--public/panorama/textinput/textinput_fullscreen.h50
-rw-r--r--public/panorama/textinput/textinput_settings.h74
-rw-r--r--public/panorama/transformations.h246
-rw-r--r--public/panorama/uievent.h1793
-rw-r--r--public/panorama/uieventcodes.h18
-rw-r--r--public/panorama/uievents.h211
-rw-r--r--public/panorama/uifileresource.h87
-rw-r--r--public/panorama/uijsregistration.h724
-rw-r--r--public/panorama/uioverlaybuffersettype.h31
-rw-r--r--public/panorama/uipbmsgbase.h597
-rw-r--r--public/panorama/uischeduleddel.h44
-rw-r--r--public/panorama/uisettings.h50
-rw-r--r--public/panorama/uitoplevelwindow.h299
-rw-r--r--public/panorama/uitoplevelwindowopenvroverlay.h108
-rw-r--r--public/panorama/uitoplevelwindowoverlay.h177
-rw-r--r--public/panorama/uiwebapiclient.h70
-rw-r--r--public/panorama/vrevents.h28
79 files changed, 25276 insertions, 0 deletions
diff --git a/public/panorama/controls/animatedimagestrip.h b/public/panorama/controls/animatedimagestrip.h
new file mode 100644
index 0000000..77f8fa8
--- /dev/null
+++ b/public/panorama/controls/animatedimagestrip.h
@@ -0,0 +1,69 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef ANIMATED_IMAGE_STRIP_H
+#define ANIMATED_IMAGE_STRIP_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "image.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Animated Image Strip
+//
+// Takes an image that has multiple sub-frames and animates displaying them.
+// Accepts strips in either horizontal or vertical orientation.
+//-----------------------------------------------------------------------------
+class CAnimatedImageStrip : public CImagePanel
+{
+ DECLARE_PANEL2D( CAnimatedImageStrip, CImagePanel );
+
+public:
+ CAnimatedImageStrip( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CAnimatedImageStrip();
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+
+ virtual void Paint() OVERRIDE;
+
+ void StartAnimating();
+
+ void StopAnimating();
+ void StopAnimatingAtFrame( int nFrame );
+
+ int GetDefaultFrame() const { return m_nDefaultFrame; }
+ void SetDefaultFrame( int nFrame ) { m_nDefaultFrame = nFrame; }
+
+ float GetFrameTime() const { return m_flFrameTime; }
+ void SetFrameTime( float flFrameTime ) { m_flFrameTime = flFrameTime; }
+
+ void SetCurrentFrame( int nFrame );
+ int GetCurrentFrame() const { return m_nCurrentFrameIndex; }
+
+ int GetFrameCount();
+
+private:
+ void AdvanceFrame();
+ int GetFrameIndex( int nFrame );
+
+ bool EventPanelLoaded( const CPanelPtr< IUIPanel > &panelPtr );
+ bool EventAdvanceFrame();
+
+ int m_nDefaultFrame;
+ float m_flFrameTime;
+ int m_nCurrentFrameIndex;
+ int m_nStopAtFrameIndex;
+ bool m_bAnimating;
+ bool m_bCurrentFramePainted;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_BUTTON_H
diff --git a/public/panorama/controls/button.h b/public/panorama/controls/button.h
new file mode 100644
index 0000000..8710698
--- /dev/null
+++ b/public/panorama/controls/button.h
@@ -0,0 +1,113 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_BUTTON_H
+#define PANORAMA_BUTTON_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "label.h"
+
+namespace panorama
+{
+
+class CLabel;
+
+//-----------------------------------------------------------------------------
+// Purpose: Button
+//-----------------------------------------------------------------------------
+class CButton : public CPanel2D
+{
+ DECLARE_PANEL2D( CButton, CPanel2D );
+
+public:
+ CButton( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CButton();
+
+ // clone
+ virtual bool IsClonable() { return AreChildrenClonable(); }
+ virtual CPanel2D *Clone();
+
+ // events
+ bool EventActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+
+protected:
+ virtual void InitClonedPanel( CPanel2D *pPanel );
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: ToggleButton
+//-----------------------------------------------------------------------------
+class CToggleButton : public CButton
+{
+ DECLARE_PANEL2D( CToggleButton, CButton );
+
+public:
+ CToggleButton( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CToggleButton();
+
+ void SetSelected( bool bSelected );
+ void SetText( const char *pchText );
+ virtual bool OnKeyTyped( const KeyData_t &unichar );
+
+ // events
+ virtual bool EventActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ virtual const char *PchGetText() const { return m_pLabel ? m_pLabel->PchGetText() : ""; }
+
+protected:
+ virtual bool BSetProperties( const CUtlVector< ParsedPanelProperty_t > &vecProperties );
+
+ CPanel2D *m_pButton;
+ CLabel *m_pLabel;
+ CLabel::ETextType m_eTextType;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: RadioButton
+//-----------------------------------------------------------------------------
+class CRadioButton : public CButton
+{
+ DECLARE_PANEL2D( CRadioButton, CButton );
+
+public:
+ void SetSelected( bool bSelected );
+ void SetText( const char *pchText );
+ const char *GetGroup() { return m_sGroup.String(); }
+ void SetGroup( const char *pchGroup ) { m_sGroup = pchGroup; }
+
+ virtual bool BSetProperties( const CUtlVector< ParsedPanelProperty_t > &vecProperties );
+
+public:
+ CRadioButton( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CRadioButton();
+
+ // events:
+
+ // i have been activated
+ bool EventActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+
+ // the specified radio, member of the specified group, has been activated (broadcast)
+ bool EventOtherActivated( const CPanelPtr< IUIPanel > &pPanel, const char *szGroup );
+
+protected:
+ void FireSelectionEvent();
+
+ CPanel2D *m_pButton;
+ CLabel *m_pLabel;
+ CLabel::ETextType m_eTextType;
+ CUtlString m_sGroup;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_BUTTON_H
diff --git a/public/panorama/controls/carousel.h b/public/panorama/controls/carousel.h
new file mode 100644
index 0000000..58bbca6
--- /dev/null
+++ b/public/panorama/controls/carousel.h
@@ -0,0 +1,232 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef CAROUSEL_H
+#define CAROUSEL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "mathlib/mathlib.h"
+#include "mathlib/beziercurve.h"
+#include "panel2d.h"
+#include "panorama/controls/label.h"
+#include "panorama/controls/mousescroll.h"
+
+namespace panorama
+{
+
+DECLARE_PANORAMA_EVENT0( ResetCarouselMouseWheelCounts );
+DECLARE_PANORAMA_EVENT1( SetCarouselSelectedChild, CPanelPtr<CPanel2D> );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Button
+//-----------------------------------------------------------------------------
+class CCarousel : public CPanel2D
+{
+ DECLARE_PANEL2D( CCarousel, CPanel2D );
+
+public:
+ CCarousel( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CCarousel();
+
+ enum EFocusType
+ {
+ k_EFocusTypeLeft,
+ k_EFocusTypeEdge,
+ k_EFocusTypeCenter
+ };
+
+ void SetTitleText( const char *pchTitle );
+ void SetTitleVisible( bool bVisible );
+ void SetWrap( bool bWrap );
+ void SetFocusType( EFocusType eType );
+ void SetOffset( CUILength len );
+ void DrawFocusFrame( bool bDraw );
+ void DeleteChildren();
+
+ bool SetFocusToIndex( int iFocus );
+ int GetFocusIndex() const { return GetChildIndex( m_pFocusedChild.Get() ); }
+ CPanel2D *GetFocusChild() const { return m_pFocusedChild.Get(); }
+
+ // Sets the child that will get focus when the carousel has focus. Remembered between focus calls
+ void SetSelectedChild( CPanel2D *pPanel );
+
+ // Sets the panel for which focus state is checked when applying focus offset.
+ void SetFocusOffsetPanel( CPanel2D *pPanel ) { m_ptrPanelFocusOffset = pPanel; }
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+ virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties );
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ virtual void Paint();
+
+ virtual bool OnMoveRight( int nRepeats );
+ virtual bool OnMoveLeft( int nRepeats );
+ virtual bool OnTabForward( int nRepeats ) { return OnMoveRight( nRepeats ); }
+ virtual bool OnTabBackward( int nRepeats ) { return OnMoveLeft( nRepeats ); }
+ virtual bool OnMouseWheel( const panorama::MouseData_t &code );
+ virtual void OnStylesChanged();
+
+ virtual void OnUIScaleFactorChanged( float flScaleFactor ) OVERRIDE;
+
+ virtual bool BRequiresContentClipLayer() OVERRIDE { return true; }
+
+ virtual void OnInitializedFromLayout();
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName );
+#endif
+
+protected:
+
+ virtual bool OnSetFocusToNextPanel( int nRepeats, EFocusMoveDirection moveType, bool bAllowWrap, float flTabIndexCurrent, float flXPosCurrent, float flYPosCurrent, float flXStart, float fYStart ) OVERRIDE
+ {
+ if ( m_bWrap )
+ {
+ switch( moveType )
+ {
+ case k_ENextInTabOrder:
+ case k_ENextByXPosition:
+ return OnMoveRight( nRepeats );
+ case k_EPrevInTabOrder:
+ case k_EPrevByXPosition:
+ return OnMoveLeft( nRepeats );
+ default:
+ break;
+ }
+ }
+ else
+ {
+ int iFocusChild = GetChildIndex( m_pFocusedChild.Get() );
+ switch( moveType )
+ {
+ case k_ENextInTabOrder:
+ case k_ENextByXPosition:
+ if ( iFocusChild < GetChildCount() - 1 )
+ {
+ return OnMoveRight( nRepeats );
+ }
+ break;
+ case k_EPrevInTabOrder:
+ case k_EPrevByXPosition:
+ if ( iFocusChild > 0 )
+ {
+ return OnMoveLeft( nRepeats );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ // child management
+ virtual void OnBeforeChildrenChanged();
+ virtual void OnCallBeforeStyleAndLayout() { UpdateFocusAndDirtyChildStyles(); }
+
+private:
+ enum EFocusEdge
+ {
+ k_EFocusEdgeLeft,
+ k_EFocusEdgeRight
+ };
+
+ // event handlers
+ bool EventInputFocusSet( const CPanelPtr< IUIPanel > &ptrPanel );
+ bool EventInputFocusLost( const CPanelPtr< IUIPanel > &ptrPanel );
+ bool OnResetMouseWheelCounts();
+ bool EventCarouselMouseScroll( const CPanelPtr< IUIPanel > &ptrPanel, int cRepeat );
+ bool EventWindowCursorShown( IUIWindow *pWindow );
+ bool EventWindowCursorHidden( IUIWindow *pWindow );
+
+ // owned panels
+ CLabel *CreateTitleLabel();
+
+ // focus
+ bool BSetFocusToChild( CPanel2D *pPanel );
+ void MarkFocusDirty();
+ bool UpdateFocusAndDirtyChildStyles();
+
+ // helpers
+ int GetPreviousWrapPanel( int i );
+ int GetNextWrapPanel( int i );
+ float GetFinalChildWidth( CPanel2D *pChild, float flContainerHeight );
+ void GetFinalChildDimensions( float *pflWidth, float *pflHeight, CPanel2D *pChild, float flContainerHeight );
+ int CalcIndexDistanceBetweenPanels( int iLHS, int iRHS );
+ int GetNextPanelInLayout( int iStart );
+ int GetPreviousPanelInLayout( int iStart );
+ void AddCarouselStyle( CPanel2D *pChild, int iChild, int iCurrentFocus );
+ void RemoveCarouselStyle( CPanel2D *pChild, int iChild, int iCurrentFocus );
+ void RegisterForCursorChanges();
+ void UnregisterForCursorChanges();
+
+ // configured offets
+ void GetPanelOffsets( CUILength *plenX, CUILength *plenY, CUILength *plenZ, int nDistanceFromFocus, float flWidth, float flHeight );
+ CUILength GetPanelOffset( int nDistanceFromFocus, bool bUseFocus, const CUtlVector< CUILength > &vecOffsets, const CUtlVector< CUILength > &vecFocusOffsets );
+
+ // layout related
+ void GetLayoutStart( int iFocusChild, float *pflOffset, float flLeft, float flCarouselOffset, const float flContainerWidth, const float flContainerHeight );
+ void LayoutChildPanels( int iFocusChild, float flOffset, float flLeft, float flRight, const float flContainerWidth, const float flContainerHeight, const CUtlVector< CPanel2D* > &vecNewChildren );
+ bool BPositionPanelRight( int iPanel, int nDistanceFromFocus, float *pflOffset, float flLeft, float flContainerWidth, float flContainerHeight, bool bCheckFits, const CUtlVector< CPanel2D* > &vecNewChildren );
+ bool BPositionPanelLeft( int iPanel, int nDistanceFromFocus, float *pflOffset, float flLeft, float flContainerWidth, float flContainerHeight, bool bCheckFits, const CUtlVector< CPanel2D* > &vecNewChildren );
+ void LayoutMouseScrollRegions( float flFinalWidth, float flFinalHeight );
+
+ struct DirtyChildStyles_t
+ {
+ int m_iOriginalFocus;
+ CUtlVector< CPanel2D* > m_vecPanels;
+ };
+ DirtyChildStyles_t *m_pDirtyChildStyles;
+
+
+ CLabel *m_pTitleLabel;
+ CMouseScrollRegion *m_pLeftMouseScrollRegion;
+ CMouseScrollRegion *m_pRightMouseScrollRegion;
+ CPanelPtr< CPanel2D > m_pFocusedChild;
+
+ EFocusType m_eFocusType;
+ bool m_bWrap;
+ CUILength m_lenOffset;
+ bool m_bIncludeScale2d;
+
+ // for edge focus
+ EFocusEdge m_eLastFocusEdge;
+ int m_iFocusLastEdge;
+
+ struct ChildOffsets_t
+ {
+ CUtlVector< CUILength > x;
+ CUtlVector< CUILength > y;
+ CUtlVector< CUILength > z;
+ };
+ ChildOffsets_t m_childOffsets;
+ ChildOffsets_t m_childOffsetsFocus;
+ bool m_bFlowingLayout;
+ bool m_bHadFocus;
+
+ double m_flLastMouseWheel;
+ uint32 m_unMouseWheelCount;
+
+ double m_flLastMove;
+ bool m_bDelayedMovePosted;
+ bool m_bRegisteredForCursorChanges;
+
+ bool m_bShuffleIntoView;
+
+ int32 m_nPanelsVisible;
+
+ CPanelPtr< CPanel2D > m_ptrPanelFocusOffset;
+};
+
+
+} // namespace panorama
+
+#endif // CAROUSEL_H
diff --git a/public/panorama/controls/contextmenu.h b/public/panorama/controls/contextmenu.h
new file mode 100644
index 0000000..bbb5451
--- /dev/null
+++ b/public/panorama/controls/contextmenu.h
@@ -0,0 +1,78 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef CONTEXTMENU_H
+#define CONTEXTMENU_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/controls/panel2d.h"
+
+DECLARE_PANEL_EVENT1( ContextMenuEvent, const char * )
+DECLARE_PANEL_EVENT1( ContextMenuEventDirect, panorama::IUIEvent * );
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper class to derive from for creating context menus
+//-----------------------------------------------------------------------------
+class CContextMenu : public panorama::CPanel2D
+{
+ DECLARE_PANEL2D( CContextMenu, panorama::CPanel2D );
+
+public:
+ CContextMenu( CPanel2D *pParent, const char *pchName, CPanel2D *pEventParent );
+ CContextMenu( IUIWindow *pParent, const char *pchName, CPanel2D *pEventParent );
+ virtual ~CContextMenu();
+ virtual bool OnClick( IUIPanel *pPanel, const panorama::MouseData_t &code );
+
+ void SetMenuTarget( const CPanelPtr< IUIPanel >& targetPanelPtr );
+
+ void CalculatePosition() { m_bReposition = true; InvalidateSizeAndPosition(); }
+
+protected:
+ CPanel2D *GetEventParent() { return m_pEventParent; }
+
+private:
+ void Initialize( CPanel2D *pEventParent );
+
+ void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+
+ bool OnFireEvent( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel, const char *pchEventText );
+ bool OnFireEvent( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel, IUIEvent *pEvent );
+ bool OnCancelled( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, panorama::EPanelEventSource_t eSource );
+
+ CPanel2D *m_pEventParent;
+ CPanelPtr< IUIPanel > m_pMenuTarget;
+ double m_flCreateTime;
+ bool m_bReposition;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper class for simple context menus that doesn't require derivation
+//-----------------------------------------------------------------------------
+class CSimpleContextMenu : public panorama::CContextMenu
+{
+ DECLARE_PANEL2D( CSimpleContextMenu, panorama::CContextMenu );
+
+public:
+ CSimpleContextMenu( CPanel2D *pParent, const char *pchName, CPanel2D *pEventParent );
+ CSimpleContextMenu( IUIWindow *pParent, const char *pchName, CPanel2D *pEventParent );
+ virtual ~CSimpleContextMenu();
+
+ void AddMenuItem( const char *pchLabelText, const char *pchEventText );
+ void AddMenuItemEvent( const char *pchLabel, IUIEvent *pEvent );
+
+private:
+
+};
+
+} // namespace panorama
+
+#endif // CONTEXTMENU_H \ No newline at end of file
diff --git a/public/panorama/controls/dropdown.h b/public/panorama/controls/dropdown.h
new file mode 100644
index 0000000..f756bd5
--- /dev/null
+++ b/public/panorama/controls/dropdown.h
@@ -0,0 +1,137 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_DROPDOWN_H
+#define PANORAMA_DROPDOWN_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT0( DropDownSelectionChanged );
+DECLARE_PANORAMA_EVENT2( DropDownMenuClosed, bool, CPanelPtr< CPanel2D > );
+
+class CDropDownMenu;
+
+//-----------------------------------------------------------------------------
+// Purpose: Drop Down Control
+//-----------------------------------------------------------------------------
+class CDropDown : public CPanel2D
+{
+ DECLARE_PANEL2D( CDropDown, CPanel2D );
+
+public:
+ CDropDown( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CDropDown();
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ void AddOption( CPanel2D *pPanel );
+ bool HasOption( const char *pchID );
+ void RemoveOption( const char *pchID );
+ void RemoveAllOptions();
+
+ void FindOptionIDsByClass( const char *pchClassName, CUtlVector< CUtlString > &vecIDsOut );
+ void SortOptions( int( __cdecl *pfnCompare )(const ClientPanelPtr_t *, const ClientPanelPtr_t *) );
+
+ CPanel2D *GetSelected() { return m_pSelected.Get(); }
+ void SetSelected( const char *pchID, bool bNotify );
+ void SetSelected( const char *pchID ) { return SetSelected( pchID, true ); }
+ void SetDefault( const char *pchID ) { m_strDefaultSelection.Set( pchID ); }
+ void ResetToDefault( bool bNotify );
+
+ CPanel2D *AccessDropDownMenu() { return (CPanel2D*)m_pMenu.Get(); }
+
+ virtual bool OnMouseButtonDown( const MouseData_t &mouseData );
+ virtual bool OnClick( IUIPanel *pPanel, const MouseData_t &code );
+ virtual void OnResetToDefaultValue();
+
+ // Call if you know you've changed the contents of one of the option panels
+ void InvalidateOptions( bool bForceReload );
+
+ CPanel2D *FindDropDownMenuChild( const char *pchID );
+ virtual bool BIsClientPanelEvent( CPanoramaSymbol symProperty ) OVERRIDE;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+#endif
+
+protected:
+ bool EventPanelActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+ bool EventDropDownMenuClosed( bool bSelectionChanged, CPanelPtr< CPanel2D > pPanel );
+ bool EventResetToDefault( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel );
+
+ virtual void OnInitializedFromLayout();
+ void ShowMenu();
+ void UpdateSelectedChild( bool bSuppressChangedEvent, bool bInvalidateAlways = false );
+
+ virtual void OnStylesChanged() OVERRIDE;
+
+ CPanelPtr< CDropDownMenu > GetMenu() { return m_pMenu; }
+
+private:
+ CPanelPtr< CDropDownMenu >m_pMenu;
+ CPanelPtr<CPanel2D> m_pSelected;
+ bool m_bSuppressClick;
+
+ CUtlString m_strInitialSelection;
+ CUtlString m_strDefaultSelection;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Drop Down Menu (shown when activated)
+//-----------------------------------------------------------------------------
+class CDropDownMenu : public CPanel2D
+{
+ DECLARE_PANEL2D( CDropDownMenu, CPanel2D );
+
+public:
+ CDropDownMenu( CDropDown *pDropDown, const char * pchPanelID );
+ virtual ~CDropDownMenu();
+
+ void Show();
+ void Close() { Hide( false ); }
+
+ CPanel2D *GetSelectedChild();
+ void SetSelected( const char *pchID );
+ void AddOption( CPanel2D *pPanel );
+ bool HasOption( const char *pchID );
+ void RemoveOption( const char *pchID );
+ void RemoveAll();
+
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ virtual void OnResetToDefaultValue();
+ virtual IUIPanel *GetLocalizationParent() const { return m_pDropDown->UIPanel(); }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+#endif
+
+protected:
+ bool EventPanelActivated( const CPanelPtr< IUIPanel > &ptrPanel, EPanelEventSource_t eSource );
+ bool EventCancelled( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+ bool EventInputFocusTopLevelChanged( CPanelPtr< CPanel2D > ptrPanel );
+ bool EventResetToDefault( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel );
+ bool EventInputFocusSet( const panorama::CPanelPtr< IUIPanel > &ptrPanel );
+
+private:
+ void Hide( bool bSelectionChanged );
+
+ CDropDown *m_pDropDown;
+ CPanel2D *m_pSelectedChild;
+};
+
+
+} // namespace panorama
+
+#endif // PANORAMA_DROPDOWN_H
diff --git a/public/panorama/controls/edgescroller.h b/public/panorama/controls/edgescroller.h
new file mode 100644
index 0000000..46b820f
--- /dev/null
+++ b/public/panorama/controls/edgescroller.h
@@ -0,0 +1,63 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef EDGE_SCROLLER_H
+#define EDGE_SCROLLER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/controls/panel2d.h"
+
+namespace panorama
+{
+
+class CEdgeScrollBar;
+class CUIEdgeScrollBar;
+class CButton;
+
+//-----------------------------------------------------------------------------
+// Purpose: Control that shows buttons on the edges to scroll rather than a normal scroll bar
+//-----------------------------------------------------------------------------
+class CEdgeScroller : public CPanel2D
+{
+ DECLARE_PANEL2D( CEdgeScroller, CPanel2D );
+
+public:
+ CEdgeScroller( CPanel2D *pParent, const char *pchID );
+ virtual ~CEdgeScroller();
+
+ // Callback to client panel to create a scrollbar
+ virtual IUIScrollBar *CreateNewVerticalScrollBar( float flInitialScrollPos ) OVERRIDE;
+ virtual IUIScrollBar *CreateNewHorizontalScrollBar( float flInitialScrollPos ) OVERRIDE;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Scrollbar that just shows buttons on the edges of the panel rather than an actual Scrollbar
+//-----------------------------------------------------------------------------
+class CEdgeScrollBar : public CBaseScrollBar
+{
+ DECLARE_PANEL2D( CEdgeScrollBar, CBaseScrollBar );
+
+public:
+ CEdgeScrollBar( CPanel2D *pParent, const char *pchID, bool bHorizontal );
+ virtual ~CEdgeScrollBar();
+
+protected:
+ virtual void UpdateLayout( bool bImmediateMove ) OVERRIDE;
+
+private:
+ bool m_bHorizontal;
+
+ CButton *m_pMinButton;
+ CButton *m_pMaxButton;
+};
+
+
+} // namespace panorama
+
+#endif // EDGE_SCROLLER_H
diff --git a/public/panorama/controls/fileopendialog.h b/public/panorama/controls/fileopendialog.h
new file mode 100644
index 0000000..79dc451
--- /dev/null
+++ b/public/panorama/controls/fileopendialog.h
@@ -0,0 +1,224 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_FILEOPENDIALOG_H
+#define PANORAMA_FILEOPENDIALOG_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "../uievent.h"
+#include "panorama/controls/button.h"
+
+namespace panorama
+{
+
+class CDropDown;
+class CLabel;
+class CTextEntry;
+class CFileOpenDialogEntry;
+
+DECLARE_PANORAMA_EVENT0( FileOpenDialogOpen );
+DECLARE_PANORAMA_EVENT0( FileOpenDialogCancel );
+DECLARE_PANORAMA_EVENT0( FileOpenDialogClose );
+DECLARE_PANORAMA_EVENT0( FileOpenDialogFolderUp );
+DECLARE_PANEL_EVENT1( FileOpenDialogSortByColumn, int );
+DECLARE_PANEL_EVENT1( FileOpenDialogSelectFile, uint32 );
+DECLARE_PANEL_EVENT1( FileOpenDialogDoubleClickFile, uint32 );
+DECLARE_PANORAMA_EVENT0( FileOpenDialogFullPathChanged );
+DECLARE_PANORAMA_EVENT0( FileOpenDialogFilterChanged );
+DECLARE_PANEL_EVENT1( FileOpenDialogFilesSelected, const char * );
+
+//-----------------------------------------------------------------------------
+// Purpose: generic open/save as file dialog, by default deletes itself on close
+//-----------------------------------------------------------------------------
+enum FileOpenDialogType_t
+{
+ FOD_SAVE = 0,
+ FOD_OPEN,
+ FOD_SELECT_DIRECTORY,
+ FOD_OPEN_MULTIPLE,
+};
+
+struct FileData_t
+{
+ CUtlString m_FileAttributes;
+ CUtlString m_CreationTime;
+ int64 m_nCreationTime;
+ CUtlString m_LastAccessTime;
+ CUtlString m_LastWriteTime;
+ int64 m_nLastWriteTime;
+ int64 m_nFileSize;
+ CUtlString m_FileName;
+ CUtlString m_FullPath;
+ CUtlString m_FileType;
+
+ bool m_bDirectory;
+};
+
+enum FileOpenDialogSorting_t
+{
+ FOD_SORT_NAME = 0,
+ FOD_SORT_SIZE,
+ FOD_SORT_TYPE,
+ FOD_SORT_DATE_MODIFIED
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: FileOpenDialog
+//-----------------------------------------------------------------------------
+class CFileOpenDialog : public CPanel2D
+{
+ DECLARE_PANEL2D( CFileOpenDialog, CPanel2D );
+
+public:
+ CFileOpenDialog( CPanel2D *parent, const char * pchPanelID, FileOpenDialogType_t type );
+ CFileOpenDialog( panorama::IUIWindow *pParent, const char * pchPanelID, FileOpenDialogType_t type );
+ virtual ~CFileOpenDialog();
+
+ // Set the directory the file search starts in
+ void SetStartDirectory(const char *dir);
+
+ // Sets the start directory context (and resets the start directory in the process)
+ // NOTE: If you specify a startdir context, then if you've already opened
+ // a file with that same start dir context before, it will start in the
+ // same directory it ended up in.
+ void SetStartDirectoryContext( const char *pContext, const char *pDefaultDir );
+
+ // Add filters for the drop down combo box
+ // The filter info, if specified, gets sent back to the app in the FileSelected message
+ void AddFilter( const char *filter, const char *filterName, bool bActive, const char *pFilterInfo = NULL );
+
+ // Get the directory this is currently in
+ void GetDirectory( char *buf, int bufSize );
+
+ // Get the last selected file name
+ void GetSelectedFileName( char *buf, int bufSize );
+
+ /*
+ messages sent:
+ "FileSelected"
+ "fullpath" // specifies the fullpath of the file
+ "filterinfo" // Returns the filter info associated with the active filter
+ "FileSelectionCancelled"
+ */
+
+ static bool FileNameWildCardMatch( char const *pchFileName, char const *pchPattern );
+
+ // event handlers
+ bool EventOpen();
+ bool EventCancel();
+ bool EventClose();
+ bool EventFolderUp();
+ bool EventColumnSortingChanged( const CPanelPtr< IUIPanel > &pPanel, int nColumn );
+ bool EventSelectFile( const CPanelPtr< IUIPanel > &pPanel, uint32 unModifiers );
+ bool EventDoubleClickFile( const CPanelPtr< IUIPanel > &pPanel, uint32 unModifiers );
+ bool EventFullPathChanged();
+ bool EventFilterChanged();
+
+protected:
+ void Init();
+
+ void PopulateFileList();
+ void PopulateDriveList();
+
+ void OnOpen();
+
+ // TODO: needs message? hooked up to buttons/rows?
+ void OnSelectFolder();
+ void OnMatchStringSelected();
+
+ // moves the directory structure up
+ void MoveUpFolder();
+
+ // validates that the current path is valid
+ void ValidatePath();
+
+private:
+
+ // Does the specified extension match something in the filter list?
+ bool ExtensionMatchesFilter( const char *pExt );
+
+ // Choose the first non *.* filter in the filter list
+ void ChooseExtension( char *pExt, int nBufLen );
+
+ // Saves the file to the start dir context
+ void SaveFileToStartDirContext( const char *pFullPath );
+
+ // Posts a file selected message
+ void PostFileSelectedMessage( const char *pFileName );
+
+ // Posts a multiple file selected message
+ void PostMultiFileSelectedMessage();
+
+ void BuildFileList();
+ void FilterFileList();
+ void SortEntries();
+
+ bool PassesFilter( FileData_t *fd );
+ int CountSubstringMatches();
+
+ void DeselectAllEntries();
+
+ CDropDown *m_pFullPathDropDown;
+ CPanel2D *m_pFileList; // TODO: custom spreadsheet style control?
+
+ CTextEntry *m_pFileNameTextEntry;
+
+ CDropDown *m_pFileTypeCombo;
+ CButton *m_pOpenButton;
+ CButton *m_pCancelButton;
+ CButton *m_pFolderUpButton;
+ CLabel *m_pFileTypeLabel;
+ CUtlVector<CPanel2D*> m_vecColumnHeaders;
+
+ KeyValues *m_pContextKeyValues;
+
+ FileOpenDialogSorting_t m_nSorting;
+ bool m_bSortingReversed;
+
+ char m_szLastPath[1024];
+ unsigned short m_nStartDirContext;
+ FileOpenDialogType_t m_DialogType;
+ bool m_bFileSelected : 1;
+
+ CUtlVector< FileData_t > m_Files;
+ CUtlVector< FileData_t * > m_Filtered;
+
+ CUtlVector< CFileOpenDialogEntry* > m_vecSelectedEntries;
+
+ CUtlString m_CurrentSubstringFilter;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: CFileOpenDialogEntry - single row in the dialog, represents one file
+//-----------------------------------------------------------------------------
+class CFileOpenDialogEntry : public CButton
+{
+ DECLARE_PANEL2D( CFileOpenDialogEntry, CButton );
+
+public:
+ CFileOpenDialogEntry( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CFileOpenDialogEntry();
+
+ void SetFileData( FileData_t *pFileData );
+ const FileData_t* GetFileData() const { return &m_FileData; }
+
+ virtual bool OnMouseButtonUp( const panorama::MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonDoubleClick( const panorama::MouseData_t &code ) OVERRIDE;
+
+ bool OnScrolledIntoView( const CPanelPtr< IUIPanel > &panelPtr );
+
+private:
+ FileData_t m_FileData;
+
+ bool m_bCreatedControls;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_FILEOPENDIALOG_H
diff --git a/public/panorama/controls/grid.h b/public/panorama/controls/grid.h
new file mode 100644
index 0000000..c5f0f63
--- /dev/null
+++ b/public/panorama/controls/grid.h
@@ -0,0 +1,189 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef GRID_H
+#define GRID_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "panorama/controls/label.h"
+#include "panorama/controls/mousescroll.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT0( ReadyPanelForDisplay )
+DECLARE_PANEL_EVENT0( PanelDoneWithDisplay )
+DECLARE_PANEL_EVENT0( GridMotionTimeout );
+DECLARE_PANEL_EVENT0( GridInFastMotion );
+DECLARE_PANEL_EVENT0( GridStoppingFastMotion );
+DECLARE_PANEL_EVENT0( GridPageLeft );
+DECLARE_PANEL_EVENT0( GridPageRight );
+DECLARE_PANEL_EVENT0( GridDirectionalMove );
+DECLARE_PANEL_EVENT1( ChildIndexSelected, int );
+
+//-----------------------------------------------------------------------------
+// Purpose: Button
+//-----------------------------------------------------------------------------
+class CGrid : public CPanel2D
+{
+ DECLARE_PANEL2D( CGrid, CPanel2D );
+
+public:
+ CGrid( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CGrid();
+
+ CPanel2D * AccessSelectedPanel() { return m_pFocusedChild.Get(); }
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ // Scroll the grid so the focused panel is in the top left corner
+ void MoveFocusToTopLeft();
+
+ // Scroll the grid all the way to the left regardless of what's
+ // focused.
+ void ScrollPanelToLeftEdge();
+
+ // Trigger fast motion style temporarily, do this if you are directly setting focus ahead a bunch
+ void TriggerFastMotion();
+ void BumpFastMotionTimeout();
+
+ void SetHorizontalCount( int nCount ) { SetHorizontalAndVerticalCount( nCount, m_nVerticalCount ); }
+ void SetVerticalCount( int nCount ) { SetHorizontalAndVerticalCount( m_nHorizontalCount, nCount ); }
+ int GetHorizontalCount() const { return m_nHorizontalCount; }
+ int GetVerticalCount() const { return m_nVerticalCount; }
+
+ void SetHorizontalFocusLimit( int nCount ) { m_nHorizontalFocusLimit = nCount; InvalidateSizeAndPosition(); }
+ int GetHorizontalFocusLimit() const { return m_nHorizontalFocusLimit; }
+
+ float GetScrollProgress() const { return m_flScrollProgress; }
+
+ virtual bool OnMoveUp( int nRepeats );
+ virtual bool OnMoveDown( int nRepeats );
+ virtual bool OnMoveRight( int nRepeats );
+ virtual bool OnMoveLeft( int nRepeats );
+ virtual bool OnTabForward( int nRepeats );
+ virtual bool OnTabBackward( int nRepeats );
+ virtual bool OnMouseWheel( const panorama::MouseData_t &code );
+ virtual bool OnGamePadDown( const panorama::GamePadData_t &code );
+ virtual bool OnKeyDown( const KeyData_t &code );
+
+ virtual bool BRequiresContentClipLayer() OVERRIDE { return true; }
+
+ virtual void Paint();
+ virtual bool OnSetFocusToNextPanel( int nRepeats, EFocusMoveDirection moveType, bool bAllowWrap, float flTabIndexCurrent, float flXPosCurrent, float flYPosCurrent, float flXStart, float fYStart ) OVERRIDE
+ {
+ switch( moveType )
+ {
+ case k_ENextInTabOrder:
+ if ( OnTabForward( nRepeats ) )
+ return true;
+ break;
+ case k_ENextByXPosition:
+ if ( OnMoveRight( nRepeats ) )
+ return true;
+ break;
+ case k_EPrevInTabOrder:
+ if ( OnTabBackward( nRepeats ) )
+ return true;
+ break;
+ case k_EPrevByXPosition:
+ if ( OnMoveLeft( nRepeats ) )
+ return true;
+ break;
+ case k_ENextByYPosition:
+ if ( OnMoveDown( nRepeats ) )
+ return true;
+ break;
+ case k_EPrevByYPosition:
+ if ( OnMoveUp( nRepeats ) )
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ void SetHorizontalAndVerticalCount( int nHorizontalCount, int nVerticalCount );
+
+ void SetIgnoreFastMotion( bool bValue ) { m_bIgnoreFastMotion = bValue; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+#endif
+
+protected:
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ virtual void OnBeforeChildrenChanged() { m_bForceRelayout = true; }
+
+ virtual void OnChildStylesChanged() OVERRIDE { m_bVecVisibleDirty = true; }
+ virtual void OnAfterChildrenChanged() OVERRIDE { m_bVecVisibleDirty = true; }
+private:
+
+ void UpdateVecVisible();
+ int GetVisibleChildCount();
+ CPanel2D *GetVisibleChild( int iVisibleIndex );
+
+ // event handlers
+ bool EventInputFocusSet( const CPanelPtr< IUIPanel > &ptrPanel );
+ bool EventInputFocusLost( const CPanelPtr< IUIPanel > &ptrPanel );
+ bool MotionTimeout( const CPanelPtr< IUIPanel > &ptrPanel );
+ bool OnMouseScroll( const CPanelPtr< IUIPanel > &ptrPanel, int cRepeat );
+ void LayoutMouseScrollRegions( float flFinalWidth, float flFinalHeight );
+ bool EventWindowCursorShown( IUIWindow *pWindow );
+ bool EventWindowCursorHidden( IUIWindow *pWindow );
+
+ void RegisterForCursorChanges();
+ void UnregisterForCursorChanges();
+
+ int GetFocusedChildVisibleIndex();
+ void UpdateChildPositions( bool bForceTopLeft = false );
+
+ bool m_bHadFocus;
+
+ CPanelPtr< CPanel2D > m_pFocusedChild;
+ CUtlVector< CPanelPtr<CPanel2D> > m_vecPanelsReadyForDisplay;
+
+ int m_nScrollOffset;
+
+ float m_flChildWidth;
+ float m_flChildHeight;
+ float m_flScaleOffset;
+
+ float m_flScrollProgress;
+
+ int m_nHorizontalCount;
+ int m_nVerticalCount;
+
+ // Override how far right you can move before all items must shift, should be smaller than m_nHorizontalCount
+ int m_nHorizontalFocusLimit;
+
+ double m_flLastMouseWheel;
+ bool m_bForceRelayout;
+
+ bool m_bIgnoreFastMotion;
+ double m_flStartedMotion;
+ double m_flLastMotion;
+ uint64 m_ulMotionSinceStart;
+ bool m_bFastMotionStarted;
+ bool m_bVecVisibleDirty;
+
+ CUtlVector< CPanel2D * > m_vecVisibleChildren;
+
+ panorama::CMouseScrollRegion *m_pLeftMouseScrollRegion;
+ panorama::CMouseScrollRegion *m_pRightMouseScrollRegion;
+
+};
+
+
+} // namespace panorama
+
+#endif // GRID_H
diff --git a/public/panorama/controls/html.h b/public/panorama/controls/html.h
new file mode 100644
index 0000000..b1b9902
--- /dev/null
+++ b/public/panorama/controls/html.h
@@ -0,0 +1,768 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_HTML_H
+#define PANORAMA_HTML_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "tier1/utlmap.h"
+#include "tier1/utlstring.h"
+#include "../uievent.h"
+#include "mathlib/beziercurve.h"
+#include "../textinput/textinput.h"
+
+#if !defined( SOURCE2_PANORAMA ) && !defined( PANORAMA_PUBLIC_STEAM_SDK )
+#include "html/ihtmlchrome.h"
+#include "tier1/shared_memory.h"
+#endif
+
+class CTexturePanel;
+namespace panorama
+{
+class CTextTooltip;
+class CHTML;
+class CFileOpenDialog;
+
+struct HtmlFormHasFocus_t
+{
+ HtmlFormHasFocus_t() :
+ m_bInput( false ),
+ m_bInputHasMultiplePeers( false ),
+ m_bUserInputThisPage( false ),
+ m_bFocusedElementChanged( true )
+ {
+ }
+ void Reset()
+ {
+ m_bInput = false;
+ m_bUserInputThisPage = false;
+ m_bInputHasMultiplePeers = false;
+ m_bFocusedElementChanged = true;
+ }
+
+ bool operator==(const HtmlFormHasFocus_t &rhs) const
+ {
+ return rhs.m_bInput == m_bInput &&
+ rhs.m_sName == m_sName &&
+ rhs.m_sSearchLabel == m_sSearchLabel &&
+ rhs.m_sInputType == m_sInputType;
+ }
+ bool m_bInput;
+ CUtlString m_sName;
+ CUtlString m_sSearchLabel;
+ bool m_bInputHasMultiplePeers;
+ bool m_bUserInputThisPage;
+ CUtlString m_sInputType;
+ bool m_bFocusedElementChanged;
+};
+
+DECLARE_PANEL_EVENT2( HTMLURLChanged, const char *, const char * )
+DECLARE_PANEL_EVENT1( HTMLLoadPage, const char * )
+DECLARE_PANEL_EVENT2( HTMLFinishRequest, const char *, const char * )
+DECLARE_PANEL_EVENT1( HTMLTitle, const char * )
+DECLARE_PANEL_EVENT1( HTMLStatusText, const char * )
+DECLARE_PANEL_EVENT2( HTMLJSAlert, const char *, bool * )
+DECLARE_PANEL_EVENT2( HTMLJSConfirm, const char *, bool * )
+DECLARE_PANEL_EVENT2( HMTLLinkAtPosition, const char *, bool )
+DECLARE_PANEL_EVENT4( HMTLThumbNailImage, int, CUtlBuffer *, uint32, uint32 )
+DECLARE_PANEL_EVENT1( HTMLOpenLinkInNewTab, const char * )
+DECLARE_PANEL_EVENT2( HTMLOpenPopupTab, CHTML *, const char * )
+DECLARE_PANEL_EVENT2( HTMLBackForwardState, bool, bool )
+DECLARE_PANEL_EVENT2( HTMLUpdatePageSize, int, int )
+DECLARE_PANEL_EVENT5( HTMLSecurityStatus, const char *, bool, bool, bool, const char * )
+DECLARE_PANEL_EVENT1( HTMLFullScreen, bool )
+DECLARE_PANEL_EVENT2( HTMLStartMousePanning, int, int )
+DECLARE_PANEL_EVENT0( HTMLStopMousePanning )
+DECLARE_PANEL_EVENT0( HTMLCloseWindow )
+DECLARE_PANEL_EVENT2( HTMLFormHasFocus, HtmlFormHasFocus_t, const char * /* URL */ )
+DECLARE_PANEL_EVENT2( HTMLScreenShotTaken, const char *, const char * )
+DECLARE_PANEL_EVENT1( HTMLFocusedNodeValue, const char * )
+DECLARE_PANEL_EVENT0( HTMLSteamRightPadMoving );
+DECLARE_PANEL_EVENT2( HTMLStartRequest, const char *, bool * );
+
+class CImagePanel;
+
+enum CursorCode
+{
+ eCursorNone,
+ eCursorArrow
+};
+
+class IUIDoubleBufferedTexture;
+class CTransform3D;
+extern const int k_nExtraScrollRoom; // max number of padding pixels to use if needed
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHTML : public CPanel2D, public ITextInputControl
+#if !defined( SOURCE2_PANORAMA ) && !defined( PANORAMA_PUBLIC_STEAM_SDK )
+ , public IHTMLResponses
+#endif
+{
+ DECLARE_PANEL2D( CHTML, CPanel2D );
+
+public:
+ CHTML( CPanel2D *parent, const char * pchPanelID, bool bPopup = false );
+ virtual ~CHTML();
+ void Shutdown();
+
+ // panel2d overrides
+ virtual void Paint();
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ virtual void OnStylesChanged();
+ virtual bool BRequiresContentClipLayer() OVERRIDE { return true; } // BUGBUG Alfred - fix ::Paint to scale u/v offsets rather than requiring a clipping
+
+ // simple browser management
+ void OpenURL(const char *);
+ void PostURL( const char *pchURL, const char *pchPostData );
+ void AddHeader( const char *pchHeader, const char *pchValue );
+ void StopLoading();
+ void Refresh();
+ void GoBack();
+ void GoForward();
+ bool BCanGoBack();
+ bool BCanGoForward();
+
+ // kb/mouse management
+ virtual bool OnKeyDown( const KeyData_t &code ) OVERRIDE;
+ virtual bool OnKeyUp( const KeyData_t & code ) OVERRIDE;
+ virtual bool OnKeyTyped( const KeyData_t &unichar ) OVERRIDE;
+ virtual bool OnGamePadDown( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadUp( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadAnalog( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonDown( const MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonUp( const MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonDoubleClick( const MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseWheel( const MouseData_t &code ) OVERRIDE;
+ virtual void OnMouseMove( float flMouseX, float flMouseY ) OVERRIDE;
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ // run input event processing for something that may not be a real input event, so don't bubble to parents, etc.
+ bool OnGamePadDownImpl( const GamePadData_t &code, bool *out_pbOptionalResult = nullptr );
+ bool OnGamePadAnalogImpl( const GamePadData_t &code, bool *out_pbOptionalResult = nullptr );
+
+ bool ProcessAnalogScroll( float fValueX, float fValueY, double fTimeDelta, float fDeadzoneValue );
+ bool ProcessAnalogZoom( float fValueX, float fValueY, double fTimeDelta, float fDeadzoneValue );
+ void ProcessRawScroll( bool bFingerDown );
+ void ProcessRawZoom( float fValueRaw );
+
+ // browser helpers
+ void Copy();
+ void Paste();
+ void RequestLinkUnderGamepad() { RequestLinkAtPosition( GetActualLayoutWidth()/2 - GetHScrollOffset(), GetActualLayoutHeight()/2 - GetVScrollOffset() ); }
+ void RequestLinkUnderMouse() { RequestLinkAtPosition( m_flCursorX - GetHScrollOffset(), m_flCursorY - GetVScrollOffset() ); }
+ void ZoomToElementUnderPanelCenter();
+ void ZoomToElementUnderMouse();
+ const char *PchLastLinkAtPosition() { return m_LinkAtPos.m_sURL; }
+ void RunJavascript( const char *pchScript );
+ void ViewSource();
+ void SetHorizontalScroll( int scroll );
+ void SetVerticalScroll( int scroll );
+ void OnHTMLCursorMove( float flMouseX, float flMouseY );
+
+ // finding text on the page
+ void Find( const char *pchSubStr );
+ void StopFind();
+ void FindNext();
+ void FindPrevious();
+
+ void SetFileDialogChoice( const char *pchFileName ); // callback if cef wanted us to pick a file
+
+ bool BAcceptMouseInput(); // returns true if the control is listening to mouse input right now, false if gamepad input mode is on
+ virtual bool BRequiresFocus() OVERRIDE { return true; }
+
+ bool BIgnoreMouseBackForwardButtons() { return m_bIgnoreMouseBackForwardButtons; }
+ void SetIgnoreMouseBackForwardButtons( bool bIgnore ) { m_bIgnoreMouseBackForwardButtons = bIgnore; }
+
+ const char *PchCurrentURL() { return m_sCurrentURL; } // the current URL the browser has loaded
+ const char *PchCurrentPageTitle() { return m_sHTMLTitle; } // the title of the currently loaded page
+
+ void SaveCurrentPageToJPEG( const char *pchFileName, int nWide, int nTall ); // save this current page to a jpeg
+
+ // results for JS alert popups
+ void DismissJSDialog( bool bRetVal );
+
+ static uint32 GetAndResetPaintCounter();
+
+ void ReleaseTextureMemory( bool bSuppressTextureLoads = false );
+ void RefreshTextureMemory();
+
+ void CaptureThumbNailImage( CPanel2D *pEventTarget, int iUserData );
+ void IncrementPageScale( float flScaleIncrement, bool bZoomFromOrigin = false );
+ void ExitFullScreen();
+ void ExecuteJavaScript( const char *pchScript );
+
+ // SSL/security state for the loaded html page
+ bool BIsSecure() const { return m_bIsSecure; }
+ bool BIsCertError() const { return m_bIsCertError; }
+ bool BIsEVCert() const { return m_bIsEVCert; }
+ const char *PchCertName() const { return m_sCertName; }
+
+ // if true don't allow the page to scroll beyond the page edges
+ void SetDontAllowOverScroll( bool bState );
+ void SetEmbeddedMode( bool bState );
+
+ void ZoomPageToFocusedElement( int nLeftOffset, int nTopOffset );
+
+ // ITextInputControl helpers
+ virtual int32 GetCursorOffset() const { return 0; }
+ virtual uint GetCharCount() const { return 0; }
+
+ virtual const char *PchGetText() const { return ""; }
+ virtual const wchar_t *PwchGetText() const { return L""; }
+
+ virtual void InsertCharacterAtCursor( const wchar_t &unichar );
+ virtual void InsertCharactersAtCursor( const wchar_t *pwch, size_t cwch )
+ {
+ for ( uint i = 0; i < cwch; i++ )
+ InsertCharacterAtCursor( pwch[i] );
+ }
+ bool BSupportsImmediateTextReturn() { return false; }
+ void RequestControlString() { RequestFocusedNodeValue(); }
+
+ virtual CPanel2D *GetAssociatedPanel() { return this; }
+
+ void PauseFlashVideoIfVisible();
+
+ void ResetScrollbarsAndClearOverflow();
+
+ void SetPopupChild(CHTML *pChild) { m_pPopupChild = pChild; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const char *pchName ) OVERRIDE;
+ static void ValidateStatics( CValidator &validator, const char *pchName );
+#endif
+
+ class CHTMLVerticalScrollBar : public CScrollBar
+ {
+ DECLARE_PANEL2D( CHTMLVerticalScrollBar, CScrollBar );
+
+ public:
+ CHTMLVerticalScrollBar( CPanel2D *parent, const char * pchPanelID ) : CScrollBar( parent, pchPanelID )
+ {
+ m_pScrollThumb->AddClass( "VerticalScrollThumb" );
+ }
+
+ void ScrollToMousePos()
+ {
+ float flHeight = GetActualLayoutHeight();
+ if ( flHeight > 0.00001f )
+ {
+ if ( m_bMouseWentDownOnThumb )
+ {
+ float flPercentDiff = (m_flMouseY - m_flMouseStartY) / flHeight;
+ float flPositionOffset = flPercentDiff * GetRangeSize();
+ float flPosition = m_flScrollStartPosition + flPositionOffset;
+ SetScrollWindowPosition( clamp( flPosition, 0.0f, GetRangeSize() - GetScrollWindowSize() ), true );
+ }
+ else
+ {
+ float flPercent = m_flMouseY / flHeight;
+ float flPos = GetRangeSize() * flPercent;
+ SetScrollWindowPosition( clamp( flPos, 0.0f, GetRangeSize() - GetScrollWindowSize() ), true );
+ }
+ }
+ }
+
+
+ virtual ~CHTMLVerticalScrollBar() {}
+
+ protected:
+ virtual void UpdateLayout( bool bImmediateMove )
+ {
+ CUILength zero;
+ zero.SetLength( 0.0f );
+
+ if ( GetRangeSize() < 0.001f )
+ return;
+
+ CUILength length;
+
+ float flXPosPercent = (GetScrollWindowPosition() - GetRangeMin()) / GetRangeSize();
+ length.SetPercent( flXPosPercent * 100.0f );
+ if ( bImmediateMove )
+ m_pScrollThumb->SetPositionWithoutTransition( zero, length, zero );
+ else
+ m_pScrollThumb->SetPosition( zero, length, zero );
+
+ float flWidthPercent = GetScrollWindowSize() / GetRangeSize();
+
+ length.SetPercent( flWidthPercent*100.0f );
+ m_pScrollThumb->AccessStyleDirty()->SetHeight( length );
+ length.SetPercent( 100.0f );
+ m_pScrollThumb->AccessStyleDirty()->SetWidth( length );
+
+ m_bLastMoveImmediate = bImmediateMove;
+ }
+ };
+
+ class CHTMLHorizontalScrollBar : public CScrollBar
+ {
+ DECLARE_PANEL2D( CHTMLHorizontalScrollBar, CScrollBar );
+
+ public:
+ CHTMLHorizontalScrollBar( CPanel2D *parent, const char * pchPanelID ) : CScrollBar( parent, pchPanelID )
+ {
+ m_pScrollThumb->AddClass( "HorizontalScrollThumb" );
+ }
+
+ void ScrollToMousePos()
+ {
+ float flWidth = GetActualLayoutWidth();
+ if ( flWidth > 0.00001f )
+ {
+ if ( m_bMouseWentDownOnThumb )
+ {
+ float flPercentDiff = (m_flMouseX - m_flMouseStartX) / flWidth;
+ float flPositionOffset = flPercentDiff * GetRangeSize();
+ float flPosition = m_flScrollStartPosition + flPositionOffset;
+ SetScrollWindowPosition( clamp( flPosition, 0.0f, GetRangeSize() - GetScrollWindowSize() ), true );
+ }
+ else
+ {
+ float flPercent = m_flMouseX / flWidth;
+ float flPos = GetRangeSize() * flPercent;
+ SetScrollWindowPosition( clamp( flPos, 0.0f, GetRangeSize() - GetScrollWindowSize() ), true );
+ }
+ }
+ }
+
+
+ virtual ~CHTMLHorizontalScrollBar() {}
+
+ protected:
+ virtual void UpdateLayout( bool bImmediateMove )
+ {
+ CUILength zero;
+ zero.SetLength( 0.0f );
+
+ if ( GetRangeSize() < 0.001f )
+ return;
+
+ CUILength length;
+
+ float flXPosPercent = (GetScrollWindowPosition() - GetRangeMin()) / GetRangeSize();
+ length.SetPercent( flXPosPercent * 100.0f );
+ if ( bImmediateMove )
+ m_pScrollThumb->SetPositionWithoutTransition( length, zero, zero );
+ else
+ m_pScrollThumb->SetPosition( length, zero, zero );
+
+ float flWidthPercent = GetScrollWindowSize() / GetRangeSize();
+
+ length.SetPercent( flWidthPercent*100.0f );
+ m_pScrollThumb->AccessStyleDirty()->SetWidth( length );
+ length.SetPercent( 100.0f );
+ m_pScrollThumb->AccessStyleDirty()->SetHeight( length );
+ m_bLastMoveImmediate = bImmediateMove;
+ }
+ };
+
+ enum EHTMLScrollDirection
+ {
+ kHTMLScrollDirection_Up,
+ kHTMLScrollDirection_Down,
+ kHTMLScrollDirection_Left,
+ kHTMLScrollDirection_Right
+ };
+
+ bool BCanScrollInDirection( EHTMLScrollDirection eDirection ) const;
+
+ static float GetScrollDeadzoneScale() { return s_fScrollDeadzoneScale; }
+
+protected:
+ // functions you can override to specialize html behavior
+ virtual void OnURLChanged( const char *url, const char *pchPostData, bool bIsRedirect );
+ virtual void OnFinishRequest(const char *url, const char *pageTitle);
+ virtual void OnPageLoaded( const char *url, const char *pageTitle, const CUtlMap < CUtlString, CUtlString > &headers );
+ virtual bool OnStartRequestInternal( const char *url, const char *target, const char *pchPostData, bool bIsRedirect );
+ virtual void ShowPopup();
+ virtual void HidePopup();
+ virtual bool OnOpenNewTab( const char *pchURL, bool bForeground );
+ virtual bool OnPopupHTMLWindow( const char *pchURL, int x, int y, int wide, int tall );
+ virtual void SetHTMLTitle( const char *pchTitle );
+ virtual void OnLoadingResource( const char *pchURL );
+ virtual void OnSetStatusText(const char *text);
+ virtual void OnSetCursor( CursorCode cursor );
+ virtual void OnFileLoadDialog( const char *pchTitle, const char *pchInitialFile );
+ virtual void OnShowToolTip( const char *pchText );
+ virtual void OnUpdateToolTip( const char *pchText );
+ virtual void OnHideToolTip();
+ virtual void OnSearchResults( int iActiveMatch, int nResults );
+
+ friend class ::CTexturePanel;
+ IUIDoubleBufferedTexture *m_pDoubleBufferedTexture;
+ IUIDoubleBufferedTexture *m_pDoubleBufferedTexturePending;
+ IUIDoubleBufferedTexture *m_pDoubleBufferedTextureComboBox;
+ int32 m_nTextureSerial; // serial number of the last texture we uploaded
+
+ void RequestFocusedNodeValue();
+ // if true then our html control overrides scrolling and scrollbars, if false we
+ // let the web control scroll itself
+ void SetManualHTMLScroll( bool bControlScroll ) { m_bControlPageScrolling = bControlScroll; }
+
+private:
+ typedef void (CHTML::* ScrollFunc_t)( float, bool );
+ bool ProcessAnalogScrollAxis( float fValue, float fDeadzoneValue, double fTimeDelta, ScrollFunc_t ScrollFunc );
+
+ // we used to create the virtual mouse in our constructor, but now we don't know enough information at
+ // construction time to know whether we want one (ie., if we're wrapped by CHTMLSimpleNavigationWrapper
+ // we disable touchpad navigation). Instead we just try to lazy-create one at first use.
+ void LazyCreateVirtualMouseIfNecessary();
+
+ // getters/setters for html cef object
+ void SetHTMLFocus();
+ void KillHTMLFocus();
+ int HorizontalScroll();
+ int VerticalScroll();
+ bool IsHorizontalScrollBarVisible();
+ bool IsVeritcalScrollBarVisible();
+ void RequestLinkAtPosition( int x, int y );
+ void GetCookiesForURL( const char *pchURL );
+ void UpdatePanoramaScrollBars();
+ bool BHandleKeyPressPageScroll() const;
+
+#if defined( SOURCE2_PANORAMA ) || defined( PANORAMA_PUBLIC_STEAM_SDK )
+ STEAM_CALLBACK( CHTML, OnLinkAtPositionResponse, HTML_LinkAtPosition_t, m_LinkAtPosRespose );
+
+ STEAM_CALLBACK( CHTML, OnHTMLNeedsPaint, HTML_NeedsPaint_t, m_HTML_NeedsPaint );
+ STEAM_CALLBACK( CHTML, OnHTMLStartRequest, HTML_StartRequest_t, m_HTML_StartRequest );
+ STEAM_CALLBACK( CHTML, OnHTMLCloseBrowser, HTML_CloseBrowser_t, m_HTML_CloseBrowser );
+ STEAM_CALLBACK( CHTML, OnHTMLURLChanged, HTML_URLChanged_t, m_HTML_URLChanged );
+ STEAM_CALLBACK( CHTML, OnHTMLFinishedRequest, HTML_FinishedRequest_t, m_HTML_FinishedRequest );
+ STEAM_CALLBACK( CHTML, OnHTMLOpenLinkInNewTab, HTML_OpenLinkInNewTab_t, m_HTML_OpenLinkInNewTab );
+ STEAM_CALLBACK( CHTML, OnHTMLChangedTitle, HTML_ChangedTitle_t, m_HTML_ChangedTitle );
+ STEAM_CALLBACK( CHTML, OnHTMLSearchResults, HTML_SearchResults_t, m_HTML_SearchResults );
+ STEAM_CALLBACK( CHTML, OnHTMLCanGoBackAndForward, HTML_CanGoBackAndForward_t, m_HTML_CanGoBackAndForward );
+ STEAM_CALLBACK( CHTML, OnHTMLHorizontalScroll, HTML_HorizontalScroll_t, m_HTML_HorizontalScroll );
+ STEAM_CALLBACK( CHTML, OnHTMLVerticalScroll, HTML_VerticalScroll_t, m_HTML_VerticalScroll );
+ STEAM_CALLBACK( CHTML, OnHTMLJSAlert, HTML_JSAlert_t, m_HTML_JSAlert );
+ STEAM_CALLBACK( CHTML, OnHTMLJSConfirm, HTML_JSConfirm_t, m_HTML_JSConfirm );
+ STEAM_CALLBACK( CHTML, OnHTMLFileOpenDialog, HTML_FileOpenDialog_t, m_HTML_FileOpenDialog );
+ STEAM_CALLBACK( CHTML, OnHTMLNewWindow, HTML_NewWindow_t, m_HTML_NewWindow );
+ STEAM_CALLBACK( CHTML, OnHTMLSetCursor, HTML_SetCursor_t, m_HTML_SetCursor );
+ STEAM_CALLBACK( CHTML, OnHTMLStatusText, HTML_StatusText_t, m_HTML_StatusText );
+ STEAM_CALLBACK( CHTML, OnHTMLShowToolTip, HTML_ShowToolTip_t, m_HTML_ShowToolTip );
+ STEAM_CALLBACK( CHTML, OnHTMLUpdateToolTip, HTML_UpdateToolTip_t, m_HTML_UpdateToolTip );
+ STEAM_CALLBACK( CHTML, OnHTMLHideToolTip, HTML_HideToolTip_t, m_HTML_HideToolTip );
+#else
+ // message handlers for ipc thread
+ void BrowserSetIndex( int idx ) { m_iBrowser = idx; SendPendingHTMLMessages(); }
+ int BrowserGetIndex() { return m_iBrowser; }
+ void BrowserReady( const CMsgBrowserReady *pCmd );
+ void BrowserSetSharedPaintBuffers( const CMsgSetSharedPaintBuffers *pCmd );
+ void BrowserNeedsPaint( const CMsgNeedsPaint *pCmd );
+ void BrowserStartRequest( const CMsgStartRequest *pCmd );
+ void BrowserURLChanged( const CMsgURLChanged *pCmd );
+ void BrowserLoadedRequest( const CMsgLoadedRequest *pCmd );
+ void BrowserFinishedRequest(const CMsgFinishedRequest *pCmd);
+ void BrowserPageSecurity( const CMsgPageSecurity *pCmd );
+ void BrowserShowPopup( const CMsgShowPopup *pCmd );
+ void BrowserHidePopup( const CMsgHidePopup *pCmd );
+ void BrowserOpenNewTab( const CMsgOpenNewTab *pCmd );
+ IHTMLResponses *BrowserPopupHTMLWindow( const CMsgPopupHTMLWindow *pCmd );
+ void BrowserSetHTMLTitle( const CMsgSetHTMLTitle *pCmd );
+ void BrowserLoadingResource( const CMsgLoadingResource *pCmd );
+ void BrowserStatusText( const CMsgStatusText *pCmd );
+ void BrowserSetCursor( const CMsgSetCursor *pCmd );
+ void BrowserFileLoadDialog( const CMsgFileLoadDialog *pCmd );
+ void BrowserShowToolTip( const CMsgShowToolTip *pCmd );
+ void BrowserUpdateToolTip( const CMsgUpdateToolTip *pCmd );
+ void BrowserHideToolTip( const CMsgHideToolTip *pCmd );
+ void BrowserSearchResults( const CMsgSearchResults *pCmd );
+ void BrowserClose( const CMsgClose *pCmd );
+ void BrowserHorizontalScrollBarSizeResponse( const CMsgHorizontalScrollBarSizeResponse *pCmd );
+ void BrowserVerticalScrollBarSizeResponse( const CMsgVerticalScrollBarSizeResponse *pCmd );
+ void BrowserGetZoomResponse( const CMsgGetZoomResponse *pCmd ) {}
+ void BrowserLinkAtPositionResponse( const CMsgLinkAtPositionResponse *pCmd );
+ void BrowserZoomToElementAtPositionResponse( const CMsgZoomToElementAtPositionResponse *pCmd );
+ void BrowserJSAlert( const CMsgJSAlert *pCmd );
+ void BrowserJSConfirm( const CMsgJSConfirm *pCmd );
+ void BrowserCanGoBackandForward( const CMsgCanGoBackAndForward *pCmd );
+ void BrowserOpenSteamURL( const CMsgOpenSteamURL *pCmd );
+ void BrowserSizePopup( const CMsgSizePopup *pCmd );
+ void BrowserScalePageToValueResponse( const CMsgScalePageToValueResponse *pCmd );
+ void BrowserRequestFullScreen( const CMsgRequestFullScreen *pCmd );
+ void BrowserExitFullScreen( const CMsgExitFullScreen *pCmd );
+ void BrowserGetCookiesForURLResponse( const CMsgGetCookiesForURLResponse *pCmd );
+ void BrowserNodeGotFocus( const CMsgNodeHasFocus *pCmd );
+ void BrowserSavePageToJPEGResponse( const CMsgSavePageToJPEGResponse *pCmd );
+ void BrowserFocusedNodeValueResponse( const CMsgFocusedNodeTextResponse *pCmd );
+ void BrowserComboNeedsPaint(const CMsgComboNeedsPaint *pCmd);
+ bool BSupportsOffMainThreadPaints();
+ void ThreadNotifyPendingPaints();
+#endif
+
+ // helpers to control browser side, pos and textures
+ void SetBrowserSize( int wide, int tall );
+ void SendPendingHTMLMessages();
+
+ // helpers to move the html page around inside the control
+ void ScrollPageUp( float flScrollValue, bool bApplyBezier );
+ void ScrollPageDown( float flScrollValue, bool bApplyBezier );
+ void ScrollPageLeft( float flScrollValue, bool bApplyBezier );
+ void ScrollPageRight( float flScrollValue, bool bApplyBezier );
+
+ // Overrides for scroll bar to call back to us rather than normal panel2d call
+ virtual void ScrollToXPercent( float flXPercent );
+ virtual void ScrollToYPercent( float flXPercent );
+
+ // event handlers
+ bool OnGamepadInput();
+ bool OnPropertyTransitionEnd( const CPanelPtr< IUIPanel > &pPanel, CStyleSymbol prop );
+ bool OnSetBrowserSize( const CPanelPtr< IUIPanel > &pPanel, int nWide, int nTall );
+ bool OnHTMLFormFocusPending( const CPanelPtr< IUIPanel > &pPanel );
+ bool OnInputFocusSet( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+ bool OnInputFocusLost( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+ bool OnHTMLScreenShotCaptured( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel, int nThumbNailWidth, int nThumbNailHeight );
+ bool OnHTMLCommitZoom( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel, float flZoom );
+ bool OnHTMLRequestRepaint( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+
+#if defined( SOURCE2_PANORAMA ) || defined( PANORAMA_PUBLIC_STEAM_SDK )
+ bool OnFileOpenDialogFilesSelected( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel, const char *pszFiles );
+#endif
+
+ // moving the html texture around
+ void ResizeBrowserTextureIfNeeded();
+ int AdjustPageScrollForTextureOffset( int &nTargetValue, const int nCurScroll, const int nMaxScroll, float &flOffsetTextureScroll, const float flMaxTextureScroll );
+
+ int GetHScrollOffset()
+ {
+ return m_ScrollLeft.m_flOffsetTextureScroll;
+ }
+
+ int GetVScrollOffset()
+ {
+ return m_ScrollUp.m_flOffsetTextureScroll;
+ }
+
+ void ClampTextureScroll( bool bAllowScrollBorder = true );
+
+ bool m_bInitialized; // used to prevent double shutdown
+ bool m_bReady; // When we are ready to load a url
+ CTexturePanel *m_pTexurePanel;
+
+ int m_nWindowWide, m_nWindowTall; // how big the html texture should be
+ int m_nTextureWide, m_nTextureTall;
+
+ // find in page state
+ bool m_bInFind;
+ CUtlString m_sLastSearchString;
+
+ CUtlString m_sURLToLoad; // url to load once the browser is created
+ CUtlString m_sURLPostData; // post data for url to load
+
+ CUtlString m_sCurrentURL; // the current url we have loaded
+ CUtlString m_sHTMLTitle; // the title of the page we are on
+
+ int m_iBrowser; // our browser handle
+
+ float m_flZoom; // what zoom level we are at
+ bool m_bLastKeyFocus; // tracking for when key focus changes in style application
+
+ struct ScrollControl_t
+ {
+ ScrollControl_t()
+ {
+ Reset();
+ }
+
+ void Reset()
+ {
+ m_flOffsetTextureScroll = 0.0f;
+ m_bScrollingUp = false;
+ m_flLastScrollTime = 0.0f;
+ }
+
+ float m_flOffsetTextureScroll; // amount the html texture is scrolled around the panel itself
+ bool m_bScrollingUp; // we are scrolling up (or left) on the page last?
+ double m_flLastScrollTime; // when did we scroll in this direction last, used for accel curve
+ };
+
+ ScrollControl_t m_ScrollUp;
+ ScrollControl_t m_ScrollLeft;
+
+ struct ScrollData_t
+ {
+ ScrollData_t()
+ {
+ m_bVisible = false;
+ m_nMaxScroll = m_nScroll = m_nPageSize = m_nWebScroll = 0;
+ }
+
+ bool operator==( const ScrollData_t &rhs ) const
+ {
+ return rhs.m_bVisible == m_bVisible &&
+ rhs.m_nScroll == m_nScroll &&
+ rhs.m_nPageSize == m_nPageSize &&
+ rhs.m_nMaxScroll == m_nMaxScroll;
+ }
+
+ bool operator!=( const ScrollData_t &rhs ) const
+ {
+ return !operator==(rhs);
+ }
+
+ bool m_bVisible; // is the scroll bar visible
+ int m_nMaxScroll; // most amount of pixels we can scroll
+ int m_nPageSize; // the underlying size of the page itself in pixels
+ int m_nScroll; // currently scrolled amount of pixels
+ int m_nWebScroll; // last scrolled return value from cef, not updated locally
+ };
+ bool ScrollHelper( ScrollControl_t &scrollControl, float flScrollDelta, int iMaxScrollOffset, ScrollData_t &scrollBar, float &flScrollHTMLAmount, bool bApplyBezier ); // shared code when scrolling around the page
+ bool SetupScrollBar( const ScrollData_t & scrollData, bool bHorizontal, float flContentSize, float flMaxSize );
+ CScrollBar *MakeScrollBar( bool bHorizontal);
+
+ ScrollData_t m_scrollHorizontal; // details of horizontal scroll bar
+ ScrollData_t m_scrollVertical; // details of vertical scroll bar
+ CCubicBezierCurve< Vector2D > m_ScrollBezier; // the curve to scale scroll accel by
+
+ struct LinkAtPos_t
+ {
+ LinkAtPos_t() { m_bLiveLink = false; }
+ CUtlString m_sURL;
+ bool m_bLiveLink;
+ bool m_bInput;
+ };
+ LinkAtPos_t m_LinkAtPos; // cache for link at pos requests, because the request is async
+
+ // last position we saw the mouse at
+ float m_flCursorX;
+ float m_flCursorY;
+
+ double m_flGamePadInputTime; // last time we saw input from the gamepad
+
+ bool m_bPopupVisible; // true if a popup menu is visible on the client
+ bool m_bCanGoBack;
+ bool m_bCanGoForward;
+ bool m_bIgnoreMouseBackForwardButtons;
+
+ int m_nHTMLPageWide; // last size we told CEF the page should be
+ int m_nHTMLPageTall;
+
+ CHTMLVerticalScrollBar *m_pVerticalScrollBar; // our own copy of the scroll bars that we control manually
+ CHTMLHorizontalScrollBar *m_pHorizontalScrollBar;
+ float m_flLastVeritcalScrollPos;
+ float m_flLastHorizontalScrollPos;
+
+ static uint32 sm_PaintCount;
+ uint32 m_PageLoadCount; // the number of posturl calls we have made
+#if !defined( SOURCE2_PANORAMA ) && !defined( PANORAMA_PUBLIC_STEAM_SDK )
+ CUtlVector<HTMLCommandBuffer_t *> m_vecPendingMessages;
+#endif
+ bool m_bSuppressTextureLoads;
+
+ bool m_bCaptureThumbNailThisFrame;
+ CPanel2D *m_pCaptureEventTarget;
+ int m_nCaptureUserData;
+
+ bool m_bCommenceZoomOperationOnTextureUpload; // when the next texture upload is ready, should we apply scale/offset transforms we have saved above
+ float m_flHorizScrollOffset; // the offset between page scroll and texture scroll we had at the start of a zoom
+ float m_flVertScrollOffset; // the offset between page scroll and texture scroll we had at the start of a zoom
+ bool m_bFullScreen; // are we in fullscreen right now?
+ bool m_bConfigureYouTubeHTML5OptIn; // are we doing the forcefully opt into youtube html5 beta path
+ bool m_bMousePanningActive; // true if the mouse is in panning mode
+ Vector2D m_vecMousePanningPos; // the x,y pos of the mouse over the panel when middle panning started
+ CImagePanel *m_pMousePanningImage; // the image to show when panning
+ CCubicBezierCurve< Vector2D > m_MousePanBezier; // the curve to scale panning accel by
+ bool m_bIsSecure; // is this page ssl secure?
+ bool m_bIsCertError; // did we have a cert error when loading?
+ bool m_bIsEVCert; // is it an EV cert?
+ CUtlString m_sCertName; // who was the cert issued to?
+ bool m_bEmbedded; // if true we are embedded instance, just show html pages and simple scrolling, not complex interactions
+ bool m_bAllowOverScroll; // if true allow scrolling the edge of the texture beyond the edge of the screen (i.e so you can hover the recticle at any point)
+ bool m_bLastScrollbarSetupAllowedOverScroll;
+ float m_flMouseLastX;
+ float m_flMouseLastY;
+ float m_flLastSteamPadScroll;
+ uint32 m_unSteamPadScrollRepeats;
+
+ panorama::HtmlFormHasFocus_t m_evtFocus; // used for saving state of controls that have focus info dispatched
+
+ bool m_bPendingInputZoom; // true if we are zooming into an input element
+ bool m_bFocusEventSentForClick; // time we sent a focus event to the browser
+ bool m_bDidMousePanWhileMouseDown; // did we do panning with the mouse held down
+ bool m_bWaitingForZoomResponse;
+
+ Vector2D m_LastSteamRightPad;
+
+ panorama::CTextTooltip *m_pTooltip;
+ bool m_bGotKeyDown;
+#if defined( SOURCE2_PANORAMA ) || defined( PANORAMA_PUBLIC_STEAM_SDK )
+ HHTMLBrowser m_HTMLBrowser;
+ void OnBrowserReady( HTML_BrowserReady_t *pBrowserReady, bool bIOFailure );
+ CCallResult< CHTML, HTML_BrowserReady_t > m_SteamCallResultBrowserReady;
+
+ CPanelPtr< CFileOpenDialog > m_pFileOpenDialog;
+
+ CUtlVector<HHTMLBrowser> m_vecDenyNewBrowserWindows;
+#else
+ CChromePaintBufferClient m_SharedPaintBuffer;
+#endif
+
+ int m_nPopupX;
+ int m_nPopupY;
+ int m_nPopupWide;
+ int m_nPopupTall;
+ int m_nTextureSerialCombo;
+ CUtlBuffer m_ComboTexture;
+ CHTML *m_pPopupChild;
+
+ CThreadMutex m_mutexHTMLTexture;
+ CThreadMutex m_mutexScreenShot;
+ CUtlBuffer m_bufScreenshotTexture;
+ float m_flScrollRemainder;
+ int m_nTargetHorizontalScrollValue;
+ int m_nTargetVerticalScrollValue;
+ bool m_bControlPageScrolling;
+
+ // virtual mouse used when steam controller is connected
+ IVirtualMouse *m_pLeftMousePad;
+ Vector2D m_vecVirtualScrollPrev;
+ Vector2D m_vecVirtualScrollOrigin;
+ bool m_bVerticalAxisSnap;
+ bool m_bClickingLeftPad;
+ bool m_bMarkZoomStart;
+ float m_flInitialZoomLevel;
+ float m_flZoomSwipeOriginPosition;
+
+ static const float s_fScrollDeadzoneScale;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CHTMLSimpleNavigationWrapper : public CPanel2D
+{
+ DECLARE_PANEL2D( CHTMLSimpleNavigationWrapper, CPanel2D );
+
+public:
+ CHTMLSimpleNavigationWrapper( CPanel2D *pParent, const char *pchPanelID );
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+
+ virtual bool OnGamePadDown( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadAnalog( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnMouseWheel( const MouseData_t &code ) OVERRIDE;
+
+private:
+ void EnsureHTMLPanelReference();
+
+private:
+ CHTML *m_pHTML;
+ CPanoramaSymbol m_symWrappedHTMLID;
+ bool m_bInEventProcessing;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_HTML_H
diff --git a/public/panorama/controls/image.h b/public/panorama/controls/image.h
new file mode 100644
index 0000000..3c75637
--- /dev/null
+++ b/public/panorama/controls/image.h
@@ -0,0 +1,121 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_IMAGEPANEL_H
+#define PANORAMA_IMAGEPANEL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "../data/iimagesource.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT1( SetImageSource, const char * );
+DECLARE_PANEL_EVENT0( ClearImageSource );
+enum EImageScaling
+{
+ k_EImageScalingNone,
+ k_EImageScalingStretchBoth,
+ k_EImageScalingStretchX,
+ k_EImageScalingStretchY,
+ k_EImageScalingStretchBothToFitPreserveAspectRatio,
+ k_EImageScalingStretchXToFitPreserveAspectRatio,
+ k_EImageScalingStretchYToFitPreserveAspectRatio,
+ k_EImageScalingStretchBothToCoverPreserveAspectRatio
+};
+
+enum EImageHorizontalAlignment
+{
+ k_EImageHorizontalAlignmentCenter,
+ k_EImageHorizontalAlignmentLeft,
+ k_EImageHorizontalAlignmentRight,
+};
+
+enum EImageVerticalAlignment
+{
+ k_EImageVerticalAlignmentCenter,
+ k_EImageVerticalAlignmentTop,
+ k_EImageVerticalAlignmentBottom,
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: ImagePanel
+//-----------------------------------------------------------------------------
+class CImagePanel : public CPanel2D
+{
+ DECLARE_PANEL2D( CImagePanel, CPanel2D );
+
+public:
+ CImagePanel( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CImagePanel();
+
+ virtual void Paint();
+ virtual bool BSetProperties( const CUtlVector< ParsedPanelProperty_t > &vecProperties );
+
+ bool OnImageLoaded( const CPanelPtr< IUIPanel > &pPanel, IImageSource *pImage );
+ bool OnSetImageSource( const CPanelPtr<IUIPanel> &pPanel, const char *pchImageSource );
+ bool OnClearImageSource( const CPanelPtr<IUIPanel> &pPanel );
+
+ IImageSource *GetImage() { return m_pImage; }
+
+ // Set an image from a URL (file://, http://), if pchDefaultImage is specified it must be a file:// url and will be
+ // used while the actual image is loaded asynchronously, it will also remain in use if the actual image fails to load
+ void SetImage( const char *pchImageURL, const char *pchDefaultImageURL = NULL, bool bPrioritizeLoad = false, int nResizeWidth = -1, int nResizeHeight = -1 );
+
+ // Set an image from an already created IImageSource, you should almost always use the simpler SetImage( pchImageURL, pchDefaultImageURL ) call.
+ void SetImage( IImageSource *pImage );
+
+ void Clear();
+ bool IsSet() { return (m_pImage != NULL); }
+
+ void SetScaling( EImageScaling eScale );
+ void SetScaling( CPanoramaSymbol symScale );
+ void SetAlignment( EImageHorizontalAlignment horAlign, EImageVerticalAlignment verAlign );
+ void SetVisibleImageSlice( int nX, int nY, int nWidth, int nHeight );
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties );
+
+ virtual bool BRequiresContentClipLayer();
+
+ void SetImageJS( const char *pchImageURL );
+
+ virtual bool IsClonable() OVERRIDE { return AreChildrenClonable(); }
+ virtual CPanel2D *Clone() OVERRIDE;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+#endif
+
+protected:
+ virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions );
+
+ virtual void InitClonedPanel( CPanel2D *pPanel ) OVERRIDE;
+private:
+
+ EImageScaling m_eScaling;
+ EImageHorizontalAlignment m_eHorAlignment;
+ EImageVerticalAlignment m_eVerAlignment;
+ int m_nVisibleSliceX;
+ int m_nVisibleSliceY;
+ int m_nVisibleSliceWidth;
+ int m_nVisibleSliceHeight;
+ CUtlString m_strSource;
+ CUtlString m_strSourceDefault;
+ bool m_bAnimate;
+
+ IImageSource *m_pImage;
+ float m_flPrevAnimateWidth;
+ float m_flPrevAnimateHeight;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_IMAGEPANEL_H
diff --git a/public/panorama/controls/label.h b/public/panorama/controls/label.h
new file mode 100644
index 0000000..01e1ffb
--- /dev/null
+++ b/public/panorama/controls/label.h
@@ -0,0 +1,232 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_LABEL_H
+#define PANORAMA_LABEL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "panorama/localization/ilocalize.h"
+#include "panorama/text/iuitextlayout.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT0( CopySelectedLabelText );
+
+//-----------------------------------------------------------------------------
+// Purpose: Label
+//-----------------------------------------------------------------------------
+class CLabel : public CPanel2D, public ILocalizationStringSizeResolver
+{
+ DECLARE_PANEL2D( CLabel, CPanel2D );
+
+public:
+ CLabel( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CLabel();
+
+ virtual void Paint();
+ virtual bool BSetProperties( const CUtlVector< ParsedPanelProperty_t > &vecProperties );
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ enum ETextType
+ {
+ k_ETextTypePlain,
+ k_ETextTypeUnlocalized,
+ k_ETextTypeHTML
+ };
+ virtual void SetText( const char *pchValue, ETextType eTextType = k_ETextTypePlain );
+ virtual void AppendText( const char *pchValue, ETextType eTextType = k_ETextTypePlain );
+ virtual const char *PchGetText() const { return m_pLocText ? m_pLocText->String() : ""; }
+
+ bool OnLocalizationChanged( const CPanelPtr< IUIPanel > &pPanel, const ILocalizationString *pString ); // can't be virtual as it is an event catcher
+
+ void SetMaxChars( EStringTruncationStyle eTruncationStyle, uint32 nMaxChars );
+ void SetStyleForRange( int iStartIndex, int iEndIndex, CPanoramaSymbol symStyle );
+
+ virtual bool BRequiresContentClipLayer() { return m_bMayDrawOutsideBounds; }
+ virtual bool BAcceptsFocus() { return false; }
+
+ virtual bool GetContextUIBounds( float *pflX, float *pflY, float *pflWidth, float *pflHeight ) OVERRIDE;
+
+ bool BHasSelection() { return m_nSelectionEndIndex != -1; }
+ void CopySelectionToClipboard();
+
+ bool OnCopySelectedLabelText( const CPanelPtr< IUIPanel > &pPanel );
+
+ // for cloning
+ virtual bool IsClonable() { return AreChildrenClonable(); }
+ virtual CPanel2D *Clone();
+
+ // Get the count of anchor tags in this label, will be zero if not HTML
+ uint32 GetHREFCount();
+
+ // Get vector of all url targets in the label
+ void GetHREFTargets( CUtlVector< CUtlString > &vecTargets );
+
+ // enable or disable selection of text via mouse clicks
+ void SetAllowTextSelection( bool bAllow ) { m_bAllowTextSelection = bAllow; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+ void ValidateLinkVector( CValidator &validator, CUtlVector< CUtlString > *pvecLinks );
+#endif
+
+ // Allow us to recalc HTML style flags on scale factor changes
+ virtual void OnUIScaleFactorChanged( float flScaleFactor ) OVERRIDE;
+
+ virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties ) OVERRIDE;
+
+ enum EHTMLFormatFlag
+ {
+ k_EHTMLFormatTagNone = 0,
+ k_EHTMLFormatTagAnchor = 1,
+ k_EHTMLFormatTagBold = 1 << 1,
+ k_EHTMLFormatTagItalics = 1 << 2,
+ k_EHTMLFormatTagEmphasized = 1 << 3,
+ k_EHTMLFormatTagStrong = 1 << 4,
+ k_EHTMLFormatTagSpan = 1 << 5,
+ k_EHTMLFormatTagHeader1 = 1 << 6,
+ k_EHTMLFormatTagHeader2 = 1 << 7,
+ k_EHTMLFormatTagFont = 1 << 8,
+ k_EHTMLFormatTagPre = 1 << 9,
+ };
+
+protected:
+ virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions );
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ virtual void OnStylesChanged();
+ virtual void OnMouseMove( float flMouseX, float flMouseY );
+ virtual bool OnMouseButtonDown( const MouseData_t &code );
+ virtual bool OnMouseButtonUp( const MouseData_t &code );
+ bool EventStyleFlagsChanged( const CPanelPtr< IUIPanel > &pPanel );
+ bool OnFindLongestStringForLocVariable( const CPanelPtr< IUIPanel > &pPanel );
+
+ virtual void InitClonedPanel( CPanel2D *pPanel );
+
+ virtual void SetTextFromJS(const char *pchValue)
+ {
+ if( m_bParseAsHTML )
+ SetText( pchValue, k_ETextTypeHTML );
+ else
+ SetText( pchValue, k_ETextTypeUnlocalized );
+ }
+
+ bool BParseAsHTML() const { return m_bParseAsHTML; }
+ void SetParseAsHTML( bool bParseAsHTML ) { m_bParseAsHTML = bParseAsHTML; }
+
+private:
+ struct TextRangeFormat_t
+ {
+ static const Color k_colorUnspecified;
+
+ TextRangeFormat_t()
+ {
+ m_iStartChar = -1;
+ m_iEndChar = -1;
+ m_unHTMLFormatFlags = 0;
+ m_iHREF = -1;
+ m_iMouseOver = -1;
+ m_iMouseOut = -1;
+ m_iContextMenu = -1;
+ m_pStyle = NULL;
+ m_unStyleFlags = 0;
+ m_color = k_colorUnspecified;
+ m_bChildOwner = false;
+ }
+
+ void CopyWithoutRecalcData( const TextRangeFormat_t &rhs );
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+ int m_iStartChar;
+ int m_iEndChar;
+
+ uint m_unHTMLFormatFlags;
+ CUtlVector< CPanoramaSymbol > m_vecClasses;
+ int m_iHREF; // index into m_vecParsedHREFs if clickable. Multiple ranges could have the same URL, so hold indexes instead of copy strings
+ int m_iMouseOver; // index into m_vecParsedMouseOvers if clickable. Multiple ranges could have the same URL, so hold indexes instead of copy strings
+ int m_iMouseOut; // index into m_vecParsedMouseOuts if clickable. Multiple ranges could have the same URL, so hold indexes instead of copy strings
+ int m_iContextMenu; // index into m_vecParsedContextMenus if clickable. Multiple ranges could have the same URL, so hold indexes instead of copy strings
+
+ IUIPanelStyle *m_pStyle;
+ uint m_unStyleFlags;
+
+ Color m_color;
+
+ CUtlString m_strChildID;
+ bool m_bChildOwner;
+
+ struct RangeFormatBox_t
+ {
+ Vector2D topLeft;
+ Vector2D bottomRight;
+ };
+
+ CUtlVector< RangeFormatBox_t > m_vecBoundingBoxes;
+ };
+
+ void SetTextInternal( const char *pchValue, ETextType eTextType, bool bTrustedSource );
+ void SetFromHTMLInternal( const char *pchText, bool bAppend, bool bTrusted );
+ int ParseStringFromTag( const char *pchTag, const char *pchString, CUtlVector<CUtlString> **ppVecStrings );
+ int ParseHREFFromTag( const char *pchTag );
+ int ParseMouseOverFromTag( const char *pchTag );
+ int ParseMouseOutFromTag( const char *pchTag );
+ int ParseContextMenuFromTag( const char *pchTag );
+ void UpdateTextRangeStyles();
+ TextRangeFormat_t &AppendTextRangeFormat( int iStartChar, int iEndChar, uint unHTMLFormatFlags, const CUtlVector< CPanoramaSymbol > &vecStyles, int iHREF, int iMouseOver, int iMouseOut, int iContextMenu, const Color &color, const char *pszChildID, bool bChildOwner );
+ void RemoveTextRangeFormats();
+ bool BCoordsInTextRange( const TextRangeFormat_t &rangeFormat, float flX, float flY );
+ int FindTextRangeAt( float flX, float flY );
+
+ IUITextLayout *CreateTextLayout( float flWidth, float flHeight, bool bUseChildDesiredSize, const char *pchOptStringToUse = NULL );
+ IUITextLayout *CreateCurrentLayoutTextLayout();
+ virtual int ResolveStringLengthInPixels( const char *pchString );
+
+ bool HandleAnchorTagEvent( CUtlVector< CUtlString > *pvecLinks, int iLinkIndex );
+
+ static void CloneLinksVector( CUtlVector< CUtlString > *pSourceLinks, CUtlVector< CUtlString > **ppDestinationLinks );
+
+ bool m_bContentSizeDirty;
+ float m_flMaxWidthLastContentSize;
+ float m_flMaxHeightLastContentSize;
+ float m_flLastUIScaleFactor;
+
+ bool m_bLeftMouseIsDown;
+ Vector2D m_LastMousePos;
+ bool m_bSelectionRectDirty;
+ int32 m_nSelectionStartIndex;
+ int32 m_nSelectionEndIndex;
+ CUtlVector<IUITextLayout::HitTestRegionRect_t> m_vecSelectionRects;
+
+ bool m_bMayDrawOutsideBounds;
+ bool m_bAllowTextSelection;
+
+ CMutableLocalizationString m_pLocText;
+ CMutableLocalizationString m_pLocTextHTML; // the base string with html markup preserved
+ uint32 m_nMaxChars; // max chars to store in this label
+ EStringTruncationStyle m_eStringTruncationStyle; // how to truncate our text
+ bool m_bParseAsHTML; // if true, set text will be parsed as html
+ CUtlVector< TextRangeFormat_t > m_vecTextRangeFormats; // list of parsed text range formats
+ CUtlVector< CUtlString > *m_pvecParsedHREFs; // parsed href.. indexes are added to text range formats. Multiple ranges could have same URL.
+ CUtlVector< CUtlString > *m_pvecParsedMouseOvers; // parsed onmouseover.. indexes are added to text range formats. Multiple ranges could have same URL.
+ CUtlVector< CUtlString > *m_pvecParsedMouseOuts; // parsed onmouseout.. indexes are added to text range formats. Multiple ranges could have same URL.
+ CUtlVector< CUtlString > *m_pvecParsedContextMenus; // parsed oncontextmenu.. indexes are added to text range formats. Multiple ranges could have same URL.
+ TextRangeFormat_t *m_pLastHoverRange; // last text range the mouse was hovering over
+ TextRangeFormat_t *m_pMouseDownRange; // index into m_vecTextRangeFormats
+
+ static uint32 s_unNextInlineImageID;
+};
+
+} // namespace panorama
+
+
+#endif // PANORAMA_LABEL_H
diff --git a/public/panorama/controls/listsegmentview.h b/public/panorama/controls/listsegmentview.h
new file mode 100644
index 0000000..e4ffc02
--- /dev/null
+++ b/public/panorama/controls/listsegmentview.h
@@ -0,0 +1,84 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef LIST_SEGMENT_VIEW_H
+#define LIST_SEGMENT_VIEW_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+
+DECLARE_PANEL_EVENT0( ListSegmentViewRetreat );
+DECLARE_PANEL_EVENT0( ListSegmentViewAdvance );
+
+DECLARE_PANORAMA_EVENT0( ListSegmentViewChanged );
+
+
+namespace panorama
+{
+ /*
+
+ A class that handles displaying X sequential elements from its children. Similar to a carousel, but more
+ minimal -- you handle advancing/retreating yourself. Supports up to 10 visible elements.
+
+ Things you need to do:
+ - Specify "items-displayed:" in the xml, which is how many elements are shown at once.
+ - Specify "step-size:" in the xml, which is how many steps it'll move when advancing or retreating. Cannot be bigger than items-displayed.
+ - Define these classes, which will be added to the child elements (X is always 1 through 10):
+ .ListSegmentDisplayedX, one for each of the elements you intend to display.
+ .ListSegmentHiddenBeforeX, one for each hidden element that's off the "top/left" of the display. These guys are prior to the displayed window.
+ .ListSegmentHiddenAfterX, one for each hidden element that's off the "bottom/right" of the display. These guys are after the displayed window.
+ .ListSegmentSnap, which eliminates any transitions you're using in your element class, so that elements just go directly to their displayed/hidden states immediately.
+
+ Then you just need to add children (in order) to it, and call AdvancePosition and RetreatPosition to move through them.
+
+ */
+
+//-----------------------------------------------------------------------------
+// Purpose: List Segment View
+//-----------------------------------------------------------------------------
+class CListSegmentView : public CPanel2D
+{
+ DECLARE_PANEL2D( CListSegmentView, CPanel2D );
+
+public:
+ CListSegmentView( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CListSegmentView();
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+ virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties ) OVERRIDE;
+
+ virtual void OnStylesChanged() OVERRIDE { UpdateChildrenStyles( false ); BaseClass::OnStylesChanged(); }
+ virtual void OnAfterChildrenChanged() OVERRIDE { UpdateChildrenStyles( false ); BaseClass::OnAfterChildrenChanged(); }
+
+ virtual bool BRequiresContentClipLayer() OVERRIDE { return true; }
+
+ bool RetreatPosition( const CPanelPtr< IUIPanel > &panelPtr );
+ bool AdvancePosition( const CPanelPtr< IUIPanel > &panelPtr );
+
+ int GetCurrentPage( void );
+ int GetNumPages( void );
+
+ bool IsAtStart( void );
+ bool IsAtEnd( void );
+
+ void ResetPosition( void );
+
+private:
+
+ void UpdateChildrenStyles( bool bSnap );
+
+ int m_nItemsDisplayed;
+ int m_nStepSize;
+
+ int m_nCurrentChildIndex;
+};
+
+
+} // namespace panorama
+
+#endif // LIST_SEGMENT_VIEW_H
diff --git a/public/panorama/controls/mousescroll.h b/public/panorama/controls/mousescroll.h
new file mode 100644
index 0000000..62ee5eb
--- /dev/null
+++ b/public/panorama/controls/mousescroll.h
@@ -0,0 +1,53 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef MOUSESCROLL_H
+#define MOUSESCROLL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "mathlib/mathlib.h"
+#include "mathlib/beziercurve.h"
+#include "panel2d.h"
+#include "panorama/controls/label.h"
+#include "panorama/controls/mousescroll.h"
+#include "panorama/uischeduleddel.h"
+
+
+namespace panorama
+{
+DECLARE_PANEL_EVENT1( MouseScroll, int );
+
+//-----------------------------------------------------------------------------
+// Purpose: Panel which is the clickable mouse region to scroll a carousel or other horizontal list type panel
+//-----------------------------------------------------------------------------
+class CMouseScrollRegion : public CPanel2D
+{
+ DECLARE_PANEL2D( CMouseScrollRegion, CPanel2D );
+
+public:
+ CMouseScrollRegion( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CMouseScrollRegion();
+
+ virtual bool OnMouseButtonDown( const MouseData_t &code );
+ virtual bool OnMouseButtonDoubleClick( const MouseData_t &code );
+ virtual bool OnMouseButtonTripleClick( const MouseData_t &code );
+ virtual bool OnMouseButtonUp( const MouseData_t &code );
+
+private:
+ void DispatchScrollEvent();
+ void MouseButtonDown();
+
+ CCubicBezierCurve< Vector2D > m_repeatCurve;
+ panorama::CUIScheduledDel m_scheduledScrollRepeat;
+ double m_flMouseDownTimestamp;
+ int m_cMouseDownRepeats;
+};
+
+} // namespace panorama
+
+#endif // MOUSESCROLL_H
diff --git a/public/panorama/controls/movieplayer.h b/public/panorama/controls/movieplayer.h
new file mode 100644
index 0000000..b76f100
--- /dev/null
+++ b/public/panorama/controls/movieplayer.h
@@ -0,0 +1,320 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_MOVIEPLAYER_H
+#define PANORAMA_MOVIEPLAYER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "../data/iimagesource.h"
+#include "../data/panoramavideoplayer.h"
+#include "panorama/uischeduleddel.h"
+
+namespace panorama
+{
+class CToggleButton;
+class CLabel;
+class CSlider;
+
+DECLARE_PANEL_EVENT0( MoviePlayerAudioStart );
+DECLARE_PANEL_EVENT0( MoviePlayerAudioStop );
+DECLARE_PANEL_EVENT0( MoviePlayerPlaybackStart );
+DECLARE_PANEL_EVENT0( MoviePlayerPlaybackStop );
+DECLARE_PANEL_EVENT1( MoviePlayerPlaybackEnded, EVideoPlayerPlaybackError );
+DECLARE_PANORAMA_EVENT0( MoviePlayerTogglePlayPause );
+DECLARE_PANORAMA_EVENT0( MoviePlayerFastForward );
+DECLARE_PANEL_EVENT0( MoviePlayerUIVisible );
+DECLARE_PANORAMA_EVENT0( MoviePlayerJumpBack );
+DECLARE_PANORAMA_EVENT0( MoviePlayerVolumeControl );
+DECLARE_PANORAMA_EVENT0( MoviePlayerFullscreenControl );
+DECLARE_PANORAMA_EVENT1( MoviePlayerSetRepresentation, int );
+DECLARE_PANORAMA_EVENT0( MoviePlayerSelectVideoQuality );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Base class for controls that pop above movie button bar
+//-----------------------------------------------------------------------------
+class CMovieControlPopupBase : public CPanel2D
+{
+public:
+ CMovieControlPopupBase( CPanel2D *pInvokingPanel, const char *pchPanelID );
+ virtual ~CMovieControlPopupBase() {}
+
+ void Show( float flVolume );
+ void Close();
+
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight ) OVERRIDE;
+
+protected:
+ bool EventCancelled( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+
+ CPanel2D *m_pInvisibleBackground;
+ CPanel2D *m_pInvokingPanel;
+ CPanel2D *m_pPopupBackground;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Top level menu for volume slider
+//-----------------------------------------------------------------------------
+class CVolumeSliderPopup : public CMovieControlPopupBase
+{
+ DECLARE_PANEL2D( CVolumeSliderPopup, CMovieControlPopupBase );
+
+public:
+ CVolumeSliderPopup( CPanel2D *pInvokingPanel, const char *pchPanelID );
+ virtual ~CVolumeSliderPopup() {}
+
+ void Show( float flVolume );
+ virtual bool OnKeyDown( const KeyData_t &unichar ) OVERRIDE;
+
+private:
+ bool EventSliderValueChanged( const CPanelPtr< IUIPanel > &pPanel, float flValue );
+
+ CSlider *m_pSlider;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Top level menu for showing video resolutions to select
+//-----------------------------------------------------------------------------
+class CMovieVideoQualityPopup : public CMovieControlPopupBase
+{
+ DECLARE_PANEL2D( CMovieVideoQualityPopup, CMovieControlPopupBase );
+
+public:
+ CMovieVideoQualityPopup( CPanel2D *pInvokingPanel, const char *pchPanelID );
+ virtual ~CMovieVideoQualityPopup() {}
+
+ void AddRepresentation( int iRep, int nHeight );
+ void Show( int iFocusRep, int nVideoHeight );
+
+private:
+ struct Representation_t
+ {
+ int m_iRep;
+ int m_nHeight;
+ };
+
+ bool EventSetRepresentation( int iRep );
+ static bool SortRepresentations( const Representation_t &lhs, const Representation_t &rhs );
+
+ CUtlVector< Representation_t > m_vecRepresentations;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Movie panel. Just displays the movie
+//-----------------------------------------------------------------------------
+class CMoviePanel : public CPanel2D
+{
+ DECLARE_PANEL2D( CMoviePanel, CPanel2D );
+
+public:
+ CMoviePanel( CPanel2D *parent, const char *pchPanelID );
+ virtual ~CMoviePanel();
+
+ CVideoPlayerPtr GetMovie() { return m_pVideoPlayer; }
+ void SetMovie( const char *pchFile );
+ void SetMovie( CVideoPlayerPtr pVideoPlayer );
+ bool IsSet() { return (m_pVideoPlayer != NULL); }
+ void Clear();
+ void SetPlaybackVolume( float flVolume );
+ void SuggestMovieHeight();
+
+ virtual void Paint();
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+#endif
+
+protected:
+ virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions ) OVERRIDE;
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight ) OVERRIDE;
+ bool EventVideoPlayerInitialized( IVideoPlayer *pIMovie );
+
+private:
+ CVideoPlayerPtr m_pVideoPlayer;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Displays debug info for a movie
+//-----------------------------------------------------------------------------
+class CMovieDebug : public CPanel2D
+{
+ DECLARE_PANEL2D( CMovieDebug, CPanel2D );
+
+public:
+ CMovieDebug( CPanel2D *pParent, const char *pchID );
+ virtual ~CMovieDebug() {}
+
+ void Show( CVideoPlayerPtr pVideoPlayer );
+
+private:
+ void Update();
+
+ CVideoPlayerPtr m_pVideoPlayer;
+ CLabel *m_pDimensions;
+ CLabel *m_pResolution;
+ CLabel *m_pFileType;
+ CLabel *m_pVideoSegment;
+ CLabel *m_pVideoBandwidth;
+
+ panorama::CUIScheduledDel m_scheduledUpdate;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Movie player. Includes UI
+//-----------------------------------------------------------------------------
+class CMoviePlayer : public CPanel2D
+{
+ DECLARE_PANEL2D( CMoviePlayer, CPanel2D );
+
+public:
+ CMoviePlayer( CPanel2D *parent, const char *pchPanelID );
+ virtual ~CMoviePlayer();
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ CVideoPlayerPtr GetMovie() { return m_pMoviePanel->GetMovie(); }
+ void SetMovie( const char *pchFile );
+ void SetMovie( CVideoPlayerPtr pVideoPlayer );
+ bool IsSet() { return m_pMoviePanel->IsSet(); }
+ void Clear();
+
+ enum EAutoplay
+ {
+ k_EAutoplayOff,
+ k_EAutoplayOnLoad,
+ k_EAutoplayOnFocus
+ };
+
+ enum EControls
+ {
+ k_EControlsNone,
+ k_EControlsMinimal,
+ k_EControlsFull,
+ k_EControlsInvalid
+ };
+
+ void SetAutoplay( EAutoplay eAutoPlay, bool bSkipPlay = false );
+ void SetRepeat( bool bRepeat );
+ void SetControls( EControls eControls );
+ void SetControls( const char *pchControls );
+
+
+ virtual bool OnGamePadDown( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnKeyTyped( const KeyData_t &unichar ) OVERRIDE;
+ virtual panorama::IUIPanel *OnGetDefaultInputFocus() OVERRIDE;
+
+ void Play();
+ void Pause();
+ void Stop();
+ void TogglePlayPause();
+ void FastForward();
+ void Rewind();
+ void SetPlaybackVolume( float flVolume );
+
+ // title control
+ void SetTitleText( const char *pchText );
+ void ShowTitle( bool bImmediatelyVisible = false );
+ void HideTitle();
+ bool BAdjustingVolume();
+
+ virtual bool OnMouseButtonDown( const MouseData_t &code );
+
+protected:
+ virtual bool BSetProperties( const CUtlVector< ParsedPanelProperty_t > &vecProperties );
+
+ static EControls EControlsFromString( const char *pchControls );
+
+ bool EventInputFocusSet( const CPanelPtr< IUIPanel > &ptrPanel );
+ bool EventInputFocusLost( const CPanelPtr< IUIPanel > &ptrPanel );
+ bool EventMovieInitialized( IVideoPlayer *pIMovie );
+ bool EventVideoPlayerPlaybackStateChanged( IVideoPlayer *pIMovie );
+ bool EventVideoPlayerChangedRepresentation( IVideoPlayer *pIMovie );
+ bool EventVideoPlayerEnded( IVideoPlayer *pIMovie );
+ bool EventActivated( const CPanelPtr< IUIPanel > &ptrPanel, EPanelEventSource_t eSource );
+ bool EventCancelled( const CPanelPtr< IUIPanel > &ptrPanel, EPanelEventSource_t eSource );
+ bool EventMovieTogglePlayPause();
+ bool EventMoviePlayerFastForward();
+ bool EventMoviePlayerJumpBack();
+ bool EventMoviePlayerVolumeControl();
+ bool EventMoviePlayerSelectQuality();
+ bool EventSoundVolumeChanged( ESoundType eSoundType, float flVolume );
+ bool EventSoundMuteChanged( bool bMute );
+ bool EventSetRepresentation( int iRep );
+
+ void UpdateFullUI();
+ void UpdateTimeline();
+ void UpdatePlayPauseButton();
+ void UpdatePlaybackSpeed();
+ void Seek( uint unOffset );
+ void RaisePlaybackStartEvents();
+ void RaisePlaybackStopEvents();
+ void DisplayControls( bool bVisible );
+ void DisplayTimeline( bool bVisible );
+ bool BAnyControlsVisible();
+ bool BControlBarVisible();
+ bool BTimelineVisible();
+ void UpdateMovingPlayingStyle();
+ void UpdateVolumeControls();
+ void SetAudioVolumeStyle( CPanoramaSymbol symStyle );
+
+ void ShowTitleInternal( bool bImmediatelyVisible = false );
+ void HideTitleInternal();
+
+private:
+ CMoviePanel *m_pMoviePanel;
+ CPanelPtr< CMovieDebug > m_ptrDebug;
+
+ // minimal UI
+ CPanel2D *m_pLoadingThrobber;
+ CPanel2D *m_pPlayIndicator;
+ CPanoramaSymbol m_symMoviePlaybackStyle;
+
+ // title sections
+ CPanel2D *m_pPlaybackTitleAndControls;
+ CLabel *m_pPlaybackTitle;
+ bool m_bExternalShowTitle;
+
+ // full UI
+ CPanel2D *m_pPlaybackControls;
+ CPanel2D *m_pPlaybackProgressBar;
+ CToggleButton *m_pPlayPauseBtn;
+ CLabel *m_pPlaybackSpeed;
+ CPanel2D *m_pTimeline;
+ CPanel2D *m_pControlBarRow;
+ CPanel2D *m_pVolumeControl;
+ CLabel *m_pErrorMessage;
+ CPanelPtr< CVolumeSliderPopup > m_ptrVolumeSlider;
+ CPanelPtr< CMovieVideoQualityPopup > m_ptrVideoQualityPopup;
+ CButton *m_pVideoQualityBtn;
+
+ bool m_bInConstructor;
+ bool m_bRaisedAudioStartEvent;
+ bool m_bRaisedPlaybackStartEvent;
+ bool m_bHadFocus;
+ bool m_bCloseControlsOnPlay;
+
+ EAutoplay m_eAutoplay;
+ EControls m_eControls;
+ bool m_bDisableActivatePause;
+ bool m_bShowControlsNotFullscreen;
+ bool m_bRepeat;
+ bool m_bMuted; // muted flag
+ float m_flVolume; // playback volume, defaults to movie volume setting
+ int m_iDesiredVideoRepresentation; // representation selected by user or -1. Video player might not yet have changed to playing this rep
+};
+
+
+} // namespace panorama
+
+#endif // PANORAMA_MOVIEPLAYER_H
diff --git a/public/panorama/controls/panel2d.h b/public/panorama/controls/panel2d.h
new file mode 100644
index 0000000..a514708
--- /dev/null
+++ b/public/panorama/controls/panel2d.h
@@ -0,0 +1,1109 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANEL2D_H
+#define PANEL2D_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "../iuiengine.h"
+#include "../iuipanel.h"
+#include "../iuipanelclient.h"
+#include "../iuipanelstyle.h"
+#include "panorama/transformations.h"
+#include "panorama/input/keycodes.h"
+#include "panorama/layout/panel2dfactory.h"
+#include "panorama/layout/stylefiletypes.h"
+#include "panorama/input/mousecursors.h"
+#include "panorama/input/iuiinput.h"
+#include "panorama/uieventcodes.h"
+#include "panorama/uievent.h"
+#include "panorama/iuiwindow.h"
+#include "panorama/layout/panel2dfactory.h"
+#include "color.h"
+#include "utlvector.h"
+#include "utlstring.h"
+#include "panelptr.h"
+#include "steam/steamtypes.h"
+#if defined( SOURCE2_PANORAMA )
+#include "currencyamount.h"
+#else
+#include "rtime.h"
+#include "amount.h"
+#endif
+#include "tier1/utlmap.h"
+#include "panorama/layout/stylesymbol.h"
+
+namespace panorama
+{
+
+#pragma warning(push)
+// warning C4251: 'CPanel2D::symbol' : class 'CUtlSymbol' needs to have dll-interface to be used by clients of class 'CPanel2D'
+#pragma warning( disable : 4251 )
+
+class CLayoutFile;
+class CTopLevelWindow;
+class CVerticalScrollBar;
+class CHorizontalScrollBar;
+struct PanelDescription_t;
+class CUIRenderEngine;
+class CImageResourceManager;
+class CPanelStyle;
+class CBackgroundImageLayer;
+class CPanel2D;
+class CScrollBar;
+
+// Typedefs for getter/setter methods that can be exposed via JS
+typedef float(CPanel2D::*PanelFloatGetter_t)() const;
+typedef void(CPanel2D::*PanelFloatSetter_t)(float);
+typedef const char *(CPanel2D::*PanelStringGetter_t)() const;
+typedef void(CPanel2D::*PanelStringSetter_t)(const char *);
+typedef bool(CPanel2D::*PanelBoolGetter_t)() const;
+typedef void(CPanel2D::*PanelBoolSetter_t)(bool);
+typedef CPanoramaSymbol( CPanel2D::*PanelSymbolGetter_t )() const;
+typedef void(CPanel2D::*PanelSymbolSetter_t)(CPanoramaSymbol);
+
+inline CPanel2D * ToPanel2D( IUIPanel *pPanel )
+{
+ if( pPanel )
+ return (CPanel2D*)(pPanel->ClientPtr());
+
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Struct used to perform hit tests
+//-----------------------------------------------------------------------------
+struct TransformContext_t
+{
+ float m_flPosX;
+ float m_flPosY;
+ float m_flPosZ;
+ VMatrix m_TransformMatrix;
+ float m_flWidth;
+ float m_flHeight;
+
+ float m_flPerspective;
+ float m_flPerspectiveOriginX;
+ float m_flPerspectiveOriginY;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Basic 2D UI panel. These may be transformed in 3D space, but they are
+// at a base level 2D rectangular containers for other panels/paint operations.
+//-----------------------------------------------------------------------------
+class CPanel2D : public panorama::IUIPanelClient
+{
+ DECLARE_PANEL2D_NO_BASE( CPanel2D );
+
+public:
+ CPanel2D( IUIWindow *parent, const char * pchID );
+ CPanel2D( CPanel2D *parent, const char * pchID );
+ CPanel2D( CPanel2D *parent, const char *pchID, uint32 ePanelFlags );
+
+ virtual ~CPanel2D();
+
+ // Check if the panel has loaded layout
+ bool IsLoaded() const { return m_pIUIPanel->IsLoaded(); }
+
+ virtual void OnDeletePanel() OVERRIDE { delete this; }
+
+ // Access the panorama side UI panel interface for the client panel
+ virtual IUIPanel *UIPanel() const { return m_pIUIPanel; }
+
+ void DeleteAsync( float flDelay = 0.0f );
+
+ // Set the panel visible
+ void SetVisible( bool bVisible ) { m_pIUIPanel->SetVisible( bVisible ); }
+ bool BIsVisible() const { return m_pIUIPanel->BIsVisible(); }
+
+ // Get the base position for the panel
+ void GetPosition( CUILength &x, CUILength &y, CUILength &z, bool bIncludeUIScaleFactor = true );
+
+ // Set the base position for the panel
+ void SetPosition( CUILength x, CUILength y, CUILength z, bool bPreScaledByUIScaleFactor = false );
+ void SetPositionWithoutTransition( CUILength x, CUILength y, CUILength z, bool bPreScaledByUIScaleFactor = false );
+ void SetTransform3D( const CUtlVector<CTransform3D *> &vecTransforms );
+ void SetOpacity( float flOpacity );
+ bool BIsTransparent() { return m_pIUIPanel->BIsTransparent(); }
+ void SetPreTransformScale2D( float flX, float flY );
+
+ // Set the base width/height for the panel
+ CUILength GetStyleWidth();
+ CUILength GetStyleHeight();
+ void SetSize( CUILength width, CUILength height );
+
+ // The the bounds that should be used for placing a tooltip, returning false means "use the entire panel"
+ virtual bool GetContextUIBounds( float *pflX, float *pflY, float *pflWidth, float *pflHeight ) { return false; }
+
+ // Set the animation style for the panel
+ void SetAnimation( const char *pchAnimationName, float flDuration, float flDelay, EAnimationTimingFunction eTimingFunc, EAnimationDirection eDirection, float flIterations ) { m_pIUIPanel->SetAnimation( pchAnimationName, flDuration, flDelay, eTimingFunc, eDirection, flIterations ); }
+
+ // Returns the layout file for this panel
+ CPanoramaSymbol GetLayoutFile() const { return m_pIUIPanel->GetLayoutFile(); }
+
+ // Returns define from layout file for this panel
+ char const * GetLayoutFileDefine( char const *szDefineName );
+ int GetLayoutFileDefineInt( const char *szDefineName, int defaultValue );
+ float GetLayoutFileDefineFloat( const char *szDefineName, float defaultValue );
+
+ // Style access
+ panorama::IUIPanelStyle *AccessStyle() const { return m_pIUIPanel->AccessIUIStyle(); }
+
+ // Style access
+ panorama::IUIPanelStyle *AccessStyleDirty() const { return m_pIUIPanel->AccessIUIStyleDirty(); }
+
+ void ApplyStyles( bool bTraverse ) { return m_pIUIPanel->ApplyStyles( bTraverse ); }
+
+ // Mark styles dirty for the panel
+ void MarkStylesDirty( bool bIncludeChildren ) { m_pIUIPanel->MarkStylesDirty( bIncludeChildren ); }
+
+ void ClearPropertyFromCode( panorama::CStyleSymbol symProperty );
+
+ // Virtual called on scale factor for panel changing
+ virtual void OnUIScaleFactorChanged( float flScaleFactor ) OVERRIDE { }
+
+ // Paint the panel and it's children, called by the rendering layer when it's time to paint.
+ void PaintTraverse() { m_pIUIPanel->PaintTraverse(); }
+
+ // Paint the panels contents
+ virtual void Paint() OVERRIDE;
+
+ // Invalidates painting and tells the panel it must repaint next frame
+ void SetRepaint( EPanelRepaint eRepaintNeeded );
+
+ // sets & loads the layout file for this panel
+ bool BLoadLayout( const char *pchFile, bool bOverrideExisting = false, bool bPartialLayout = false ) { return m_pIUIPanel->BLoadLayout( pchFile, bOverrideExisting, bPartialLayout ); }
+
+ // sets & loads the layout for this panel
+ bool BLoadLayoutFromString( const char *pchXMLString, bool bOverrideExisting = false, bool bPartialLayout = false ) { return m_pIUIPanel->BLoadLayoutFromString( pchXMLString, bOverrideExisting, bPartialLayout ); }
+
+ // sets loads the layout file for this panel, asynchronously supporting remote http:// paths
+ void LoadLayoutAsync( const char *pchFile, bool bOverrideExisting = false, bool bPartialLayout = false ) { return m_pIUIPanel->LoadLayoutAsync( pchFile, bOverrideExisting, bPartialLayout ); }
+
+ // loads the layout file for this panel, asynchronously supporting remote http:// paths in css within
+ void LoadLayoutFromStringAsync( const char *pchXMLString, bool bOverrideExisting, bool bPartialLayout = false ) { return m_pIUIPanel->LoadLayoutFromStringAsync( pchXMLString, bOverrideExisting, bPartialLayout ); }
+
+ // Measure self and children. First pass of layout
+ void DesiredLayoutSizeTraverse( float flMaxWidth, float flMaxHeight ) { m_pIUIPanel->DesiredLayoutSizeTraverse( flMaxWidth, flMaxHeight ); }
+ void DesiredLayoutSizeTraverse( float *pflDesiredWidth, float *pflDesiredHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions ) { m_pIUIPanel->DesiredLayoutSizeTraverse( pflDesiredWidth, pflDesiredHeight, flMaxWidth, flMaxHeight, bFinalDimensions ); }
+
+ // Arrange children. Second pass of layout
+ void LayoutTraverse( float x, float y, float flFinalWidth, float flFinalHeight ) { m_pIUIPanel->LayoutTraverse( x, y, flFinalWidth, flFinalHeight ); }
+
+ // methods to invalid certain parts of layout
+ void InvalidateSizeAndPosition() { m_pIUIPanel->InvalidateSizeAndPosition(); }
+ void InvalidatePosition() { m_pIUIPanel->InvalidatePosition(); }
+ bool IsSizeValid() { return m_pIUIPanel->IsSizeValid(); }
+ bool IsPositionValid() { return m_pIUIPanel->IsPositionValid(); }
+ bool IsChildSizeValid() { return m_pIUIPanel->IsChildSizeValid(); }
+ bool IsChildPositionValid() { return m_pIUIPanel->IsChildPositionValid(); }
+ bool IsSizeTransitioning() { return m_pIUIPanel->IsSizeTransitioning(); }
+ bool IsPositionTransitioning() { return m_pIUIPanel->IsPositionTransitioning(); }
+ bool IsChildPositionTransitioning() { return m_pIUIPanel->IsChildPositionTransitioning(); }
+ bool IsChildSizeTransitioning() { return m_pIUIPanel->IsChildSizeTransitioning(); }
+
+ // size getters
+ float GetDesiredLayoutWidth() const { return m_pIUIPanel->GetDesiredLayoutWidth(); }
+ float GetDesiredLayoutHeight() const { return m_pIUIPanel->GetDesiredLayoutHeight(); }
+
+ // Content size is what our contents actually take up, not accounting for fixed/relative
+ // size set on us in styles which affect desired layout size
+ float GetContentWidth() const { return m_pIUIPanel->GetContentWidth(); }
+ float GetContentHeight() const { return m_pIUIPanel->GetContentHeight(); }
+
+ // Actual size is the size given to the panel after layout, hopefully as big as its desired size.
+ // Actual size does NOT include margins (which are really in the parent).
+ float GetActualLayoutWidth() const { return m_pIUIPanel->GetActualLayoutWidth(); }
+ float GetActualLayoutHeight() const { return m_pIUIPanel->GetActualLayoutHeight(); }
+
+ // Render size is the size of the content for rendering, this is either the actual layout size, or if
+ // that is smaller than the content size + padding then it's the content size + padding.
+ float GetActualRenderWidth() { return m_pIUIPanel->GetActualRenderWidth(); }
+ float GetActualRenderHeight() { return m_pIUIPanel->GetActualRenderHeight(); }
+
+ // Offset will include position, alignment, and margin adjustments
+ float GetActualXOffset() const { return m_pIUIPanel->GetActualXOffset(); }
+ float GetActualYOffset() const { return m_pIUIPanel->GetActualYOffset(); }
+
+ // Offset to apply to contents for scrolling
+ float GetContentsYScrollOffset() const { return m_pIUIPanel->GetContentsYScrollOffset(); }
+ float GetContentsXScrollOffset() const { return m_pIUIPanel->GetContentsXScrollOffset(); }
+ float GetContentsYScrollOffsetTarget() const { return m_pIUIPanel->GetContentsYScrollOffsetTarget(); }
+ float GetContentsXScrollOffsetTarget() const { return m_pIUIPanel->GetContentsXScrollOffsetTarget(); }
+ double GetContentsXScrollTransitionStart() const { return m_pIUIPanel->GetContentsXScrollTransitionStart(); }
+ double GetContentsYScrollTransitionStart() const { return m_pIUIPanel->GetContentsYScrollTransitionStart(); }
+ float GetInterpolatedXScrollOffset() { return m_pIUIPanel->GetInterpolatedXScrollOffset(); }
+ float GetInterpolatedYScrollOffset() { return m_pIUIPanel->GetInterpolatedYScrollOffset(); }
+
+ // Can the panel scroll further?
+ bool BCanScrollUp() { return m_pIUIPanel->BCanScrollUp(); }
+ bool BCanScrollDown() { return m_pIUIPanel->BCanScrollDown(); }
+ bool BCanScrollLeft() { return m_pIUIPanel->BCanScrollLeft(); }
+ bool BCanScrollRight() { return m_pIUIPanel->BCanScrollRight(); }
+
+ // style class management
+ void AddClass( const char *pchName ) { m_pIUIPanel->AddClass( pchName ); }
+ void AddClass( CPanoramaSymbol symbol ) { m_pIUIPanel->AddClass( symbol ); }
+ void AddClasses( const char *pchName ) { m_pIUIPanel->AddClasses( pchName ); }
+ void AddClasses( CPanoramaSymbol *pSymbols, uint cSymbols ) { m_pIUIPanel->AddClasses( pSymbols, cSymbols ); }
+ void RemoveClass( const char *pchName ) { m_pIUIPanel->RemoveClass( pchName ); }
+ void RemoveClass( CPanoramaSymbol symName ) { m_pIUIPanel->RemoveClass( symName ); }
+ void RemoveClasses( const CPanoramaSymbol *pSymbols, uint cSymbols ) { m_pIUIPanel->RemoveClasses( pSymbols, cSymbols ); }
+ void RemoveClasses( const char *pchName ) { m_pIUIPanel->RemoveClasses( pchName ); }
+ void RemoveAllClasses() { m_pIUIPanel->RemoveAllClasses(); }
+
+ // bugbug jmccaskey - dangerous cross dll interface signature? Is CUtlVector the same in debug/release?
+ const CUtlVector< CPanoramaSymbol > &GetClasses() const { return m_pIUIPanel->GetClasses(); }
+
+ bool BHasClass( const char *pchName ) const { return m_pIUIPanel->BHasClass( pchName ); }
+ bool BHasClass( CPanoramaSymbol symName ) const { return m_pIUIPanel->BHasClass( symName ); }
+ bool BAscendantHasClass( const char *pchName ) const { return m_pIUIPanel->BAscendantHasClass( pchName ); }
+ bool BAscendantHasClass( CPanoramaSymbol symName ) const { return m_pIUIPanel->BAscendantHasClass( symName ); }
+ void ToggleClass( const char *pchName ) { m_pIUIPanel->ToggleClass( pchName ); }
+ void ToggleClass( CPanoramaSymbol symName ) { m_pIUIPanel->ToggleClass( symName ); }
+ void SetHasClass( const char *pchName, bool bHasClass ) { m_pIUIPanel->SetHasClass( pchName, bHasClass ); }
+ void SetHasClass( CPanoramaSymbol symName, bool bHasClass ) { m_pIUIPanel->SetHasClass( symName, bHasClass ); }
+ void SwitchClass( const char *pchAttribute, const char *pchName ) { m_pIUIPanel->SwitchClass( pchAttribute, pchName ); }
+ void SwitchClass( const char *pchAttribute, CPanoramaSymbol symName ) { m_pIUIPanel->SwitchClass( pchAttribute, symName ); }
+
+ const char *GetID() const { return m_pIUIPanel->GetID(); }
+ bool BHasID() const { return m_pIUIPanel->GetID()[0] != '0'; }
+
+ void SetTabIndex( float flTabIndex ) { m_pIUIPanel->SetTabIndex( flTabIndex ); }
+ void SetSelectionPosition( float flXPos, float flYPos ) { m_pIUIPanel->SetSelectionPosition( flXPos, flYPos ); }
+ void SetSelectionPositionX( float flXPos ) { m_pIUIPanel->SetSelectionPositionX( flXPos ); }
+ void SetSelectionPositionY( float flYPos ) { m_pIUIPanel->SetSelectionPositionY( flYPos ); }
+
+ float GetSelectionPositionX() const { return m_pIUIPanel->GetSelectionPositionX(); }
+ float GetSelectionPositionY() const { return m_pIUIPanel->GetSelectionPositionY(); }
+ float GetTabIndex() const { return m_pIUIPanel->GetTabIndex(); }
+
+ //
+ // Implementation of functions that panorama calls back on UI control classes
+ //
+
+ // kb/mouse management
+ virtual bool OnKeyDown( const KeyData_t &code ) OVERRIDE;
+ virtual bool OnKeyUp( const KeyData_t & code ) OVERRIDE;
+ virtual bool OnKeyTyped( const KeyData_t &unichar ) OVERRIDE;
+ virtual bool OnGamePadDown( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadUp( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadAnalog( const GamePadData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonDown( const MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonUp( const MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonDoubleClick( const MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonTripleClick( const MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseWheel( const MouseData_t &code ) OVERRIDE;
+ virtual void OnMouseMove( float flMouseX, float flMouseY ) OVERRIDE;
+ virtual bool OnClick( IUIPanel *pPanel, const MouseData_t &code ) OVERRIDE;
+
+ // events
+ bool OnScrollDirection( IUIScrollBar *pScrollBar, bool bIncreasePosition, float flDelta );
+ bool OnScrollUp();
+ bool OnScrollDown();
+ bool OnScrollLeft();
+ bool OnScrollRight();
+
+ bool OnPageDirection( IUIScrollBar *pScrollBar, bool bIncreasePosition );
+ bool OnPageUp();
+ bool OnPageDown();
+ bool OnPageLeft();
+ bool OnPageRight();
+
+ // Scrolling
+ void ScrollVertically( float flScrollDelta, bool bImmediateMove = false );
+ void ScrollHorizontally( float flScrollDelta, bool bImmediateMove = false );
+ void ScrollToShowVerticalRange( float flRangeStart, float flRangeEnd );
+ virtual void ScrollToXPercent( float flXPercent );
+ virtual void ScrollToYPercent( float flXPercent );
+
+ // navigation events, override these in children if you want special navigation handling,
+ // shouldn't be needed often though, use tabindex/selectionpos in xml layout files!
+ virtual bool OnMoveUp( int nRepeats );
+ virtual bool OnMoveDown( int nRepeats );
+ virtual bool OnMoveLeft( int nRepeats );
+ virtual bool OnMoveRight( int nRepeats );
+ virtual bool OnTabForward( int nRepeats );
+ virtual bool OnTabBackward( int nRepeats );
+
+
+ // child iteration
+ int GetChildCount() const { return m_pIUIPanel->GetChildCount(); }
+ CPanel2D *GetChild( int i ) const { return ToPanel2D( m_pIUIPanel->GetChild( i ) ); }
+ CPanel2D *GetFirstChild() const { return ToPanel2D( m_pIUIPanel->GetFirstChild() ); }
+ CPanel2D *GetLastChild() const { return ToPanel2D( m_pIUIPanel->GetLastChild() ); }
+ // Return index of child in creation/panel vector order (also default tab order)
+ int GetChildIndex( const CPanel2D *pChild ) const { if( !pChild ) return -1; else return m_pIUIPanel->GetChildIndex( pChild->UIPanel() ); }
+
+ int GetHiddenChildCount() const { return m_pIUIPanel->GetHiddenChildCount(); }
+ CPanel2D *GetHiddenChild( int i ) const { return ToPanel2D( m_pIUIPanel->GetHiddenChild( i ) ); }
+
+ // Gets immediate ancestor of this panel in panel hierarchy
+ CPanel2D *GetParent() const { return ToPanel2D( m_pIUIPanel->GetParent() ); }
+
+ // searches only immediate children
+ CPanel2D *FindChild( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindChild( pchID ) ); }
+
+ // searches all children even outside layout file scope
+ CPanel2D *FindChildTraverse( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindChildTraverse( pchID ) ); }
+
+ // searches any children created from our layout file
+ CPanel2D *FindChildInLayoutFile( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindChildInLayoutFile( pchID ) ); }
+
+ // searches any panel created from our layout file (so parents or children!)
+ CPanel2D *FindPanelInLayoutFile( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindPanelInLayoutFile( pchID ) ); }
+
+ void MoveChildAfter( CPanel2D *pChildToMove, CPanel2D *pBefore ) { return m_pIUIPanel->MoveChildAfter( pChildToMove->UIPanel(), pBefore->UIPanel() ); }
+ void MoveChildBefore( CPanel2D *pChildToMove, CPanel2D *pAfter ) { return m_pIUIPanel->MoveChildBefore( pChildToMove->UIPanel(), pAfter->UIPanel() ); }
+
+ // window management
+ IUIWindow *GetParentWindow() const { return m_pIUIPanel->GetParentWindow(); }
+
+
+ // input & focus
+ bool BAcceptsInput() { return m_pIUIPanel->BAcceptsInput(); }
+ void SetAcceptsInput( bool bAllowInput ) { m_pIUIPanel->SetAcceptsInput( bAllowInput ); }
+ bool BAcceptsFocus() const { return m_pIUIPanel->BAcceptsFocus(); }
+ void SetAcceptsFocus( bool bAllowFocus ) { m_pIUIPanel->SetAcceptsFocus( bAllowFocus ); }
+ bool BCanAcceptInput() { return m_pIUIPanel->BCanAcceptInput(); }
+ void SetDefaultFocus( const char *pchChildID ) { m_pIUIPanel->SetDefaultFocus( pchChildID ); }
+ const char *GetDefaultFocus() const { return m_pIUIPanel->GetDefaultFocus(); }
+ void SetDisableFocusOnMouseDown( bool bDisable ) { m_pIUIPanel->SetDisableFocusOnMouseDown( bDisable ); }
+ bool BFocusOnMouseDown() { return m_pIUIPanel->BFocusOnMouseDown(); }
+ virtual bool BRequiresFocus() { return false; } // Override if your control requires taking focus in order to operate (e.g. TextEntry)
+
+ // Should this panel be the top of an input hierarchy and keep track of focus within itself, not losing focus when a panel in some
+ // other hierarchy changes focus? Use this for panels that are peers like friends vs browser vs mainmenu in tenfoot
+ bool BTopOfInputContext() { return m_pIUIPanel->BTopOfInputContext(); }
+ void SetTopOfInputContext( bool bIsTopOfInputContext ) { return m_pIUIPanel->SetTopOfInputContext( bIsTopOfInputContext ); }
+
+ CPanel2D *GetParentInputContext() { return ToPanel2D( m_pIUIPanel->GetParentInputContext() ); }
+
+ // Get the default input focus child within this panel, may be null
+ CPanel2D *GetDefaultInputFocus() { return ToPanel2D( m_pIUIPanel->GetDefaultInputFocus() ); }
+
+ // Override behavior for getting default input focus, callback from framework
+ virtual IUIPanel *OnGetDefaultInputFocus() OVERRIDE { return NULL; }
+
+ // Set focus to this panel, which will auto-scroll it into full view as well if parent has overflow: scroll
+ bool SetFocus() { return m_pIUIPanel->SetFocus(); }
+
+ // Set the focus to this panel in it's input context, but do not make the context change if some other context currently
+ // has focus
+ bool UpdateFocusInContext() { return m_pIUIPanel->UpdateFocusInContext(); }
+
+ // Set the focus in response to receiving hover (on panels that a parent sets childfocusonhover), this will
+ // never scroll the parent.
+ bool SetFocusDueToHover() { return m_pIUIPanel->SetFocusDueToHover(); }
+
+ void SetInputContextFocus() { m_pIUIPanel->SetInputContextFocus(); }
+
+ // retrieve the style flags (map to CSS psuedo-classes) for this panel
+ uint GetStyleFlags() const { return m_pIUIPanel->GetStyleFlags(); }
+ void AddStyleFlag( EStyleFlags eStyleFlag ) { m_pIUIPanel->AddStyleFlag( eStyleFlag ); }
+ void RemoveStyleFlag( EStyleFlags eStyleFlag ) { m_pIUIPanel->RemoveStyleFlag( eStyleFlag ); }
+ bool IsInspected() const { return m_pIUIPanel->IsInspected(); }
+ bool BHasHoverStyle() const { return m_pIUIPanel->BHasHoverStyle(); }
+ void SetSelected( bool bSelected ) { m_pIUIPanel->SetSelected( bSelected ); }
+ bool IsSelected() const { return m_pIUIPanel->IsSelected(); }
+ bool BHasKeyFocus() const { return m_pIUIPanel->BHasKeyFocus(); }
+ bool BHasDescendantKeyFocus() const { return m_pIUIPanel->BHasDescendantKeyFocus(); }
+ bool IsLayoutLoading() const { return m_pIUIPanel->IsLayoutLoading(); }
+
+ // enable/disable
+ void SetEnabled( bool bEnabled ) { m_pIUIPanel->SetEnabled( bEnabled ); }
+ bool IsEnabled() const { return m_pIUIPanel->IsEnabled(); }
+
+ bool IsActivationEnabled() { return m_pIUIPanel->IsActivationEnabled(); }
+
+ // Set activation disabled on this panel, input/focus still generally work, but Activate events won't be handled, useful to prevent a button
+ // being clicked when out of focus, but leave it able to be focused for later activation or such
+ void SetActivationEnabled( bool bEnabled ) { m_pIUIPanel->SetActivationEnabled( bEnabled ); }
+
+ // Set all our immediate children enabled/disabled
+ void SetAllChildrenActivationEnabled( bool bEnabled ) { m_pIUIPanel->SetAllChildrenActivationEnabled( bEnabled ); }
+
+ // Enable/disable hit testing of this panel, you may want a parent that is never hit test that has a large region, but clicks
+ // just pass through to other things behind it. Children may still hit test.
+ void SetHitTestEnabled( bool bEnabled ) { m_pIUIPanel->SetHitTestEnabled( bEnabled ); }
+ bool BHitTestEnabled() const { return m_pIUIPanel->BHitTestEnabled(); }
+ void SetHitTestEnabledTraverse( bool bEnabled ) { m_pIUIPanel->SetHitTestEnabledTraverse( bEnabled ); }
+
+ void SetOnActivateEvent( IUIEvent *pEvent );
+ void SetOnActivateEvent( const char *pchEventString );
+ void SetOnFocusEvent( IUIEvent *pEvent );
+ void SetOnCancelEvent( IUIEvent *pEvent );
+ void SetOnContextMenuEvent( IUIEvent *pEvent );
+ void SetOnLoadEvent( IUIEvent *pEvent );
+ void SetOnMouseActivateEvent( IUIEvent *pEvent );
+ void SetOnMouseOverEvent( IUIEvent *pEvent );
+ void SetOnMouseOutEvent( IUIEvent *pEvent );
+ void SetOnDblClickEvent( IUIEvent *pEvent );
+ void SetOnTabForwardEvent( IUIEvent *pEvent );
+ void SetOnTabBackwardEvent( IUIEvent *pEvent );
+
+ // bugbug jmccaskey - DELETE ME
+ // bugbug jmccaskey - both of the next two functions need to be deleted, we should
+ // not expose panel event internals like this, but parental button needs some refactoring
+ // first. That refactoring must happen to work at all with javascript panel events anyway.
+ VecUIEvents_t * GetPanelEvents( CPanoramaSymbol symEvent ) { return m_pIUIPanel->GetPanelEvents( symEvent ); }
+ virtual void OnPanelEventSet( CPanoramaSymbol symEvent ) OVERRIDE { }
+
+ bool BHasOnActivateEvent() { return m_pIUIPanel->BHasOnActivateEvent(); }
+ bool BHasOnMouseActivateEvent() { return m_pIUIPanel->BHasOnMouseActivateEvent(); }
+
+ void ClearOnActivateEvent();
+
+ // Dialog variables
+ void SetDialogVariable( const char *pchKey, const char *pchValue );
+ void SetDialogVariable( const char *pchKey, int iVal );
+ // We do NOT have a uint32 type here by design, to prevent you accidenatlly using a RTime32
+ // and getting a number value. Either cast to int for a number or construct a CRTime
+#if defined (SOURCE2_PANORAMA )
+ void SetDialogVariable( const char *pchKey, time_t timeVal );
+ void SetDialogVariable( const char *pchKey, CCurrencyAmount amount );
+#else
+ void SetDialogVariable( const char *pchKey, CAmount amount );
+ void SetDialogVariable( const char *pchKey, CRTime timeVal );
+#endif
+ void SetDialogVariable( const char *varName, const CUtlString &value );
+ void SetDialogVariableLocString( const char *varName, const char *pchValue );
+
+
+
+ // Scrolling controls
+ void ScrollToTop() { m_pIUIPanel->ScrollToTop(); }
+ void ScrollToBottom() { m_pIUIPanel->ScrollToBottom(); }
+ void ScrollToLeftEdge() { m_pIUIPanel->ScrollToLeftEdge(); }
+ void ScrollToRightEdge() { m_pIUIPanel->ScrollToRightEdge(); }
+ void ScrollParentToMakePanelFit( ScrollBehavior_t behavior = SCROLL_BEHAVIOR_DEFAULT, bool bImmediateScroll = false ) { m_pIUIPanel->ScrollParentToMakePanelFit( behavior, bImmediateScroll ); }
+ void ScrollToFitRegion( float x0, float x1, float y0, float y1, ScrollBehavior_t behavior = SCROLL_BEHAVIOR_DEFAULT, bool bDirectParentScrollOnly = false, bool bImmediateScroll = false ) { m_pIUIPanel->ScrollToFitRegion( x0, x1, y0, y1, behavior, bDirectParentScrollOnly, bImmediateScroll ); }
+ bool BCanSeeInParentScroll() { return m_pIUIPanel->BCanSeeInParentScroll(); }
+
+ void OnScrollPositionChanged() { m_pIUIPanel->OnScrollPositionChanged(); }
+ void SetSendChildScrolledIntoViewEvents( bool bSendChildScrolledIntoViewEvents ) { m_pIUIPanel->SetSendChildScrolledIntoViewEvents( bSendChildScrolledIntoViewEvents ); } // this must be enabled on your parent for ScrolledIntoView events to fire and IsScrolledIntoView state to be set
+ void FireScrolledIntoViewEvent() { m_pIUIPanel->FireScrolledIntoViewEvent(); }
+ void FireScrolledOutOfViewEvent() { m_pIUIPanel->FireScrolledOutOfViewEvent(); }
+ bool IsScrolledIntoView() const { return m_pIUIPanel->IsScrolledIntoView(); }
+
+ bool BSelectionPosVerticalBoundary() { return m_pIUIPanel->BSelectionPosVerticalBoundary(); }
+ bool BSelectionPosHorizontalBoundary() { return m_pIUIPanel->BSelectionPosHorizontalBoundary(); }
+
+ // Tell panel to set focus to next panel in specified movement direction/type
+ bool SetFocusToNextPanel( int nRepeats, EFocusMoveDirection moveType, bool bAllowWrap, float flTabIndexCurrent, float flXPosCurrent, float flYPosCurrent, float flXStart, float flYStart ) { return m_pIUIPanel->SetFocusToNextPanel( nRepeats, moveType, bAllowWrap, flTabIndexCurrent, flXPosCurrent, flYPosCurrent, flXStart, flYStart ); }
+ virtual bool OnSetFocusToNextPanel( int nRepeats, EFocusMoveDirection moveType, bool bAllowWrap, float flTabIndexCurrent, float flXPosCurrent, float flYPosCurrent, float flXStart, float flYStart ) OVERRIDE{ return false; }
+ bool SetInputFocusToFirstOrLastChildInFocusOrder( EFocusMoveDirection moveType, float flXStart, float flYStart ) { return m_pIUIPanel->SetInputFocusToFirstOrLastChildInFocusOrder( moveType, flXStart, flYStart ); }
+
+ // hierarchy
+ void SetParent( CPanel2D *pParent ) { m_pIUIPanel->SetParent( pParent ? pParent->UIPanel() : NULL ); }
+ void RemoveAndDeleteChildren() { m_pIUIPanel->RemoveAndDeleteChildren(); }
+ void RemoveAndDeleteChildrenOfType( CPanoramaSymbol symPanelType ) { m_pIUIPanel->RemoveAndDeleteChildrenOfType( symPanelType ); }
+ uint32 GetChildCountOfType( CPanoramaSymbol symPanelType ) { return m_pIUIPanel->GetChildCountOfType( symPanelType ); }
+ bool IsDescendantOf( const CPanel2D *pPanel ) const { return m_pIUIPanel->IsDescendantOf( pPanel ? pPanel->m_pIUIPanel : NULL ); }
+ CPanel2D *FindAncestor( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindAncestor( pchID ) ); }
+
+ // layout file
+ CPanoramaSymbol GetLayoutFileLoadedFrom() const { return m_pIUIPanel->GetLayoutFileLoadedFrom(); }
+
+ // Override this and return true if you know your panel will never draw outside it's bounds,
+ // thus allowing an optimization to skip pushing clipping layers.
+ virtual bool BRequiresContentClipLayer() OVERRIDE { return false; }
+
+ // debug
+ virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties );
+
+ void SetTooltip( CPanel2D *pPanel );
+
+ // Panel events
+ bool DispatchPanelEvent( CPanoramaSymbol symPanelEvent ) { return m_pIUIPanel->DispatchPanelEvent( symPanelEvent ); }
+ bool BParsePanelEvent( CPanoramaSymbol symPanelEvent, const char *pchValue ) { return m_pIUIPanel->BParsePanelEvent( symPanelEvent, pchValue ); }
+ bool BIsPanelEventSet( CPanoramaSymbol symPanelEvent ) { return m_pIUIPanel->BIsPanelEventSet( symPanelEvent ); }
+ bool BIsPanelEvent( CPanoramaSymbol symProperty ) { return m_pIUIPanel->BIsPanelEvent( symProperty ); }
+
+ // the input namespace to use for this panel
+ const char *GetInputNamespace() const { return m_pIUIPanel->GetInputNamespace(); }
+
+ // the mouse cursor to display when hovered
+ virtual EMouseCursors GetMouseCursor() OVERRIDE { return eMouseCursor_Arrow; }
+
+ // controls if clicking on an unfocused panel should set focus
+ void SetMouseCanActivate( EMouseCanActivate eMouseCanActivate, const char *pchOptionalParent = NULL ) { m_pIUIPanel->SetMouseCanActivate( eMouseCanActivate, pchOptionalParent ); }
+ EMouseCanActivate GetMouseCanActivate() { return m_pIUIPanel->GetMouseCanActivate(); }
+ CPanel2D *FindParentForMouseCanActivate() { return ToPanel2D( m_pIUIPanel->FindParentForMouseCanActivate() ); }
+
+ // controls if clicking on an unfocused panel should set focus
+ void SetChildFocusOnHover( bool bEnable ) { m_pIUIPanel->SetChildFocusOnHover( bEnable ); }
+ bool GetChildFocusOnHover() { return m_pIUIPanel->GetChildFocusOnHover(); }
+
+ // Set background images for the panel
+ void SetBackgroundImages( const CUtlVector< CBackgroundImageLayer * > &vecLayers );
+ CUtlVector< CBackgroundImageLayer * > *GetBackgroundImages();
+
+ // called once after registering with UIEngine::CallBeforeStyleAndLayout()
+ virtual void OnCallBeforeStyleAndLayout() OVERRIDE {}
+
+ // clone
+ virtual bool IsClonable();
+ virtual CPanel2D *Clone();
+
+ // sort children
+ void SortChildren( int( __cdecl *pfnCompare )(const ClientPanelPtr_t *, const ClientPanelPtr_t *) ) { m_pIUIPanel->SortChildren( pfnCompare ); }
+
+ // set the namespace to use for input
+ void SetInputNamespace( const char *pchNamespace ) { m_pIUIPanel->SetInputNamespace( pchNamespace ); }
+
+ // override this if you need to have the loc system consider an alternate panel hierarchy for resolving dialog variables
+ virtual IUIPanel *GetLocalizationParent() const OVERRIDE { return GetParent() ? GetParent()->m_pIUIPanel : NULL; }
+
+ // child management, use with caution! normally always managed internally.
+ void AddChild( CPanel2D *pChild ) { m_pIUIPanel->AddChild( pChild->UIPanel() ); }
+
+ // child management, use with caution! normally always managed internally. Returns child index we inserted at.
+ int AddChildSorted( bool( __cdecl *pfnLessFunc )(ClientPanelPtr_t const &p1, ClientPanelPtr_t const &p2), CPanel2D *pChild ) { return m_pIUIPanel->AddChildSorted( pfnLessFunc, pChild->UIPanel() ); }
+
+ // child management, use with caution! normally always managed internally.
+ void RemoveChild( CPanel2D *pChild ) { m_pIUIPanel->RemoveChild( pChild->UIPanel() ); }
+
+ // Check if styles are dirty for the panel
+ bool BStylesDirty() const { return m_pIUIPanel->BStylesDirty(); }
+
+ // Check if styles are possibly dirty for any of our children
+ bool BChildStylesDirty() { return m_pIUIPanel->BChildStylesDirty(); }
+
+ // Set that we need an on styles changed call when styles become non-dirty, even if there is no actual change.
+ void SetOnStylesChangedNeeded() { m_pIUIPanel->SetOnStylesChangedNeeded(); }
+
+
+ // Getter for panel attributes
+ int GetAttribute( const char *pchAttrName, int nDefaultValue ) { return m_pIUIPanel->GetAttribute( pchAttrName, nDefaultValue ); }
+
+ // Getter for panel attributes
+ const char *GetAttribute( const char *pchAttrName, const char * pchDefaultValue ) { return m_pIUIPanel->GetAttribute( pchAttrName, pchDefaultValue ); }
+
+ // Getter for panel attributes
+ uint32 GetAttribute( const char *pchAttrName, uint32 unDefaultValue ) { return m_pIUIPanel->GetAttribute( pchAttrName, unDefaultValue ); }
+
+ // Getter for panel attributes
+ uint64 GetAttribute( const char *pchAttrName, uint64 unDefaultValue ) { return m_pIUIPanel->GetAttribute( pchAttrName, unDefaultValue ); }
+
+ // Setter for panel attributes
+ void SetAttribute( const char *pchAttrName, int nValue ) { m_pIUIPanel->SetAttribute( pchAttrName, nValue ); }
+
+ // Setter for panel attributes
+ void SetAttribute( const char *pchAttrName, const char * pchValue ) { m_pIUIPanel->SetAttribute( pchAttrName, pchValue ); }
+
+ // Setter for panel attributes
+ void SetAttribute( const char *pchAttrName, uint32 unValue ) { m_pIUIPanel->SetAttribute( pchAttrName, unValue ); }
+
+ // Setter for panel attributes
+ void SetAttribute( const char *pchAttrName, uint64 unValue ) { m_pIUIPanel->SetAttribute( pchAttrName, unValue ); }
+
+ // walks parents calculating the top left corner relative to window space
+ void GetPositionWithinWindow( float *pflX, float *pflY );
+
+ // walks parents calculating the top left corner relative to the ancestor's space. If
+ // the passed in panel is NULL or not an ancestor, this will end up being relative to the window space
+ virtual void GetPositionWithinAncestor( CPanel2D *pAncestor, float *pflX, float *pflY ) OVERRIDE;
+
+ bool BHasAnyActiveTransitions();
+
+ // Get the nearest parent that establishes a javascript context, or return ourself if we ourselves create one
+ panorama::CPanel2D *GetJavaScriptContextParent() const { return (CPanel2D*)(m_pIUIPanel->GetJavaScriptContextParent()->ClientPtr()); }
+
+ // Called to ask us to setup object template for Javascript, you can implement this in a child class and then call
+ // the base method (so all the normal panel2d stuff gets exposed), plus call the various RegisterJS helpers yourself
+ // to expose additional panel type specific data/methods.
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ // Callback to client panel to create a scrollbar
+ virtual IUIScrollBar *CreateNewVerticalScrollBar( float flInitialScrollPos ) OVERRIDE;
+
+ // Callback to client panel to create a scrollbar
+ virtual IUIScrollBar *CreateNewHorizontalScrollBar( float flInitialScrollPos ) OVERRIDE;
+
+ // Callback to hide tooltip if it's visible
+ virtual void HideTooltip() OVERRIDE;
+
+ // Has this panel ever been layed out
+ virtual bool BHasBeenLayedOut() const { return m_pIUIPanel->BHasBeenLayedOut(); }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+ void Validate( CValidator &validator, const tchar *pchName );
+ static void ValidateStatics( CValidator &validator, const char *pchName );
+#endif
+
+ void SetLayoutLoadedFromParent( CPanel2D *pParent ) { m_pIUIPanel->SetLayoutLoadedFromParent( pParent ? pParent->UIPanel() : NULL ); }
+
+ IUIImageManager *UIImageManager() { return m_pIUIPanel->UIImageManager(); }
+
+protected:
+ friend class CPanelStyle;
+ friend class CStyleFileSet;
+ friend class CVerticalScrollBar;
+ friend class CHorizontalScrollBar;
+
+ virtual IUIRenderEngine *AccessRenderEngine() { return m_pIUIPanel->GetParentWindow()->UIRenderEngine(); }
+
+ void FirePanelLoadedEvent() { m_pIUIPanel->FirePanelLoadedEvent(); }
+
+ // override to change how this panel is measured
+ virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions ) OVERRIDE
+ {
+ m_pIUIPanel->OnContentSizeTraverse( pflContentWidth, pflContentHeight, flMaxWidth, flMaxHeight, bFinalDimensions );
+ }
+
+ // override to add additional panel events
+ virtual bool BIsClientPanelEvent( CPanoramaSymbol symProperty ) OVERRIDE;
+
+ // override to change how this panel arranges its children
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight ) OVERRIDE { m_pIUIPanel->OnLayoutTraverse( flFinalWidth, flFinalHeight ); }
+
+ virtual void OnStylesChanged() OVERRIDE { if ( m_pIUIPanel->GetParent() ) { m_pIUIPanel->GetParent()->ClientPtr()->OnChildStylesChanged(); } }
+ virtual void OnVisibilityChanged() OVERRIDE {}
+
+ virtual void OnChildStylesChanged() OVERRIDE { }
+
+ // methods for setting properties from a layout file. Default BSetProperties calls BSetProperty on each element.
+ virtual bool BSetProperties( const CUtlVector< ParsedPanelProperty_t > &vecProperties ) OVERRIDE;
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+
+
+ virtual void OnBeforeChildrenChanged() OVERRIDE {}
+ virtual void OnAfterChildrenChanged() OVERRIDE {}
+ virtual void OnRemoveChild( IUIPanel *pChild ) OVERRIDE {}
+
+ virtual void OnInitializedFromLayout() OVERRIDE {}
+
+ void SetLayoutFile( CPanoramaSymbol symLayoutFile ) { m_pIUIPanel->SetLayoutFile( symLayoutFile ); }
+ void SetLayoutFileTraverse( CPanoramaSymbol symLayoutFile );
+
+ void SetMouseTracking( bool bState ) { m_pIUIPanel->SetMouseTracking( bState ); }
+
+ // for cloning
+ bool AreChildrenClonable();
+ virtual void InitClonedPanel( CPanel2D *pPanel );
+
+ // for setting parent disabled style flag
+ //bugbug jmccaskey - these are broken... would like to fix so they are uneeded
+ virtual void AddDisabledFlagToChildren() { }
+ virtual void RemoveDisabledFlagFromChildren() { }
+
+ // Pointer to basic IUIPanel interface from panorama
+ IUIPanel *m_pIUIPanel;
+
+private:
+ // we by design don't have a uint32 overload of this, use this function here to enforce it
+ void SetDialogVariable( const char *pchKey, uint32 nInvalid ) { Assert( !"Invalid call" ); }
+
+ CUtlVector<IUIPanel *> const &AccessChildren() { return m_pIUIPanel->AccessChildren(); }
+ CUtlVector<IUIPanel *> const &JSFindChildrenWithClassTraverse( const char *pchClass );
+
+
+ // event handler functions, these CANNOT be virtual, if you need to override then
+ // have this function call into another helper that is virtual to override behavior
+ bool EventAppendChildrenFromLayoutFileAsync( const CPanelPtr< IUIPanel > &pPanel, const char *pchLayoutFile );
+ bool EventAddStyleClass( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
+ bool EventRemoveStyleClass( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
+ bool EventToggleStyleClass( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
+ bool EventAddStyleClassToEachChild( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
+ bool EventRemoveStyleClassFromEachChild( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
+ bool EventPanelActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+ bool EventPanelCancelled( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+ bool EventPanelContextMenu( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+ bool EventPanelLoaded( const CPanelPtr< IUIPanel > &pPanel );
+ bool EventShowTooltip( const CPanelPtr< IUIPanel > &pPanel );
+ bool EventScrollUp() { return OnScrollUp(); }
+ bool EventScrollDown() { return OnScrollDown(); }
+ bool EventScrollLeft() { return OnScrollLeft(); }
+ bool EventScrollRight() { return OnScrollRight(); }
+ bool EventScrollPanelUp( const CPanelPtr< IUIPanel > &pPanel ) { return OnScrollUp(); }
+ bool EventScrollPanelDown( const CPanelPtr< IUIPanel > &pPanel ) { return OnScrollDown(); }
+ bool EventScrollPanelLeft( const CPanelPtr< IUIPanel > &pPanel ) { return OnScrollLeft(); }
+ bool EventScrollPanelRight( const CPanelPtr< IUIPanel > &pPanel ) { return OnScrollRight(); }
+ bool EventPageUp() { return OnPageUp(); }
+ bool EventPageDown() { return OnPageDown(); }
+ bool EventPageLeft() { return OnPageLeft(); }
+ bool EventPageRight() { return OnPageRight(); }
+ bool EventPagePanelUp( const CPanelPtr< IUIPanel > &pPanel ) { return OnPageUp(); }
+ bool EventPagePanelDown( const CPanelPtr< IUIPanel > &pPanel ) { return OnPageDown(); }
+ bool EventPagePanelLeft( const CPanelPtr< IUIPanel > &pPanel ) { return OnPageLeft(); }
+ bool EventPagePanelRight( const CPanelPtr< IUIPanel > &pPanel ) { return OnPageRight(); }
+ bool EventScrollToTop( const CPanelPtr< IUIPanel > &pPanel );
+ bool EventScrollToBottom( const CPanelPtr< IUIPanel > &pPanel );
+ bool EventMoveUp( int nRepeats ) { return OnMoveUp( nRepeats ); }
+ bool EventMoveDown( int nRepeats ) { return OnMoveDown( nRepeats ); }
+ bool EventMoveLeft( int nRepeats ) { return OnMoveLeft( nRepeats ); }
+ bool EventMoveRight( int nRepeats ) { return OnMoveRight( nRepeats ); }
+ bool EventTabForward( int nRepeats ) { return OnTabForward( nRepeats ); }
+ bool EventTabBackward( int nRepeats ) { return OnTabBackward( nRepeats ); }
+ bool EventImageLoaded( const CPanelPtr< IUIPanel > &pPanel, IImageSource *pImage );
+ bool EventImageFailedLoad( const CPanelPtr< IUIPanel > &pPanel, IImageSource *pImage );
+ bool EventSetPanelEvent( const CPanelPtr< IUIPanel > &pPanel, const char *pchPanelEventName, const char *pchPanelEventAction );
+ bool EventClearPanelEvent( const CPanelPtr< IUIPanel > &pPanel, const char *pchPanelEventName );
+ bool EventIfHasClassEvent( const CPanelPtr< IUIPanel > &pPanel, const char * pchClassName, IUIEvent * pEventToFire );
+ bool EventIfNotHasClassEvent( const CPanelPtr< IUIPanel > &pPanel, const char * pchClassName, IUIEvent * pEventToFire );
+ bool EventIfHoverOtherEvent( const CPanelPtr< IUIPanel > &pPanel, const char *pchOtherPanelID, IUIEvent * pEventToFire );
+ bool EventIfNotHoverOtherEvent( const CPanelPtr< IUIPanel > &pPanel, const char *pchOtherPanelID, IUIEvent * pEventToFire );
+ bool EventIfHoverOverEventInternal( const CPanelPtr< IUIPanel > &pPanel, const char *pchOtherPanelID, IUIEvent * pEventToFire, bool bFireIfHovered );
+ bool EventCheckChildrenScrolledIntoView( const CPanelPtr< IUIPanel > &pPanel ) { return m_pIUIPanel->OnCheckChildrenScrolledIntoView(); }
+ bool EventScrollPanelIntoView( const CPanelPtr< IUIPanel > &pPanel, ScrollBehavior_t behavior, bool bImmediate );
+
+ void Initialize( IUIWindow *window, CPanel2D *parent, const char *pchID, uint32 ePanelFlags );
+ bool BAppyLayoutFile( CLayoutFile *pLayoutFile, CUtlVector< CPanel2D * > *pvecExistingPanels );
+ void DeletePanelsForReloadTraverse( CPanoramaSymbol symPath, CUtlVector< CPanel2D * > *pvecPanelsWithID );
+
+ // Is this a property we must create our children before applying during layout file application?
+ virtual bool BIsDelayedProperty( CPanoramaSymbol symProperty ) OVERRIDE;
+
+ void ClearPanelEventJS( CPanoramaSymbol symPanelEvent ) { m_pIUIPanel->ClearPanelEvents( symPanelEvent ); }
+
+ // Private helper for JS attribute registration
+ void RegisterJSFloatTabIndexSelectionPos( const char *pchjsMemberName, PanelFloatGetter_t pGetFunc, PanelFloatSetter_t pSetFunc );
+
+ void SetDefaultFocusOnMouseDownBehavior();
+
+ // tooltip for panel. Need to keep a safe pointer as the tooltip is a top level window and will be deleted at shutdown automatically
+ CPanelPtr< CPanel2D > m_pTooltip;
+
+ static CUtlVector<IUIPanel *> s_vecMatchingChildren;
+};
+
+
+class CUIScrollBar;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Base class for all types of scroll bars
+//-----------------------------------------------------------------------------
+class CBaseScrollBar : public CPanel2D
+{
+ DECLARE_PANEL2D( CBaseScrollBar, CPanel2D );
+
+public:
+ CBaseScrollBar( CPanel2D *parent, const char * pchPanelID );
+
+ virtual ~CBaseScrollBar();
+
+ IUIScrollBar *Interface();
+
+ // Normalizes the position to be within range min/max
+ void Normalize( bool bImmediateThumbUpdate = false )
+ {
+ if ( m_flWindowStart < m_flRangeMin )
+ m_flWindowStart = m_flRangeMin;
+
+ if ( m_flWindowStart + m_flWindowSize > m_flRangeMax )
+ {
+ m_flWindowStart = m_flRangeMax - m_flWindowSize;
+ m_flWindowStart = RoundFloatToInt( m_flWindowStart );
+ }
+ else
+ {
+ m_flWindowStart = RoundFloatToInt( m_flWindowStart );
+ }
+
+ UpdateLayout( bImmediateThumbUpdate );
+ }
+
+ // Set the scroll range
+ void SetRangeMinMax( float flRangeMin, float flRangeMax )
+ {
+ if ( m_flRangeMin != flRangeMin || m_flRangeMax != flRangeMax )
+ {
+ m_flRangeMin = flRangeMin;
+ m_flRangeMax = flRangeMax;
+
+ if ( GetParent() )
+ GetParent()->InvalidatePosition();
+
+ Normalize( false );
+ }
+ }
+
+ // return the size of the range we have
+ float GetRangeSize() const { return m_flRangeMax - m_flRangeMin; }
+ float GetRangeMin() const { return m_flRangeMin; }
+ float GetRangeMax() const { return m_flRangeMax; }
+
+ // Set the window size
+ void SetScrollWindowSize( float flWindowSize )
+ {
+ if ( m_flWindowSize != flWindowSize )
+ {
+ m_flWindowSize = flWindowSize;
+
+ if ( GetParent() )
+ GetParent()->InvalidatePosition();
+
+ Normalize( false );
+ }
+ }
+
+ // Get scroll window size
+ float GetScrollWindowSize() { return m_flWindowSize; }
+
+ // Set the current window position
+ void SetScrollWindowPosition( float flWindowPos, bool bImmediateMove = false )
+ {
+ m_flWindowStart = flWindowPos;
+ m_flLastScrollTime = UIEngine()->GetCurrentFrameTime();
+
+
+ if ( GetParent() )
+ {
+ if ( GetParent()->IsChildPositionValid() && GetParent()->IsPositionValid() )
+ Normalize( bImmediateMove );
+
+ GetParent()->InvalidatePosition();
+ GetParent()->OnScrollPositionChanged();
+ }
+ }
+
+ double GetLastScrollTime() { return m_flLastScrollTime; }
+
+ // Get scroll window position
+ float GetScrollWindowPosition() { return m_flWindowStart; }
+
+ bool BLastMoveImmediate() { return m_bLastMoveImmediate; }
+
+protected:
+
+ friend class CUIScrollBar;
+
+ CUIScrollBar *m_pScrollBarInterface;
+
+ virtual void UpdateLayout( bool bImmediateMove ) = 0;
+
+ bool m_bLastMoveImmediate;
+
+ double m_flLastScrollTime;
+ float m_flRangeMin;
+ float m_flRangeMax;
+ float m_flWindowSize;
+ float m_flWindowStart;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Default Scrollbar
+//-----------------------------------------------------------------------------
+class CScrollBar : public CBaseScrollBar
+{
+ DECLARE_PANEL2D( CScrollBar, CBaseScrollBar );
+
+public:
+ CScrollBar( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CScrollBar();
+
+ virtual void ScrollToMousePos() = 0;
+
+ virtual void OnMouseMove( float flMouseX, float flMouseY )
+ {
+ // If there's a transform set on the parent, adjust the input as appropriate.
+ Vector vMousePosition( flMouseX, flMouseY, 0.0f );
+ if ( GetParent() )
+ {
+ VMatrix matParentTransform = GetParent()->AccessStyle()->GetTransform3DMatrix();
+ vMousePosition = matParentTransform * vMousePosition;
+ }
+
+ m_flMouseX = vMousePosition.x;
+ m_flMouseY = vMousePosition.y;
+
+ if ( m_bMouseDown )
+ ScrollToMousePos();
+ }
+
+ virtual bool OnMouseButtonDown( const MouseData_t &code )
+ {
+ // Only interested in left clicks
+ if ( code.m_MouseCode != MOUSE_LEFT )
+ return BaseClass::OnMouseButtonDown( code );
+
+ AddClass( "MouseDown" );
+
+ if ( m_pScrollThumb->BHasHoverStyle() )
+ m_bMouseWentDownOnThumb = true;
+ else
+ m_bMouseWentDownOnThumb = false;
+ m_bMouseDown = true;
+ m_flMouseStartX = m_flMouseX;
+ m_flMouseStartY = m_flMouseY;
+ m_flScrollStartPosition = GetScrollWindowPosition();
+ ScrollToMousePos();
+
+ return true;
+ }
+
+ virtual bool OnMouseButtonUp( const MouseData_t &code )
+ {
+ // Only interested in left clicks
+ if ( code.m_MouseCode != MOUSE_LEFT )
+ return BaseClass::OnMouseButtonDown( code );
+
+ m_bMouseDown = false;
+ ScrollToMousePos();
+
+ RemoveClass( "MouseDown" );
+
+ return true;
+ }
+
+protected:
+ CPanel2D *m_pScrollThumb;
+
+ bool m_bMouseDown;
+ bool m_bMouseWentDownOnThumb;
+
+ float m_flMouseX;
+ float m_flMouseY;
+ float m_flMouseStartX;
+ float m_flMouseStartY;
+ float m_flScrollStartPosition;
+};
+
+
+class CUIScrollBar : public IUIScrollBar
+{
+public:
+ CUIScrollBar( CBaseScrollBar *pParent ) { m_pParent = pParent; }
+
+ virtual IUIPanel* UIPanel() OVERRIDE { return m_pParent->UIPanel(); }
+ virtual IUIPanelClient* ClientPtr() OVERRIDE { return m_pParent; }
+
+ virtual void Normalize( bool bImmediateThumbUpdate ) OVERRIDE { return m_pParent->Normalize( bImmediateThumbUpdate ); }
+
+ virtual void SetRangeMinMax( float flRangeMin, float flRangeMax ) OVERRIDE { return m_pParent->SetRangeMinMax( flRangeMin, flRangeMax ); }
+
+ virtual float GetRangeSize() const OVERRIDE { return m_pParent->GetRangeSize(); }
+ virtual float GetRangeMin() const OVERRIDE { return m_pParent->GetRangeMin(); }
+ virtual float GetRangeMax() const OVERRIDE { return m_pParent->GetRangeMax(); }
+
+ // Set the window size
+ virtual void SetScrollWindowSize( float flWindowSize ) OVERRIDE { return m_pParent->SetScrollWindowSize( flWindowSize ); }
+
+ // Get scroll window size
+ virtual float GetScrollWindowSize() OVERRIDE { return m_pParent->GetScrollWindowSize(); }
+
+ // Set the current window position
+ virtual void SetScrollWindowPosition( float flWindowPos, bool bImmediateMove = false ) OVERRIDE { return m_pParent->SetScrollWindowPosition( flWindowPos, bImmediateMove ); }
+
+ virtual float GetLastScrollTime() OVERRIDE { return m_pParent->GetLastScrollTime(); }
+
+ // Get scroll window position
+ virtual float GetScrollWindowPosition() OVERRIDE { return m_pParent->GetScrollWindowPosition(); }
+
+ // Return true if the user is manually dragging the scrollbar with the mouse
+ virtual bool BLastMoveImmediate() OVERRIDE { return m_pParent->BLastMoveImmediate(); }
+
+private:
+ CBaseScrollBar *m_pParent;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Vertical scroll bar
+//-----------------------------------------------------------------------------
+class CVerticalScrollBar : public CScrollBar
+{
+ DECLARE_PANEL2D( CVerticalScrollBar, CScrollBar );
+
+public:
+ CVerticalScrollBar( CPanel2D *parent, const char * pchPanelID ) : CScrollBar( parent, pchPanelID )
+ {
+ m_pScrollThumb->AddClass( "VerticalScrollThumb" );
+ }
+
+ void ScrollToMousePos()
+ {
+ CPanel2D *pPanel = GetParent();
+ if ( pPanel )
+ {
+ float flHeight = GetActualLayoutHeight();
+ if ( flHeight > 0.00001f )
+ {
+ if ( m_bMouseWentDownOnThumb )
+ {
+ float flPercentDiff = (m_flMouseY - m_flMouseStartY) / flHeight;
+ float flPositionOffset = flPercentDiff * pPanel->GetContentHeight();
+ float flPosition = m_flScrollStartPosition + flPositionOffset;
+ SetScrollWindowPosition( clamp( flPosition, 0.0f, pPanel->GetContentHeight() - GetScrollWindowSize() ), true );
+ }
+ else
+ {
+ float flPercent = m_flMouseY / flHeight;
+ float flPos = pPanel->GetContentHeight() * flPercent;
+ SetScrollWindowPosition( clamp( flPos, 0.0f, pPanel->GetContentHeight() - GetScrollWindowSize() ), true );
+ }
+ }
+ }
+ }
+
+
+ virtual ~CVerticalScrollBar() {}
+
+protected:
+ virtual void UpdateLayout( bool bImmediateMove );
+
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Horizontal scroll bar
+//-----------------------------------------------------------------------------
+class CHorizontalScrollBar : public CScrollBar
+{
+ DECLARE_PANEL2D( CHorizontalScrollBar, CScrollBar );
+
+public:
+ CHorizontalScrollBar( CPanel2D *parent, const char * pchPanelID ) : CScrollBar( parent, pchPanelID )
+ {
+ m_pScrollThumb->AddClass( "HorizontalScrollThumb" );
+ }
+
+ void ScrollToMousePos()
+ {
+ CPanel2D *pPanel = GetParent();
+ if ( pPanel )
+ {
+ float flWidth = GetActualLayoutWidth();
+ if ( flWidth > 0.00001f )
+ {
+ if ( m_bMouseWentDownOnThumb )
+ {
+ float flPercentDiff = ( m_flMouseX - m_flMouseStartX ) / flWidth;
+ float flPositionOffset = flPercentDiff * pPanel->GetContentWidth();
+ float flPosition = m_flScrollStartPosition + flPositionOffset;
+ SetScrollWindowPosition( clamp( flPosition, 0.0f, pPanel->GetContentWidth() - GetScrollWindowSize() ), true );
+ }
+ else
+ {
+ float flPercent = m_flMouseX / flWidth;
+ float flPos = pPanel->GetContentWidth() * flPercent;
+ SetScrollWindowPosition( clamp( flPos, 0.0f, pPanel->GetContentWidth() - GetScrollWindowSize() ), true );
+ }
+ }
+ }
+ }
+
+ virtual ~CHorizontalScrollBar() {}
+
+protected:
+
+ virtual void UpdateLayout( bool bImmediateMove );
+};
+
+#pragma warning(pop)
+
+
+} // namespace panorama
+
+#endif // PANEL2D_H
diff --git a/public/panorama/controls/panelhandle.h b/public/panorama/controls/panelhandle.h
new file mode 100644
index 0000000..bbd868b
--- /dev/null
+++ b/public/panorama/controls/panelhandle.h
@@ -0,0 +1,56 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANELHANDLE_H
+#define PANELHANDLE_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier0/platform.h"
+
+namespace panorama
+{
+
+const uint64 k_ulInvalidPanelHandle64 = 0x00000000FFFFFFFF;
+
+//
+// Safe handle to a panel. To get pointer to actual panel, call IUIEngine::GetPanelPtr
+//
+struct PanelHandle_t
+{
+ int32 m_iPanelIndex; // index into panel map
+ uint32 m_unSerialNumber; // unique number used to ensure that panel at m_iPanelIndex is still the panel we originally pointed to
+
+ bool operator<( const PanelHandle_t &rhs ) const
+ {
+ if ( m_iPanelIndex != rhs.m_iPanelIndex )
+ return m_iPanelIndex < rhs.m_iPanelIndex;
+
+ return m_unSerialNumber < rhs.m_unSerialNumber;
+ }
+
+ bool operator==( const PanelHandle_t &rhs ) const
+ {
+ return (m_iPanelIndex == rhs.m_iPanelIndex) && (m_unSerialNumber == rhs.m_unSerialNumber);
+ }
+
+ bool operator!=( const PanelHandle_t &rhs ) const
+ {
+ return !(*this == rhs);
+ }
+
+
+ static const PanelHandle_t &InvalidHandle()
+ {
+ static PanelHandle_t s_invalid = { k_ulInvalidPanelHandle64 >> 32, 0xffffffff & k_ulInvalidPanelHandle64 };
+ return s_invalid;
+ }
+};
+
+} // namespace panorama
+
+#endif // PANELHANDLE_H
diff --git a/public/panorama/controls/panelptr.h b/public/panorama/controls/panelptr.h
new file mode 100644
index 0000000..79a1838
--- /dev/null
+++ b/public/panorama/controls/panelptr.h
@@ -0,0 +1,153 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANELPTR_H
+#define PANELPTR_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panelhandle.h"
+#include "../iuiengine.h"
+#include "../iuipanelclient.h"
+#include "panorama/panoramacxx.h"
+#include "generichash.h"
+
+namespace panorama
+{
+
+class CPanel2D;
+
+//
+// Safe pointer to a panel
+//
+template < class T >
+class CPanelPtr
+{
+public:
+ CPanelPtr() { Clear(); }
+ CPanelPtr( const CPanelPtr &rhs ) { *this = rhs; }
+ CPanelPtr( const IUIPanel *pPanel ) { Set( pPanel ); }
+ CPanelPtr( const IUIPanelClient *pPanel ) { Set( pPanel ? pPanel->UIPanel() : (IUIPanel*)NULL ); }
+
+ CPanelPtr< T > &operator=( const CPanelPtr< T > &ptr ) { m_handle = ptr.m_handle; return *this; }
+ T *operator=( T *pPanel ) { Set( pPanel ); return pPanel; }
+
+ void Clear()
+ {
+ m_handle = PanelHandle_t::InvalidHandle();
+ }
+
+ void Set( const IUIPanel *pPanel )
+ {
+ if( pPanel )
+ m_handle = UIEngine()->GetPanelHandle( pPanel );
+ else
+ Clear();
+ }
+
+ void Set( const IUIPanelClient *pPanel )
+ {
+ if( pPanel )
+ m_handle = UIEngine()->GetPanelHandle( pPanel->UIPanel() );
+ else
+ Clear();
+ }
+
+ T * Get() const
+ {
+ if ( m_handle == PanelHandle_t::InvalidHandle() )
+ return NULL;
+
+ // allow us to be called to return NULL pointers early
+ if( UIEngine() == NULL )
+ {
+ return NULL;
+ }
+
+ if( panorama_is_base_of< IUIPanel, T >::value )
+ {
+ T* pPanel = (T *)UIEngine()->GetPanelPtr( m_handle );
+ if ( pPanel )
+ {
+ return pPanel;
+ }
+ else
+ {
+ m_handle = PanelHandle_t::InvalidHandle();
+ return NULL;
+ }
+ }
+ else
+ {
+ IUIPanel *pPanel = UIEngine()->GetPanelPtr( m_handle );
+ if( pPanel )
+ return (T*)(pPanel->ClientPtr());
+ else
+ {
+ m_handle = PanelHandle_t::InvalidHandle();
+ return NULL;
+ }
+ }
+ }
+
+ T *operator->() const
+ {
+ return Get();
+ }
+
+ template < class U >
+ bool operator==( const CPanelPtr< U > &rhs ) const
+ {
+ return ( m_handle == rhs.GetPanelHandle() );
+ }
+
+ template < class U >
+ bool operator!=( const CPanelPtr< U > &rhs ) const
+ {
+ return !operator==( rhs );
+ }
+
+ template < class U >
+ bool operator<( const CPanelPtr< U > &rhs) const
+ {
+ return m_handle < rhs.m_handle;
+ }
+
+ uint64 GetHandleAsUInt64() const
+ {
+ uint64 val = 0;
+ val = ((uint64)m_handle.m_unSerialNumber)<<32 | m_handle.m_iPanelIndex;
+ return val;
+ }
+
+ void SetFromUInt64( uint64 ulValue )
+ {
+ m_handle.m_unSerialNumber = ulValue>>32;
+ m_handle.m_iPanelIndex = 0xFFFFFFFF & ulValue;
+ }
+
+ const PanelHandle_t &GetPanelHandle() const { return m_handle; }
+ bool BPreviouslySet() { return ( m_handle != PanelHandle_t::InvalidHandle() ); }
+
+private:
+ mutable PanelHandle_t m_handle;
+};
+
+template< class T >
+inline uint32 HashItem( const CPanelPtr<T> &item )
+{
+#if defined( SOURCE2_PANORAMA )
+ return ::HashItem( item );
+#else
+ return HashItemAsBytes( item );
+#endif
+}
+
+} // namespace panorama
+
+
+#endif // PANELPTR_H
diff --git a/public/panorama/controls/progressbar.h b/public/panorama/controls/progressbar.h
new file mode 100644
index 0000000..3771e4e
--- /dev/null
+++ b/public/panorama/controls/progressbar.h
@@ -0,0 +1,51 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_PROGRESSBAR_H
+#define PANORAMA_PROGRESSBAR_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/controls/panel2d.h"
+
+namespace panorama
+{
+
+//////////////////////////////////////////////////////////////////////////
+//
+// progress bar, just sizes two panels to represent progress
+//
+class CProgressBar: public CPanel2D
+{
+ DECLARE_PANEL2D( CProgressBar, CPanel2D );
+public:
+ CProgressBar( CPanel2D *pParent, const char *pchID );
+ virtual ~CProgressBar();
+
+ void SetMin( float flMin ) { m_flMin = flMin; InvalidateSizeAndPosition(); }
+ void SetMax( float flMax ) { m_flMax = flMax; InvalidateSizeAndPosition(); }
+ void SetValue( float flValue ) { m_flCur = flValue; InvalidateSizeAndPosition(); }
+ float GetValue() { return m_flCur; }
+
+protected:
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+
+private:
+ float m_flMin;
+ float m_flMax;
+ float m_flCur;
+
+ CPanel2D *m_ppanelLeft;
+ CPanel2D *m_ppanelRight;
+
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_PROGRESSBAR_H
+
+
diff --git a/public/panorama/controls/slider.h b/public/panorama/controls/slider.h
new file mode 100644
index 0000000..6ac4d9f
--- /dev/null
+++ b/public/panorama/controls/slider.h
@@ -0,0 +1,123 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_SLIDER_H
+#define PANORAMA_SLIDER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/controls/panel2d.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT1( SliderValueChanged, float );
+DECLARE_PANEL_EVENT1( SlottedSliderValueChanged, int );
+DECLARE_PANEL_EVENT1( SliderFocusChanged, bool );
+
+//-----------------------------------------------------------------------------
+// Purpose: Slider control which includes track, progress & thumb
+//-----------------------------------------------------------------------------
+class CSlider: public CPanel2D
+{
+ DECLARE_PANEL2D( CSlider, CPanel2D );
+
+public:
+ CSlider( CPanel2D *pParent, const char *pchID );
+ virtual ~CSlider();
+
+ enum ESliderDirection
+ {
+ k_EDirectionVertical,
+ k_EDirectionHorizontal
+ };
+
+ void SetMin( float flMin ) { m_flMin = flMin; InvalidateSizeAndPosition(); }
+ void SetMax( float flMax ) { m_flMax = flMax; InvalidateSizeAndPosition(); }
+ void SetIncrement( float flValue ) { m_flIncrement = flValue; }
+ virtual void SetValue( float flValue );
+ float GetValue() { return m_flCur; }
+ float GetDefaultValue() { return m_flDefault; }
+ void SetDefaultValue ( float flValue ) { m_flDefault = flValue; }
+ void SetShowDefaultValue( bool bShow ) { m_bShowDefault = bShow; }
+ void SetDirection( ESliderDirection eValue );
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue );
+
+ virtual bool OnMouseButtonDown( const MouseData_t &code ) OVERRIDE;
+ virtual bool OnMouseButtonUp( const MouseData_t &code ) OVERRIDE;
+ virtual void OnMouseMove( float flMouseX, float flMouseY ) OVERRIDE;
+ virtual bool OnMoveUp( int nRepeats ) OVERRIDE;
+ virtual bool OnMoveRight( int nRepeats ) OVERRIDE;
+ virtual bool OnMoveDown( int nRepeats ) OVERRIDE;
+ virtual bool OnMoveLeft( int nRepeats ) OVERRIDE;
+
+ virtual bool OnActivate(panorama::EPanelEventSource_t eSource);
+ virtual bool OnCancel(panorama::EPanelEventSource_t eSource);
+ virtual void OnStyleFlagsChanged();
+ virtual void OnResetToDefaultValue();
+
+ void SetRequiresSelection( bool bRequireSelection ) { m_bRequiresSelection = bRequireSelection; }
+
+protected:
+ bool EventPanelActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ void SetValueFromMouse( float x, float y );
+ float GetMin() { return m_flMin; }
+ float GetMax() { return m_flMax; }
+ ESliderDirection GetDirection() { return m_eDirection; }
+
+ CPanel2D *m_pThumb;
+ CPanel2D *m_pTrack;
+ CPanel2D *m_pProgress;
+ CPanel2D *m_pDefaultTick;
+ bool EventActivated( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, panorama::EPanelEventSource_t eSource );
+ bool EventCancelled( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, panorama::EPanelEventSource_t eSource );
+ bool EventStyleFlagsChanged( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel );
+ bool EventResetToDefault( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel );
+
+private:
+ bool AllowInteraction( void );
+ bool ShouldShowDefault( void ) { return m_bShowDefault; }
+
+ float m_flMin;
+ float m_flMax;
+ float m_flDefault;
+ float m_flCur;
+ float m_flLast;
+ float m_flIncrement;
+ bool m_bRequiresSelection;
+ bool m_bDraggingThumb;
+ bool m_bShowDefault;
+ ESliderDirection m_eDirection;
+
+ float m_flLastMouseX;
+ float m_flLastMouseY;
+};
+
+class CSlottedSlider : public CSlider
+{
+ DECLARE_PANEL2D( CSlottedSlider, CSlider );
+public:
+ CSlottedSlider( CPanel2D *pParent, const char *pchID );
+ virtual ~CSlottedSlider();
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue );
+ virtual void SetValue( float flValue );
+ void SetValue( int nValue );
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ int GetCurrentNotch() { return m_nCurNotch; }
+
+private:
+ int m_nNumNotches;
+ int m_nCurNotch;
+ CUtlVector< CPanel2D* > m_pNotches;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_SLIDER_H
diff --git a/public/panorama/controls/slideshow.h b/public/panorama/controls/slideshow.h
new file mode 100644
index 0000000..cfa14ec
--- /dev/null
+++ b/public/panorama/controls/slideshow.h
@@ -0,0 +1,114 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_SLIDESHOW_H
+#define PANORAMA_SLIDESHOW_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/controls/panel2d.h"
+#include "panorama/controls/mousescroll.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT1( SlideShowPanelChanged, int );
+DECLARE_PANEL_EVENT0( SlideShowOnLayoutInitialized );
+
+//-----------------------------------------------------------------------------
+// Purpose: Panel that shows a slideshow of panels
+//-----------------------------------------------------------------------------
+class CSlideShow : public CPanel2D
+{
+ DECLARE_PANEL2D( CSlideShow, CPanel2D );
+
+public:
+ CSlideShow( CPanel2D *pParent, const char *pchID );
+ virtual ~CSlideShow();
+
+ void AddPanel( CPanel2D *pPanel, bool bDontSetFocusBySideEffect );
+ void RemoveAndDeletePanel( CPanel2D *pPanel );
+ void SetManageFocus( bool bManageFocus ) { m_bManageFocus = bManageFocus; }
+
+ void SetFocusIndex( int iFocus, bool bSkipChildCountCheck = false );
+ int GetFocusIndex() { return m_iFocusChild; }
+ CPanel2D *GetFocusChild() { return GetChild(m_iFocusChild); }
+ bool BFocusChildRightMost() { return (m_iFocusChild == (GetChildCount() - 1)); }
+
+ virtual bool OnMoveRight( int nRepeats );
+ virtual bool OnMoveLeft( int nRepeats );
+ virtual bool OnTabForward( int nRepeats );
+ virtual bool OnTabBackward( int nRepeats );
+
+ virtual void Paint();
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+
+ virtual bool OnSetFocusToNextPanel( int nRepeats, EFocusMoveDirection moveType, bool bAllowWrap, float flTabIndexCurrent, float flXPosCurrent, float flYPosCurrent, float flXStart, float fYStart ) OVERRIDE
+ {
+ switch( moveType )
+ {
+ case k_ENextInTabOrder:
+ if ( m_bManageFocus && OnTabForward( nRepeats ) )
+ return true;
+ break;
+ case k_ENextByXPosition:
+ if ( m_bManageFocus && OnMoveRight( nRepeats ) )
+ return true;
+ break;
+ case k_EPrevInTabOrder:
+ if ( m_bManageFocus && OnTabBackward( nRepeats ) )
+ return true;
+ break;
+ case k_EPrevByXPosition:
+ if ( m_bManageFocus && OnMoveLeft( nRepeats ) )
+ return true;
+ break;
+ case k_ENextByYPosition:
+ if ( m_bManageFocus && OnMoveDown( nRepeats ) )
+ return true;
+ break;
+ case k_EPrevByYPosition:
+ if ( m_bManageFocus && OnMoveUp( nRepeats ) )
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ virtual panorama::IUIPanel *OnGetDefaultInputFocus() OVERRIDE;
+
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+#endif
+
+protected:
+ bool EventInputFocusSet( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+ bool EventCarouselMouseScroll( const CPanelPtr< IUIPanel > &ptrPanel, int cRepeat );
+ bool EventSlideShowOnLayoutInitialized( const CPanelPtr< IUIPanel > &ptrPanel );
+ virtual void OnInitializedFromLayout();
+ void SetPanelStyles( int iOldFocus, int iNewFocus );
+ void LayoutMouseScrollRegions( float flFinalWidth, float flFinalHeight );
+
+private:
+ virtual void AddDisabledFlagToChildren() OVERRIDE;
+ virtual void RemoveDisabledFlagFromChildren() OVERRIDE;
+ void SetIndividualPanelStyle( int iChild, int iOldFocus, int iNewFocus );
+ void SetMouseScrollVisibility( int iFocus );
+
+ int m_iFocusChild;
+ bool m_bManageFocus;
+ CMouseScrollRegion *m_pLeftMouseScrollRegion;
+ CMouseScrollRegion *m_pRightMouseScrollRegion;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_SLIDESHOW_H
diff --git a/public/panorama/controls/source2/renderpanel.h b/public/panorama/controls/source2/renderpanel.h
new file mode 100644
index 0000000..b6e1c67
--- /dev/null
+++ b/public/panorama/controls/source2/renderpanel.h
@@ -0,0 +1,45 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_RENDERPANEL_H
+#define PANORAMA_RENDERPANEL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/controls/panel2d.h"
+#include "materialsystem2/imaterialsystem2utils.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Render panel, to use for raw source2 render operations directly in render thread
+//-----------------------------------------------------------------------------
+class CRenderPanel : public CPanel2D
+{
+ DECLARE_PANEL2D( CRenderPanel, CPanel2D );
+
+public:
+ CRenderPanel( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CRenderPanel();
+
+ void SetRenderThreadCallback( CRenderThreadCallback *pRenderCallback );
+
+ // Override and make return true if you need to paint every single frame, and will not manually call SetRepaint when you want to repaint
+ virtual bool BShouldAlwaysRepaint() { return true; }
+
+protected:
+ // Override of Panel2D paint
+ virtual void Paint() OVERRIDE;
+
+private:
+ CRenderThreadCallback *m_pRenderCallback;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_RENDERPANEL_H
diff --git a/public/panorama/controls/textentry.h b/public/panorama/controls/textentry.h
new file mode 100644
index 0000000..87068d0
--- /dev/null
+++ b/public/panorama/controls/textentry.h
@@ -0,0 +1,361 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_TEXTENTRY_H
+#define PANORAMA_TEXTENTRY_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "panorama/text/iuitextlayout.h"
+#include "panorama/textinput/textinput.h"
+#include "panorama/textinput/textinput_settings.h"
+#if !defined(SOURCE2_PANORAMA)
+#include "../common/globals.h"
+#include "../common/reliabletimer.h"
+#include "../common/framefunction.h"
+#endif
+#include "panorama/uischeduleddel.h"
+#include "imesystem/imeuiinterface.h"
+
+namespace panorama
+{
+
+class CLabel;
+class CTextEntryAutocomplete;
+
+#if defined( SOURCE2_PANORAMA )
+class CTextEntryIMEControls;
+#endif // defined( SOURCE2_PANORAMA )
+
+DECLARE_PANEL_EVENT1( TextEntrySubmit, const char * ); // always raised when user is done submitting text
+DECLARE_PANEL_EVENT0( TextEntryChanged ); // call CTextEntry::RaiseChangeEvents() to enable
+DECLARE_PANEL_EVENT0( TextEntryShowTextInputHandler );
+DECLARE_PANEL_EVENT0( TextEntryHideTextInputHandler );
+DECLARE_PANEL_EVENT0( TextEntryInsertFromClipboard );
+DECLARE_PANEL_EVENT0( TextEntryCopyToClipboard );
+DECLARE_PANEL_EVENT0( TextEntryCutToClipboard );
+
+//-----------------------------------------------------------------------------
+// Purpose: text entry
+//-----------------------------------------------------------------------------
+class CTextEntry : public CPanel2D, public ITextInputControl
+#if defined( SOURCE2_PANORAMA )
+ , public IIMEUITextField
+#endif // defined( SOURCE2_PANORAMA )
+{
+ DECLARE_PANEL2D( CTextEntry, CPanel2D );
+
+public:
+ CTextEntry( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CTextEntry();
+
+ virtual void SetupJavascriptObjectTemplate() OVERRIDE;
+
+ void SetUndoHistoryEnabled( bool bEnabled );
+ void ClearUndoHistory();
+
+ virtual bool OnKeyDown( const KeyData_t &code );
+ virtual bool OnKeyTyped( const KeyData_t &unichar );
+ virtual bool OnKeyUp( const KeyData_t & code ) { return BaseClass::OnKeyUp( code ); }
+ virtual void Paint();
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+ virtual void OnInitializedFromLayout();
+ virtual void OnStylesChanged();
+
+ virtual void OnMouseMove( float flMouseX, float flMouseY );
+ virtual bool OnMouseButtonDown( const MouseData_t &code );
+ virtual bool OnMouseButtonUp( const MouseData_t &code );
+ virtual bool OnMouseButtonDoubleClick( const MouseData_t &code );
+ virtual bool OnMouseButtonTripleClick( const MouseData_t &code );
+
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+ virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties ) OVERRIDE;
+
+ virtual bool BRequiresContentClipLayer() { return m_bMayDrawOutsideBounds; }
+
+ void SetMode( ETextInputMode_t mode );
+ ETextInputMode_t GetMode() { return m_modeInput; }
+
+ void SetText( const char *pchValue );
+ const char *PchGetText() const;
+ const wchar_t *PwchGetText() const;
+ void SetPlaceholderText( const char *pchValue );
+ const char *PchGetPlaceholderText() const;
+ void SetMaxChars( uint unMaxChars );
+ uint GetCharCount() const { return m_vecWCharData.Count() - 1; } // m_vecWCharData is terminated, so remove extra char count
+ uint GetMaxCharCount() const { return m_unMaxChars; }
+ int32 GetCursorOffset() const { return m_nCursorOffset; }
+ void SetCursorOffset( int32 nCursoroffset );
+ bool BSupportsImmediateTextReturn() { return true; }
+ void RequestControlString() { Assert( false ); } // no op, we already have the string
+
+ // Insert clipboard contents into text entry
+ void InsertFromClipboard();
+
+ // Cut selected text to clipboard
+ void CutToClipboard();
+
+ // Copy selected text to clipboard
+ void CopyToClipboard();
+
+ bool OnInsertFromClipboard( const CPanelPtr< IUIPanel > &pPanel );
+ bool OnCutToClipboard( const CPanelPtr< IUIPanel > &pPanel );
+ bool OnCopyToClipboard( const CPanelPtr< IUIPanel > &pPanel );
+
+ void SetAlwaysRenderCaret( bool bAlwaysRenderCaret );
+
+ // Delete currently selected text
+ void DeleteSelection( bool bDontPushUndoHistory );
+
+ // Clear selection region, leaving nothing selected
+ void ClearSelection();
+
+ // select all the text in the control
+ void SelectAll();
+
+ // Lock the selection in place; it can only be unlocked or deleted
+ void LockSelection( bool bLockSelection ) { m_bSelectionLocked = bLockSelection; }
+
+ // Insert characters at cursor
+ void InsertCharacterAtCursor( const wchar_t &unichar );
+ void InsertCharactersAtCursor( const wchar_t *pwch, size_t cwch );
+
+ bool BIsValidCharacter( const wchar_t wch );
+
+ void RaiseChangeEvents( bool bEnable ) { m_bRaiseChangeEvents = bEnable; }
+
+ virtual EMouseCursors GetMouseCursor();
+
+ // ITextInputControl helpers
+ virtual CPanel2D *GetAssociatedPanel() { return this; }
+
+ panorama::CTextInputHandler *GetTextInputHandler() { return m_pTextInputHandler.Get(); }
+ void SetTextInputHandler( panorama::CTextInputHandler *pTextInputHandler );
+
+ virtual bool BRequiresFocus() OVERRIDE { return true; }
+
+ // Autocomplete
+ void ClearAutocomplete( void );
+ void AddAutocomplete( const char *pszOption );
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName );
+#endif
+ int32 GetSelectionStart() { return m_nSelectionStartIndex; }
+ int32 GetSelectionEnd() { return m_nSelectionEndIndex; }
+
+ // Interface for IIMEUITextField
+#if defined( SOURCE2_PANORAMA )
+ virtual void IME_SetLoggingChannel( LoggingChannelID_t loggingChannel ) OVERRIDE;
+ virtual bool IME_IsEnabled() OVERRIDE;
+ virtual IMEUIObjectType IME_GetObjectType() OVERRIDE;
+ virtual wchar_t *IME_GetCompositionString() OVERRIDE;
+ virtual void IME_CreateCompositionString() OVERRIDE;
+ virtual void IME_ClearCompositionString() OVERRIDE;
+ virtual void IME_CommitCompositionString( const wchar_t *pString ) OVERRIDE;
+ virtual void IME_SetCompositionStringText( const wchar_t *pString ) OVERRIDE;
+ virtual void IME_SetCompositionStringPosition( uint32 nPos ) OVERRIDE;
+ virtual void IME_SetCursorInCompositionString( uint32 nPos ) OVERRIDE;
+ virtual uint32 IME_GetCaretIndex() OVERRIDE;
+ virtual uint32 IME_GetBeginIndex() OVERRIDE;
+ virtual uint32 IME_GetEndIndex() OVERRIDE;
+ virtual void IME_ReplaceCharacters( const wchar_t *pString, uint32 nStart, uint32 nEnd ) OVERRIDE;
+ virtual void IME_SetSelection( uint32 nStart, uint32 nEnd ) OVERRIDE;
+ virtual void IME_SetWideCursor( bool bWide ) OVERRIDE;
+ virtual void IME_HighlightCompositionStringText( uint32 nPos, uint32 nLen, IMETextHighlightStyle highlightStyle ) OVERRIDE;
+ virtual void IME_DeleteSelection() OVERRIDE;
+ virtual void IME_RemoveInputWindow() OVERRIDE;
+ virtual void IME_DisplayInputWindow( const wchar_t *pReadingString, const IMERectF *pPosition ) OVERRIDE;
+ virtual void IME_RepositionInputWindow( const IMERectF *pPosition ) OVERRIDE;
+ virtual void IME_CreateList( int nPageSize, int nListStartsAt1 ) OVERRIDE;
+ virtual void IME_RemoveList() OVERRIDE;
+ virtual void IME_ClearList() OVERRIDE;
+ virtual void IME_ShowList( bool bShow ) OVERRIDE;
+ virtual void IME_RepositionCandidateList( const IMERectF *pPosition ) OVERRIDE;
+ virtual void IME_SelectItemInList( int32 nItemToSelect ) OVERRIDE;
+ virtual void IME_AddToList( const wchar_t *pCandidateString ) OVERRIDE;
+#endif // defined( SOURCE2_PANORAMA )
+
+protected:
+ virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions );
+ virtual bool BIsClientPanelEvent( CPanoramaSymbol symProperty ) OVERRIDE;
+
+private:
+ bool OnTextEntryShowTextInputHandler( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+ bool OnTextEntryHideTextInputHandler( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+ bool EventActivated ( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+ bool OnTextEntryScrollToCursor( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+ bool EventInputFocusTopLevelChanged( CPanelPtr< CPanel2D > ptrPanel );
+ bool HandleTextInputFinished( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, bool bFinished, char const *pchText );
+ bool EventInputFocusSet( const CPanelPtr< IUIPanel > &ptrPanel );
+ bool EventInputFocusLost( const CPanelPtr< IUIPanel > &ptrPanel );
+
+ IUITextLayout *CreateTextLayout( float flWidth, float flHeight );
+ void RemoveCharacter( int32 offset );
+ void RaiseTextChangedEvent();
+
+ void UpdateSelectionToInclude( int32 unPreviousCursor, int32 unNewCursorPos );
+
+ void Undo();
+ void Redo();
+ void PushUndoStack();
+ void PushRedoStack();
+
+ void UpdateCapsLockWarning();
+ void OnScheduledCapsLockCheck();
+
+ void MoveCaretToEnd( bool bIsShiftHeld );
+
+ const wchar_t *PwchGetTextDisplay(); // honors password-entry mode
+
+ bool m_bUndoHistoryEnabled;
+
+ bool m_bContentSizeDirty; // content size is dirty - text has changed
+
+ float m_flMaxWidthLastContentSize;
+ float m_flMaxHeightLastContentSize;
+
+ bool m_bCaretPositionDirty;
+ bool m_bAlwaysRenderCaret;
+
+ bool m_bMayDrawOutsideBounds;
+
+ bool m_bShowTextInputHandlerOnLeftMouseUp;
+
+ bool m_bSelectionLocked;
+ bool m_bMultiline; // used to determine whether to swallow multiline-only characters (\n, etc.)
+
+ Vector2D m_LastMousePos;
+ CUtlVector<wchar_t> m_vecWCharData;
+ CUtlVector<wchar_t> m_vecWCharDataPasswordDisplay;
+ mutable CUtlString m_UTF8String;
+ mutable bool m_bUTF8StringInvalid;
+ uint32 m_unMaxChars;
+
+ int32 m_nCursorOffset;
+ Vector2D m_CaretCoords;
+ float m_flCaretHeight;
+
+ bool m_bLeftMouseIsDown;
+ bool m_bSelectionRectDirty;
+ int32 m_nSelectionStartIndex;
+ int32 m_nSelectionEndIndex;
+
+ bool m_bScrollableSizeDirty;
+ float m_flLastFinalWidthToScrollable;
+ float m_flLastFinalHeightToScrollable;
+
+ // Translation of text in single line entries to scroll to show where the cursor is
+ float m_flTextXTranslate;
+
+ CPanelPtr< CTextInputHandler > m_pTextInputHandler;
+
+ CUtlVector<IUITextLayout::HitTestRegionRect_t> m_vecSelectionRects;
+ panorama::CTextInputHandlerSettings m_settingsTextInput;
+
+ CUtlVector< wchar_t * > m_vecUndoStack;
+ CUtlVector< wchar_t * > m_vecRedoStack;
+
+ double m_flFocusTime;
+
+ // only raise text changed events when requested, as we have to convert every character to UTF8 from unicode
+ bool m_bRaiseChangeEvents;
+
+ ETextInputMode_t m_modeInput;
+
+ bool m_bDisplayInput;
+ bool m_bWarnOnCapsLock;
+ panorama::CUIScheduledDel m_scheduledCapsLockCheck;
+
+ CLabel *m_pPlaceholderText;
+
+ CPanelPtr< CTextEntryAutocomplete > m_pAutocompleteMenu;
+
+#if defined( SOURCE2_PANORAMA )
+ // IME State
+ bool m_bIMEWideCursor;
+ CUtlVector< wchar_t > m_IMECompositionString;
+ int32 m_nIMECompositionCursor;
+ int32 m_nIMEStartingCursorInsertionOffset;
+ int32 m_nIMEEndingCursorInsertionOffset;
+ bool m_bIMERejectBackspace;
+
+ CPanelPtr< CTextEntryIMEControls > m_pIMEControls;
+ LoggingChannelID_t m_IMELoggingChannel;
+#endif // defined( SOURCE2_PANORAMA )
+};
+
+class CTextEntryAutocomplete : public CPanel2D
+{
+ DECLARE_PANEL2D( CTextEntryAutocomplete, CPanel2D );
+
+public:
+ CTextEntryAutocomplete( CTextEntry *pParent, const char *pchPanelID );
+ virtual ~CTextEntryAutocomplete();
+
+ void DeleteSelf( bool bSetFocusToTarget = true );
+
+ void AddOption( const char *pszOption );
+
+private:
+ // forward keys, arrows back to my parent
+ virtual bool OnKeyDown( const KeyData_t &code );
+ virtual bool OnKeyUp( const KeyData_t & code );
+ virtual bool OnKeyTyped( const KeyData_t &unichar );
+
+ void PositionNearParent();
+
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+
+ // events
+ bool EventPanelActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
+ bool EventInputFocusSet( const CPanelPtr< IUIPanel > &pPanel );
+
+ void SuggestionSelected( CLabel *pLabel );
+
+ CPanelPtr< CTextEntry > m_pTextEntryParent;
+ bool m_bClosing;
+};
+
+#if defined( SOURCE2_PANORAMA )
+class CTextEntryIMEControls : public CPanel2D
+{
+ DECLARE_PANEL2D( CTextEntryIMEControls, CPanel2D );
+
+public:
+ CTextEntryIMEControls( CTextEntry *pParent, const char *pchPanelID );
+ virtual ~CTextEntryIMEControls();
+
+ void ClearCandidateList();
+ void CreateCandidateList( int nPageSize, int nListStartsAt1 );
+ void AddCandidate( const wchar_t *pszCandidateString );
+ void SetSelectedCandidate( int nItemToSelect );
+ void ShowCandidateList( bool bShow );
+
+ void SetReadingString( const wchar_t *pReadingString );
+
+private:
+ void PositionNearParent();
+
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+
+ CPanelPtr< CTextEntry > m_pTextEntryParent;
+
+ CPanelPtr< CLabel > m_pReadingStringLabel;
+ CPanelPtr< CPanel2D > m_pCandidateList;
+
+ int m_nCandidateListPageSize;
+ int m_nCandidateListSelectedIndex;
+
+ bool m_bShowCandidateList;
+};
+#endif // defined( SOURCE2_PANORAMA )
+
+} // namespace panorama
+
+#endif // PANORAMA_TEXTENTRY_H
diff --git a/public/panorama/controls/tooltip.h b/public/panorama/controls/tooltip.h
new file mode 100644
index 0000000..31071b3
--- /dev/null
+++ b/public/panorama/controls/tooltip.h
@@ -0,0 +1,81 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_TOOLTIP_H
+#define PANORAMA_TOOLTIP_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "../uievent.h"
+#include "label.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT0( TooltipVisible );
+
+//-----------------------------------------------------------------------------
+// Purpose: Top level panel for a tooltip
+//-----------------------------------------------------------------------------
+class CTooltip : public CPanel2D
+{
+ DECLARE_PANEL2D( CTooltip, CPanel2D );
+
+public:
+ CTooltip( IUIWindow *pParent, const char *pchName );
+ CTooltip( CPanel2D *pParent, const char *pchName );
+ virtual ~CTooltip();
+
+ void SetTooltipTarget( const CPanelPtr< IUIPanel >& targetPanelPtr );
+
+ // Get/set tooltip visibility. This is actually determined by a .css class,
+ // so that transitions can be supported
+ bool IsTooltipVisible() const;
+ void SetTooltipVisible( bool bVisible );
+
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight );
+
+ // request the tooltip to do positioning on the next layout
+ virtual void CalculatePosition() { m_bReposition = true; InvalidateSizeAndPosition(); }
+
+private:
+
+ void Init();
+ void UpdatePosition();
+
+ bool EventTooltipVisible( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel );
+
+ bool m_bReposition;
+
+ CPanelPtr< IUIPanel > m_pTooltipTarget;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Simple tooltip that just shows a string of text
+//-----------------------------------------------------------------------------
+class CTextTooltip : public CTooltip
+{
+ DECLARE_PANEL2D( CTextTooltip, CTooltip );
+
+public:
+ CTextTooltip( IUIWindow *pParent, const char *pchName );
+ CTextTooltip( CPanel2D *pParent, const char *pchName );
+ virtual ~CTextTooltip();
+
+ void SetText( const char *pchText, CLabel::ETextType eTextType = CLabel::k_ETextTypePlain );
+
+private:
+ void Init();
+
+ CLabel *m_pText;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_TOOLTIP_H \ No newline at end of file
diff --git a/public/panorama/controls/verticalscrolllist.h b/public/panorama/controls/verticalscrolllist.h
new file mode 100644
index 0000000..a9b6c51
--- /dev/null
+++ b/public/panorama/controls/verticalscrolllist.h
@@ -0,0 +1,38 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef VERTICALSCROLLLIST_H
+#define VERTICALSCROLLLIST_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panel2d.h"
+#include "panorama/controls/label.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: CVerticalScrollList
+//-----------------------------------------------------------------------------
+class CVerticalScrollList : public CPanel2D
+{
+ DECLARE_PANEL2D( CVerticalScrollList, CPanel2D );
+
+public:
+ CVerticalScrollList( CPanel2D *parent, const char * pchPanelID );
+ virtual ~CVerticalScrollList();
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+
+private:
+};
+
+
+} // namespace panorama
+
+#endif // VERTICALSCROLLLIST_H
diff --git a/public/panorama/controls/vumeter.h b/public/panorama/controls/vumeter.h
new file mode 100644
index 0000000..2dc3a11
--- /dev/null
+++ b/public/panorama/controls/vumeter.h
@@ -0,0 +1,86 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef VUMETER_H
+#define VUMETER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/controls/panel2d.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT1( VUMeterBarsChanged, int );
+
+//////////////////////////////////////////////////////////////////////////
+//
+// volume bars control for volume/mic levels
+//
+class CVUMeter: public panorama::CPanel2D
+{
+ DECLARE_PANEL2D( CVUMeter, panorama::CPanel2D );
+public:
+ CVUMeter( panorama::CPanel2D *pParent, const char *pchID );
+ virtual ~CVUMeter();
+
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
+
+ virtual void OnInitializedFromLayout();
+
+ int GetNumActiveBars() const { return m_numActive; }
+ void SetNumActiveBars( int numActive );
+
+ int GetNumBarsTotal() const { return m_numBars; }
+
+ virtual bool OnMoveLeft( int cRepeats );
+ virtual bool OnMoveRight( int cRepeats );
+
+ // Override these to avoid focus slipping away when setting with analog
+ virtual bool OnMoveUp( int nRepeats );
+ virtual bool OnMoveDown( int nRepeats );
+
+ virtual bool OnMouseButtonUp(const MouseData_t &code);
+ virtual bool OnMouseWheel(const MouseData_t &code);
+ virtual void OnMouseMove(float flMouseX, float flMouseY);
+
+ virtual bool OnActivate(panorama::EPanelEventSource_t eSource);
+ virtual bool OnCancel(panorama::EPanelEventSource_t eSource);
+ virtual void OnStyleFlagsChanged();
+
+ // if VU meter is "writable," it will be a tab stop, and be focusable. when activated
+ // it will enter a mode where you can set the bar with the dpad. if VU meter is not
+ // writable, it just displays a value.
+ void SetWritable( bool bWritable );
+
+ bool EventActivated( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, panorama::EPanelEventSource_t eSource );
+ bool EventCancelled( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, panorama::EPanelEventSource_t eSource );
+ bool EventStyleFlagsChanged( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel );
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
+#endif
+
+protected:
+ bool OnLeftRight( int dx );
+
+ bool m_bWritable;
+ int m_numBars, m_numActive;
+ CPanoramaSymbol m_symBarPanelType;
+ CPanoramaSymbol m_symBarPanelAddClass;
+ CPanoramaSymbol m_symBarPanelActiveClass;
+ CUtlVector< panorama::CPanel2D * > m_arrBars;
+
+ float m_flLastMouseX;
+ float m_flLastMouseY;
+};
+
+} // namespace panorama
+
+#endif // VUMETER_H
+
+
diff --git a/public/panorama/data/iimagesource.h b/public/panorama/data/iimagesource.h
new file mode 100644
index 0000000..d6be4f4
--- /dev/null
+++ b/public/panorama/data/iimagesource.h
@@ -0,0 +1,93 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IIMAGESOURCE_H
+#define IIMAGESOURCE_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+enum EImageFormat
+{
+ k_EImageFormatUnknown,
+ k_EImageFormatR8G8B8A8,
+ k_EImageFormatB8G8R8A8_PreMultiplied,
+ k_EImageFormatA8
+};
+
+class CPanel2D;
+
+//
+// Data source for image data used to render an asset
+//
+class IImageSource: public panorama::IUIJSObject
+{
+public:
+ virtual bool BIsValid() = 0;
+ virtual uint32 GetTextureID() = 0;
+ virtual int GetWidth() = 0;
+ virtual int GetHeight() = 0;
+ virtual EImageFormat ImageFormat() = 0;
+ virtual bool BIsAnimating() = 0;
+
+ // Ref counting
+ virtual int GetRefCount() = 0;
+ virtual int AddRef() = 0;
+ virtual int Release() = 0;
+
+ virtual const char *GetJSTypeName() { return "IImageSource"; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName ) = 0;
+#endif
+protected:
+
+ friend class CImageResourceManager;
+};
+
+
+//
+// main interface to load images for display in the ui
+//
+const int k_ResizeNone = -1;
+class IUIImageManager
+{
+public:
+
+ // load image data from a URL (file://blah, http://blah/bob.tga, etc), pchDefaultResourceURL may be null, and is what will be used while the real resource is loaded
+ // if it is set. As such it must be a local file. bPrioritizeLoad will make your request jump to the head of the queue if it is an image over HTTP, use sparingly!
+ // nResizeWidth and nResizeHeight do nothing if -1, if one is set and the other -1 the image is resized before being made into a texture, but aspect ratio is maintained
+ // with the specified dimension at the set size, if both are set the image will be stretched if needed.
+ virtual IImageSource *LoadImageFromURL( const IUIPanel *pPanel, const char *pchDefaultResourceURL, const char *pchResourceURL, bool bPrioritizeLoad, EImageFormat imgFormatOut, int32 nResizeWidth = k_ResizeNone, int32 nResizeHeight = k_ResizeNone, bool bAllowAnimation = true ) = 0;
+
+ // load image data from image file (png/jpg/tga) bytes you already have in memory, pchDefaultResourceURL may be null, and is what will be used while the real resource is loaded
+ // if it is set. As such it must be a local file.
+ virtual IImageSource *LoadImageFileFromMemory( const IUIPanel *pPanel, const char *pchResourceURLDefault, const CUtlBuffer &bufFile, int nResizeWidth = panorama::k_ResizeNone, int nResizeHeight = panorama::k_ResizeNone, bool bAllowAnimation = true ) = 0;
+
+ // load image data from RGBA bytes you already have in memory, pchDefaultResourceURL may be null, and is what will be used while the real resource is loaded
+ // if it is set. As such it must be a local file.
+ virtual IImageSource *LoadImageFromMemory( const IUIPanel *pPanel, const char *pchDefaultResourceURL, const CUtlBuffer &bufData, int nWide, int nTall, EImageFormat imgFormatIn = k_EImageFormatR8G8B8A8, int nResizeWidth = k_ResizeNone, int nResizeHeight = k_ResizeNone, bool bAllowAnimation = true ) = 0;
+
+ virtual CUtlString GetPchImageSourcePath( IImageSource *pImageSource ) = 0;
+
+ virtual void ReloadChangedImage( IImageSource *pImageToReload ) = 0;
+
+ virtual void ReloadChangedFile( const char *pchFile ) = 0;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName ) = 0;
+#endif
+};
+
+DECLARE_PANEL_EVENT1( ImageLoaded, IImageSource * );
+DECLARE_PANEL_EVENT1( ImageFailedLoad, IImageSource * );
+
+} // namespace panorama
+
+#endif // IIMAGESOURCE_H \ No newline at end of file
diff --git a/public/panorama/data/imageloader.h b/public/panorama/data/imageloader.h
new file mode 100644
index 0000000..891dd32
--- /dev/null
+++ b/public/panorama/data/imageloader.h
@@ -0,0 +1,229 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IMAGESOURCE_H
+#define IMAGESOURCE_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/data/iimagesource.h"
+#include "panorama/controls/panelptr.h"
+#include "tier1/utlbuffer.h"
+#include "tier1/fileio.h"
+#include "tier1/utlmap.h"
+#include "refcount.h"
+#include "../../panorama/uifileresource.h"
+#include "tier1/utldelegate.h"
+
+namespace panorama
+{
+
+// Helper to determine byte size of a pixel in a given format
+int GetFormatPixelBytes( EImageFormat format );
+
+class CMovie;
+class IUIRenderEngine;
+class IUITexture;
+class CImageData;
+
+
+// Helper for converting rgba8 to a8 throwing out rgb channels
+void ConvertRGBA8ToA8( CUtlBuffer &bufIn, CUtlBuffer &bufOut, uint32 unWide, uint32 unTall );
+
+class CImageProxySource;
+class CImageLoaderTask;
+
+#if defined( SOURCE2_PANORAMA )
+class CLoadFromVTexTask;
+#endif
+
+enum ESourceFormats
+{
+ k_ESourceFormatUnknown,
+ k_ESourceFormatTGA,
+ k_ESourceFormatPNG,
+ k_ESourceFormatJPG,
+ k_ESourceFormatRawRGBA,
+ k_ESourceFormatGIF,
+ k_ESourceFormatVTEX
+};
+
+class CImageData;
+typedef void (ImageDecodeCallback_t)( bool bSuccess, CImageData *pNewImage, CUtlBuffer *pBufDecoded );
+
+class CImageDecodeWorkItem
+{
+public:
+ CImageDecodeWorkItem( IUIRenderEngine *pRenderEngine, CUtlBuffer &bufDataInMayModify, const char *pchFilePath, int nWide, int nTall, int nResizeWidth, int nResizeHeight,
+ EImageFormat formatOut, bool bAllowAnimation, CUtlDelegate< ImageDecodeCallback_t > del );
+ ~CImageDecodeWorkItem();
+
+ void RunWorkItem();
+ void DispatchResult();
+
+private:
+
+ bool m_bSuccess;
+ IUIRenderEngine *m_pSurface;
+ CUtlBuffer *m_pBuffer;
+ CUtlString m_strFilePath;
+ int m_nWide;
+ int m_nTall;
+ int m_nResizeWidth;
+ int m_nResizeHeight;
+ EImageFormat m_eFormat;
+ bool m_bAllowAnimation;
+ CImageData *m_pNewImage;
+
+ CUtlDelegate< ImageDecodeCallback_t > m_Del;
+};
+
+class CImageDecodeWorkThreadPool;
+class CImageDecodeThread : public CThread
+{
+public:
+ CImageDecodeThread( CImageDecodeWorkThreadPool *pParent )
+ {
+ m_bExit = false;
+ m_pParent = pParent;
+ }
+
+ ~CImageDecodeThread()
+ {
+
+ }
+
+ void Stop() { m_bExit = true; }
+
+ virtual int Run() OVERRIDE;
+
+private:
+ volatile bool m_bExit;
+ CImageDecodeWorkThreadPool *m_pParent;
+};
+
+class CImageDecodeWorkThreadPool
+{
+public:
+ CImageDecodeWorkThreadPool();
+ ~CImageDecodeWorkThreadPool();
+
+ // Run frame on main thread
+ void RunFrame();
+
+ void AddWorkItem( CImageDecodeWorkItem *pWorkItem );
+
+private:
+
+ friend class CImageDecodeThread;
+ CImageDecodeThread * m_pWorkThreads[1];
+
+ CThreadMutex m_AsyncIoLock;
+ CThreadEvent m_ThreadEvent;
+ CUtlLinkedList< CImageDecodeWorkItem *, int > m_llAsyncIORequests;
+ CUtlLinkedList< CImageDecodeWorkItem *, int > m_llAsyncIOResults;
+};
+
+//
+// A container of images we have loaded
+//
+class CImageResourceManager : public IUIImageManager
+{
+public:
+ CImageResourceManager( IUIRenderEngine *pSurface );
+ ~CImageResourceManager();
+ virtual void Shutdown();
+
+ virtual IImageSource *LoadImageFromURL( const IUIPanel *pPanel, const char *pchResourceURLDefault, const char *pchResourceURL, bool bPrioritizeLoad, EImageFormat imgFormatOut, int32 nResizeWidth = panorama::k_ResizeNone, int32 nResizeHeight = panorama::k_ResizeNone, bool bAllowAnimation = true );
+ virtual IImageSource *LoadImageFileFromMemory( const IUIPanel *pPanel, const char *pchResourceURLDefault, const CUtlBuffer &bufFile, int nResizeWidth = panorama::k_ResizeNone, int nResizeHeight = panorama::k_ResizeNone, bool bAllowAnimation = true );
+ virtual IImageSource *LoadImageFromMemory( const IUIPanel *pPanel, const char *pchResourceURLDefault, const CUtlBuffer &bufRGBA, int nWide, int nTall, EImageFormat imgFormatIn = k_EImageFormatR8G8B8A8, int nResizeWidth = panorama::k_ResizeNone, int nResizeHeight = panorama::k_ResizeNone, bool bAllowAnimation = true );
+ virtual CUtlString GetPchImageSourcePath( IImageSource *pImageSource ) OVERRIDE;
+
+ virtual void ReloadChangedFile( const char *pchFile ) OVERRIDE;
+ virtual void ReloadChangedImage( IImageSource *pImageToReload ) OVERRIDE;
+
+ bool OnImageUnreferenced( CImageProxySource *pImage );
+
+ void RunFrame();
+
+ void QueueImageDecodeWorkItem( CImageDecodeWorkItem *pWorkItem );
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+private:
+ IImageSource *LoadImageInternal( const IUIPanel *pPanel, CFileResource &fileResourceDefault, CFileResource &fileResource, bool bPrioritizeLoad, EImageFormat imgFormatOut, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
+ CImageProxySource *GetDefaultImage( CFileResource &fileDefault, EImageFormat imgFormatOut, bool bAllowAnimation );
+
+ friend class CLoadFileURLTask;
+ friend class CLoadFileLocalTask;
+ friend class CImageLoaderTask;
+#if defined( SOURCE2_PANORAMA )
+ friend class CLoadFromVTexTask;
+#endif
+
+ // Internally adds image to our tracking maps
+ void AddImageToManager( CFileResource &resource, CImageProxySource *pImageProxy, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
+ bool RemoveImageFromManager( IImageSource *pImage );
+
+ // Loads a resource, returns vector index
+ bool OnImageLoaded( CFileResource & resource, CImageData *pImage, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
+ bool OnFailedImageLoad( CFileResource & resource, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
+ void AddLoad( CFileResource &resource, EImageFormat eFormat, bool bPrioritizeLoad, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
+
+ // Synchronous load only used for initial global default image
+ bool LoadLocalFileSynchronous( CFileResource &resource, EImageFormat eFormat, bool bAllowAnimation );
+
+#if defined( SOURCE2_PANORAMA )
+ bool FixupFileResourceToCompiledImage( CFileResource &fileResource );
+#endif
+
+ struct UrlImageKey_t
+ {
+ CFileResource fileResource;
+ int32 nTargetWidth;
+ int32 nTargetHeight;
+ bool bAllowAnimation;
+
+ // Sort on size only
+ bool operator <( const UrlImageKey_t &l ) const
+ {
+ if ( nTargetWidth < l.nTargetWidth )
+ return true;
+ else if ( nTargetWidth > l.nTargetWidth )
+ return false;
+
+ if ( nTargetHeight < l.nTargetHeight )
+ return true;
+ else if ( nTargetHeight > l.nTargetHeight )
+ return false;
+
+ if ( bAllowAnimation && !l.bAllowAnimation )
+ return true;
+ else if ( !bAllowAnimation && l.bAllowAnimation )
+ return false;
+
+ return fileResource < l.fileResource;
+ }
+ };
+ CUtlMap< UrlImageKey_t, CImageProxySource *, int, CDefLess< UrlImageKey_t > > m_mapImagesByURL;
+ CUtlMap< IImageSource *, UrlImageKey_t, int, CDefLess< IImageSource *> > m_mapAllImages;
+
+ CUtlVector< CImageLoaderTask * > m_vecLoaderTasksToStart;
+ CUtlRBTree< CImageLoaderTask *, int, CDefLess< CImageLoaderTask * > > m_treeLoadTasks;
+
+ IUIRenderEngine *m_pSurface;
+
+ CImageDecodeWorkThreadPool *m_pImageDecodePool;
+
+ bool m_bInited;
+};
+
+} // namespace panorama
+
+#endif // IMAGESOURCE_H \ No newline at end of file
diff --git a/public/panorama/data/panoramavideoplayer.h b/public/panorama/data/panoramavideoplayer.h
new file mode 100644
index 0000000..5478dbd
--- /dev/null
+++ b/public/panorama/data/panoramavideoplayer.h
@@ -0,0 +1,196 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose: Panorama specific video player code
+//=============================================================================//
+
+#ifndef PANORAMA_VIDEO_PLAYER_H
+#define PANORAMA_VIDEO_PLAYER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier1/smartptr.h"
+#include "../common/video/ivideoplayer.h"
+#include "panorama/controls/panelptr.h"
+
+namespace panorama
+{
+
+class IUIRenderEngine;
+class IUIDoubleBufferedYUV420Texture;
+class CPanoramaVideoPlayer;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Renders video frames from video player for tenfoot
+//-----------------------------------------------------------------------------
+class CVideoPlayerVideoRenderer : public IVideoPlayerVideoCallback
+{
+public:
+ CVideoPlayerVideoRenderer( IUIRenderEngine *pSurface );
+ virtual ~CVideoPlayerVideoRenderer();
+
+ uint32 GetTextureID() { return m_unTextureID; }
+ uint32 GetTextureWidth();
+ uint32 GetTextureHeight();
+
+ // IVideoPlayerVideoCallback
+ virtual bool BPresentYUV420Texture( uint nWidth, uint nHeight, void *pPlaneY, void *pPlaneU, void *pPlaneV, uint unStrideY, uint unStrideU, uint unStrideV ) OVERRIDE;
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const char *pchName );
+#endif
+
+private:
+ CInterlockedUInt m_unTextureID;
+
+ // used by video threads
+ IUIRenderEngine *m_pSurface;
+ IUIDoubleBufferedYUV420Texture *m_pYUV420DoubleBufferedTexture;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Renders audio frames from video player for tenfoot
+//-----------------------------------------------------------------------------
+class CVideoPlayerAudioRenderer : public IVideoPlayerAudioCallback
+{
+public:
+ CVideoPlayerAudioRenderer();
+ virtual ~CVideoPlayerAudioRenderer();
+
+ void SetPlaybackVolume( float flVolume );
+ void MarkShuttingDown();
+ void Shutdown();
+
+ // IVideoPlayerAudioCallback
+ virtual bool InitAudioOutput( int nSampleRate, int nChannels ) OVERRIDE;
+ virtual void FreeAudioOutput() OVERRIDE;
+ virtual bool IsReadyForAudioData() OVERRIDE;
+ virtual void *GetAudioBuffer() OVERRIDE;
+ virtual uint32 GetAudioBufferSize() OVERRIDE;
+ virtual uint32 GetAudioBufferMinSize() OVERRIDE;
+ virtual void CommitAudioBuffer( uint32 unBytes ) OVERRIDE;
+ virtual uint32 GetRemainingCommittedAudio() OVERRIDE;
+ virtual uint32 GetMixedMilliseconds() OVERRIDE;
+ virtual uint32 GetPlaybackLatency() OVERRIDE;
+ virtual void Pause() OVERRIDE;
+ virtual void Resume() OVERRIDE;
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const char *pchName );
+#endif
+
+private:
+ bool OnInitAudioMainThread( CVideoPlayerAudioRenderer *pThis, int nSampleRate, int nChannels );
+ bool OnFreeAudioMainThread( CVideoPlayerAudioRenderer *pThis );
+
+ CInterlockedInt m_bShuttingDown;
+ CThreadEvent m_eventWait;
+#ifdef SUPPORTS_AUDIO
+ IAudioOutputStream *m_pAudioStream;
+#endif
+ float m_flVolume;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Dispatches events to main panorama thread
+//-----------------------------------------------------------------------------
+typedef CUtlDelegate< void ( EVideoPlayerEvent ) > VideoPlayerEventDelegate_t;
+class CVideoPlayerEventDispatcher : public IVideoPlayerEventCallback
+{
+public:
+ CVideoPlayerEventDispatcher( CPanoramaVideoPlayer *pPlayer );
+ ~CVideoPlayerEventDispatcher();
+
+ void RegisterEventListener( IUIPanel *pPanel );
+ void UnregisterEventListener( IUIPanel *pPanel );
+
+ void RegisterEventCallback( VideoPlayerEventDelegate_t del );
+ void UnregisterEventCallback( VideoPlayerEventDelegate_t del );
+
+ bool VideoPlayerEventUIThread( CVideoPlayerEventDispatcher *pDispatcher, EVideoPlayerEvent eEvent );
+
+ // IVideoPlayerEventCallback
+ virtual void VideoPlayerEvent( EVideoPlayerEvent eEvent ) OVERRIDE;
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const char *pchName );
+#endif
+
+private:
+ void DispatchVideoEvent( EVideoPlayerEvent eEvent, IUIPanel *pTarget );
+
+ CPanoramaVideoPlayer *m_pPlayer;
+ CUtlVector< CPanelPtr< IUIPanel > > m_vecListeners;
+ CUtlVector< VideoPlayerEventDelegate_t > m_vecCallbacks;
+ double m_flLastRepeatEventDispatch;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper to create a tenfoot video player
+//-----------------------------------------------------------------------------
+class CPanoramaVideoPlayer : public IVideoPlayer, public ::CRefCount
+{
+public:
+ CPanoramaVideoPlayer( IUIPanel *pPanel );
+ CPanoramaVideoPlayer( IUIRenderEngine *pSurface );
+ virtual ~CPanoramaVideoPlayer();
+
+ virtual uint32 GetTextureID() { return m_videoCallback.GetTextureID(); }
+ uint32 GetTextureWidth() { return m_videoCallback.GetTextureWidth(); }
+ uint32 GetTextureHeight() { return m_videoCallback.GetTextureHeight(); }
+
+ void RegisterEventListener( IUIPanel *pPanel ) { m_eventCallback.RegisterEventListener( pPanel ); }
+ void UnregisterEventListener( IUIPanel *pPanel ) { m_eventCallback.UnregisterEventListener( pPanel ); }
+
+ void RegisterEventCallback( VideoPlayerEventDelegate_t del ) { m_eventCallback.RegisterEventCallback( del ); }
+ void UnregisterEventCallback( VideoPlayerEventDelegate_t del ) { m_eventCallback.UnregisterEventCallback( del ); }
+
+ void SetPlaybackVolume( float flVolume ) { m_audioCallback.SetPlaybackVolume( flVolume ); }
+
+ // IVideoPlayer
+ virtual bool BLoad( const char *pchURL ) OVERRIDE;
+ virtual bool BLoad( const byte *pubData, uint cubData ) OVERRIDE;
+ virtual void Play() OVERRIDE { m_pVideoPlayer->Play(); }
+ virtual void Stop() OVERRIDE;
+ virtual void Pause() OVERRIDE { m_pVideoPlayer->Pause(); }
+ virtual void SetPlaybackSpeed( float flPlaybackSpeed ) OVERRIDE { m_pVideoPlayer->SetPlaybackSpeed( flPlaybackSpeed ); }
+ virtual void Seek( uint unSeekMS ) OVERRIDE { m_pVideoPlayer->Seek( unSeekMS ); }
+ virtual void SetRepeat( bool bRepeat ) OVERRIDE { m_pVideoPlayer->SetRepeat( bRepeat ); }
+ virtual void SuggestMaxVeritcalResolution( int nHeight ) OVERRIDE { m_pVideoPlayer->SuggestMaxVeritcalResolution( nHeight ); }
+ virtual EVideoPlayerPlaybackState GetPlaybackState() OVERRIDE { return m_pVideoPlayer->GetPlaybackState(); }
+ virtual bool IsStoppedForBuffering() OVERRIDE { return m_pVideoPlayer->IsStoppedForBuffering(); }
+ virtual float GetPlaybackSpeed() OVERRIDE { return m_pVideoPlayer->GetPlaybackSpeed(); }
+ virtual uint32 GetDuration() OVERRIDE { return m_pVideoPlayer->GetDuration(); }
+ virtual uint32 GetCurrentPlaybackTime() OVERRIDE { return m_pVideoPlayer->GetCurrentPlaybackTime(); }
+ virtual EVideoPlayerPlaybackError GetPlaybackError() OVERRIDE { return m_pVideoPlayer->GetPlaybackError(); }
+ virtual void GetVideoResolution( int *pnWidth, int *pnHeight ) OVERRIDE { m_pVideoPlayer->GetVideoResolution( pnWidth, pnHeight ); }
+ virtual int GetVideoDownloadRate() OVERRIDE { return m_pVideoPlayer->GetVideoDownloadRate(); }
+ virtual int GetVideoRepresentationCount() OVERRIDE { return m_pVideoPlayer->GetVideoRepresentationCount(); }
+ virtual bool BGetVideoRepresentationInfo( int iRep, int *pnWidth, int *pnHeight ) OVERRIDE { return m_pVideoPlayer->BGetVideoRepresentationInfo( iRep, pnWidth, pnHeight ); }
+ virtual int GetCurrentVideoRepresentation() OVERRIDE { return m_pVideoPlayer->GetCurrentVideoRepresentation(); }
+ virtual void ForceVideoRepresentation( int iRep ) OVERRIDE { return m_pVideoPlayer->ForceVideoRepresentation( iRep ); }
+ virtual void GetVideoSegmentInfo( int *pnCurrent, int *pnTotal ) OVERRIDE { m_pVideoPlayer->GetVideoSegmentInfo( pnCurrent, pnTotal ); }
+ virtual bool BHasAudioTrack() OVERRIDE { return m_pVideoPlayer->BHasAudioTrack(); }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const char *pchName );
+#endif
+
+private:
+ IVideoPlayer *m_pVideoPlayer;
+ CVideoPlayerVideoRenderer m_videoCallback;
+ CVideoPlayerAudioRenderer m_audioCallback;
+ CVideoPlayerEventDispatcher m_eventCallback;
+};
+
+typedef CSmartPtr< CPanoramaVideoPlayer > CVideoPlayerPtr;
+
+} // namespace panorama
+
+
+#endif // PANORAMA_VIDEO_PLAYER_H \ No newline at end of file
diff --git a/public/panorama/input/gamepadcodes.h b/public/panorama/input/gamepadcodes.h
new file mode 100644
index 0000000..0ba5693
--- /dev/null
+++ b/public/panorama/input/gamepadcodes.h
@@ -0,0 +1,109 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef GAMEPADCODES_H
+#define GAMEPADCODES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+enum GamePadCode
+{
+ XK_NULL,
+ XK_BUTTON_UP,
+ XK_BUTTON_DOWN,
+ XK_BUTTON_LEFT,
+ XK_BUTTON_RIGHT,
+ XK_BUTTON_START,
+ XK_BUTTON_BACK,
+ XK_BUTTON_STICK1,
+ XK_BUTTON_STICK2,
+ XK_BUTTON_A,
+ XK_BUTTON_B,
+ XK_BUTTON_X,
+ XK_BUTTON_Y,
+ XK_BUTTON_LEFT_SHOULDER,
+ XK_BUTTON_RIGHT_SHOULDER,
+ XK_BUTTON_LTRIGGER,
+ XK_BUTTON_RTRIGGER,
+ XK_STICK1_UP,
+ XK_STICK1_DOWN,
+ XK_STICK1_LEFT,
+ XK_STICK1_RIGHT,
+ XK_STICK2_UP,
+ XK_STICK2_DOWN,
+ XK_STICK2_LEFT,
+ XK_STICK2_RIGHT,
+ XK_STICK1_ANALOG,
+ XK_STICK2_ANALOG,
+ XK_BUTTON_GUIDE,
+
+ STEAM_LEFTPAD_UP,
+ STEAM_LEFTPAD_DOWN,
+ STEAM_LEFTPAD_LEFT,
+ STEAM_LEFTPAD_RIGHT,
+ STEAM_LEFTPAD_ANALOG,
+ STEAM_RIGHTPAD_UP,
+ STEAM_RIGHTPAD_DOWN,
+ STEAM_RIGHTPAD_LEFT,
+ STEAM_RIGHTPAD_RIGHT,
+ STEAM_RIGHTPAD_ANALOG,
+ STEAM_LEFTSTICK_UP,
+ STEAM_LEFTSTICK_DOWN,
+ STEAM_LEFTSTICK_LEFT,
+ STEAM_LEFTSTICK_RIGHT,
+ STEAM_LEFTSTICK_ANALOG,
+ STEAM_BUTTON_LTRIGGER,
+ STEAM_BUTTON_RTRIGGER,
+ STEAM_BUTTON_LSHOULDER,
+ STEAM_BUTTON_RSHOULDER,
+ STEAM_BUTTON_LBACK,
+ STEAM_BUTTON_RBACK,
+ STEAM_BUTTON_GUIDE,
+ STEAM_BUTTON_SELECT,
+ STEAM_BUTTON_START,
+ STEAM_BUTTON_LPAD_CLICKED,
+ STEAM_BUTTON_LPAD_TOUCH,
+ STEAM_BUTTON_RPAD_CLICKED,
+ STEAM_BUTTON_RPAD_TOUCH,
+ STEAM_BUTTON_LPAD_DBLTAPPED,
+ STEAM_BUTTON_RPAD_DBLTAPPED,
+ STEAM_BUTTON_A,
+ STEAM_BUTTON_B,
+ STEAM_BUTTON_X,
+ STEAM_BUTTON_Y,
+ STEAM_BUTTON_DPAD_UP,
+ STEAM_BUTTON_DPAD_RIGHT,
+ STEAM_BUTTON_DPAD_DOWN,
+ STEAM_BUTTON_DPAD_LEFT,
+
+ XK_MAX_KEYS,
+};
+
+
+enum EJoystickAxis
+{
+ JOY_AXIS_X = 0,
+ JOY_AXIS_Y,
+ JOY_AXIS_Z,
+ JOY_AXIS_R,
+ JOY_AXIS_U,
+ JOY_AXIS_V,
+ JOY_MAX_AXES,
+};
+
+enum EJoystickDeadzoneMode
+{
+ JOYSTICK_DEADZONE_CROSS = 0,
+ JOYSTICK_DEADZONE_SQUARE = 1,
+};
+
+} // namespace panorama
+
+#endif // GAMEPADCODES_H \ No newline at end of file
diff --git a/public/panorama/input/iuiinput.h b/public/panorama/input/iuiinput.h
new file mode 100644
index 0000000..df362e1
--- /dev/null
+++ b/public/panorama/input/iuiinput.h
@@ -0,0 +1,543 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+#ifndef IUIINPUT_H
+#define IUIINPUT_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "keycodes.h"
+#include "mousecodes.h"
+#include "gamepadcodes.h"
+#include "tier0/platform.h"
+#include "tier1/utldelegate.h"
+#include "../controls/panelhandle.h"
+#include "../uieventcodes.h"
+#include "../iuiengine.h"
+
+#ifdef SOURCE2_PANORAMA
+#include "inputsystem/buttoncode.h"
+#endif
+
+namespace panorama
+{
+
+class CPanel2D;
+class IImageSource;
+class IUISettings;
+
+// the classes of input we understand
+enum EInputType
+{
+ k_eInputNone = 0,
+ k_eKeyDown = 1, // raw down press
+ k_eKeyUp = 2, // raw release
+ k_eKeyChar = 3, // composited text entry from the OS
+ k_eMouseDown = 4,
+ k_eMouseUp = 5,
+ k_eMouseMove = 6,
+ k_eMouseDoubleClick = 7,
+ k_eMouseTripleClick = 8,
+ k_eMouseWheel = 9,
+ k_eMouseEnter = 10,
+ k_eMouseLeave = 11,
+ k_eGamePadDown = 12,
+ k_eGamePadUp = 13,
+ k_eGamePadAnalog = 14,
+
+ k_eOverlayCommand = 5000,
+
+ k_eInputTypeMaxRange = 0xFFFFFFFF // force size to 32 bits
+};
+
+
+enum EActiveControllerType
+{
+ k_EActiveControllerType_None, // we aren't using a controller or we don't know to do
+ k_EActiveControllerType_XInput,
+ k_EActiveControllerType_Steam,
+};
+
+//
+// structs container input type specific data
+//
+struct KeyData_t
+{
+ EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
+
+ KeyCode m_KeyCode;
+ uint8 m_RepeatCount;
+ bool m_bFirstDown; // is this the first time this key was pressed
+ wchar_t m_UniChar; // unicode equivalent of this key
+ uint32 m_Modifiers; // alt, ctrl, etc held down?
+};
+
+
+struct MouseData_t
+{
+ EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
+
+ MouseCode m_MouseCode;
+ uint32 m_Modifiers;
+ uint8 m_RepeatCount;
+ int m_Delta;
+};
+
+struct GamePadData_t
+{
+ EPanelEventSource_t m_eSource; // this needs to be the first field of the struct, since it's unioned in InputMessage_t
+
+ GamePadCode m_GamePadCode;
+ uint8 m_RepeatCount; // home many times in a row we have had this button down
+ float m_fValue; // the analog value of the deflection if an axis
+
+ // if an analog event then these two are set for each axis value
+ float m_fValueX; // the analog value of the deflection along horizontal
+ float m_fValueY; // the analog value of the deflection along vertical
+
+ // For Steam controller analog events this value will indicate the time the users finger went down
+ float m_flFingerDown;
+
+ // For Steam controller analog events these values indicate the starting finger position (so you can do some basic swipe stuff)
+ float m_fValueXFirst;
+ float m_fValueYFirst;
+
+ // For Steam controller analog events this is the raw sampled coordinate without deadzoning
+ float m_fValueXRaw;
+ float m_fValueYRaw;
+};
+
+
+struct InputMessage_t
+{
+ EInputType m_eInputType;
+ float m_flInputTime;
+ union
+ {
+ EPanelEventSource_t m_eSource; // where did this event originate? this is the first field of the other *Data_t structs below.
+ KeyData_t m_KeyData;
+ MouseData_t m_MouseData;
+ GamePadData_t m_GamePadData;
+ };
+};
+
+
+//
+// A combination of event type and specific code data to mean an input event, like on key down of the A key
+//
+struct ActionInput_t
+{
+ ActionInput_t()
+ {
+ m_InputType = k_eInputNone;
+ m_Data.m_KeyCode = KEY_NONE;
+ m_unModifiers = MODIFIER_NONE;
+ }
+
+ explicit ActionInput_t( EInputType type, KeyCode code, uint32 unModifiers, const char *pchNamespace )
+ {
+ m_InputType = type;
+ m_Data.m_KeyCode = code;
+ m_unModifiers = unModifiers;
+ if ( pchNamespace && pchNamespace[0] )
+ m_symNameSpace = pchNamespace;
+ }
+
+ explicit ActionInput_t( EInputType type, GamePadCode code, const char *pchNamespace )
+ {
+ m_InputType = type;
+ m_Data.m_GamePadCode = code;
+ m_unModifiers = MODIFIER_NONE;
+ if ( pchNamespace && pchNamespace[0] )
+ m_symNameSpace = pchNamespace;
+ }
+
+ explicit ActionInput_t( EInputType type, MouseCode code, const char *pchNamespace )
+ {
+ m_InputType = type;
+ m_Data.m_MouseCode = code;
+ m_unModifiers = MODIFIER_NONE;
+ if ( pchNamespace && pchNamespace[0] )
+ m_symNameSpace = pchNamespace;
+ }
+
+ ActionInput_t( InputMessage_t &msg, const char *pchNamespace )
+ {
+ m_InputType = msg.m_eInputType;
+ if ( pchNamespace && pchNamespace[0] )
+ m_symNameSpace = pchNamespace;
+ m_unModifiers = MODIFIER_NONE;
+ switch ( msg.m_eInputType )
+ {
+ default:
+ AssertMsg( false, "Unknown input type to ActionInput_t( InputMessage_t )" );
+ break;
+ case k_eKeyDown:
+ case k_eKeyUp:
+ case k_eKeyChar:
+ m_Data.m_KeyCode = msg.m_KeyData.m_KeyCode;
+ m_unModifiers = msg.m_KeyData.m_Modifiers;
+ break;
+ case k_eMouseDown:
+ case k_eMouseDoubleClick:
+ case k_eMouseTripleClick:
+ case k_eMouseUp:
+ case k_eMouseMove:
+ case k_eMouseWheel:
+ m_Data.m_MouseCode = msg.m_MouseData.m_MouseCode;
+ m_unModifiers = msg.m_MouseData.m_Modifiers;
+ break;
+ case k_eMouseEnter:
+ case k_eMouseLeave:
+ break;
+ case k_eGamePadDown:
+ case k_eGamePadUp:
+ case k_eGamePadAnalog:
+ m_Data.m_GamePadCode = msg.m_GamePadData.m_GamePadCode;
+ break;
+ }
+ }
+
+
+ // Can't ever make this not 32bits in size, see crazy comparison operators below. Also, each
+ // member must be exactly 32bits, not less with uninitialized data.
+ EInputType m_InputType;
+ union
+ {
+ KeyCode m_KeyCode;
+ GamePadCode m_GamePadCode;
+ MouseCode m_MouseCode;
+ } m_Data;
+
+ uint32 m_unModifiers;
+ CPanoramaSymbol m_symNameSpace;
+
+ bool operator<( const ActionInput_t &that ) const
+ {
+ if ( m_InputType != that.m_InputType )
+ return m_InputType < that.m_InputType;
+
+ if ( m_unModifiers != that.m_unModifiers )
+ return m_unModifiers < that.m_unModifiers;
+
+ // I have a namespace and you don't
+ if ( m_symNameSpace.IsValid() && !that.m_symNameSpace.IsValid() )
+ return true;
+
+ // You have a namespace and I don't
+ if ( that.m_symNameSpace.IsValid() && !m_symNameSpace.IsValid() )
+ return false;
+
+ // compare namespace if both are valid but not equal
+ if ( m_symNameSpace.IsValid() && that.m_symNameSpace.IsValid() && m_symNameSpace != that.m_symNameSpace )
+ return m_symNameSpace < that.m_symNameSpace;
+
+ // lets compare the raw code now
+ switch( m_InputType )
+ {
+ default:
+ case k_eKeyDown:
+ case k_eKeyUp:
+ case k_eKeyChar:
+ return m_Data.m_KeyCode < that.m_Data.m_KeyCode;
+ case k_eMouseDown:
+ case k_eMouseUp:
+ case k_eMouseMove:
+ case k_eMouseWheel:
+ case k_eMouseDoubleClick:
+ case k_eMouseTripleClick:
+ return m_Data.m_MouseCode < that.m_Data.m_MouseCode;
+ case k_eGamePadDown:
+ case k_eGamePadUp:
+ case k_eGamePadAnalog:
+ return m_Data.m_GamePadCode < that.m_Data.m_GamePadCode;
+ }
+ }
+
+ bool operator==( const ActionInput_t &that ) const
+ {
+ if ( m_InputType == that.m_InputType && m_unModifiers == that.m_unModifiers &&
+ // also if both namespace are valid and equal OR either namespace is unset (i.e "global")
+ ( ( m_symNameSpace.IsValid() && that.m_symNameSpace.IsValid() && m_symNameSpace == that.m_symNameSpace ) || ( !m_symNameSpace.IsValid() && !that.m_symNameSpace.IsValid() ) ) )
+ {
+ switch( m_InputType )
+ {
+ default:
+ case k_eKeyDown:
+ case k_eKeyUp:
+ case k_eKeyChar:
+ return m_Data.m_KeyCode == that.m_Data.m_KeyCode;
+ case k_eMouseDoubleClick:
+ case k_eMouseTripleClick:
+ case k_eMouseDown:
+ case k_eMouseUp:
+ case k_eMouseMove:
+ case k_eMouseWheel:
+ return m_Data.m_MouseCode == that.m_Data.m_MouseCode;
+ case k_eGamePadDown:
+ case k_eGamePadUp:
+ case k_eGamePadAnalog:
+ return m_Data.m_GamePadCode == that.m_Data.m_GamePadCode;
+ }
+ }
+ return false;
+ }
+
+};
+
+// Helpers for checking modifier state
+inline bool IsControlPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LCONTROL || unModifiers & MODIFIER_RCONTROL; }
+inline bool IsAltPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LALT || unModifiers & MODIFIER_RALT; }
+inline bool IsShiftPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LSHIFT || unModifiers & MODIFIER_RSHIFT; }
+inline bool IsWinPressed( uint32 unModifiers ) { return unModifiers & MODIFIER_LWIN || unModifiers & MODIFIER_RWIN; }
+
+
+//
+// struct to wrap mouse move events for mouse tracked panels
+//
+struct MouseTrackingResults_t
+{
+ MouseTrackingResults_t()
+ {
+ m_hPanel = k_ulInvalidPanelHandle64;
+ m_flX = 0.0f;
+ m_flY = 0.0f;
+
+ }
+ MouseTrackingResults_t( uint64 handle, float x, float y )
+ {
+ m_hPanel = handle;
+ m_flX = x;
+ m_flY = y;
+ }
+
+ uint64 m_hPanel;
+ float m_flX;
+ float m_flY;
+};
+
+//
+// An interface to receive captured input
+//
+class IInputCapture
+{
+public:
+ // keyboard
+ virtual bool OnCapturedKeyDown( IUIPanel *pPanel, const KeyData_t &code ) = 0;
+ virtual bool OnCapturedKeyUp( IUIPanel *pPanel, const KeyData_t &code ) = 0;
+ virtual bool OnCapturedKeyTyped( IUIPanel *pPanel, const KeyData_t &unichar ) = 0;
+
+ // mouse
+ virtual bool OnCapturedMouseMove( IUIPanel *pPanel ) = 0;
+ virtual bool OnCapturedMouseButtonDown( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+ virtual bool OnCapturedMouseButtonUp( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+ virtual bool OnCapturedMouseButtonDoubleClick( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+ virtual bool OnCapturedMouseButtonTripleClick( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+ virtual bool OnCapturedMouseWheel( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+
+ // gamepad
+ virtual bool OnCapturedGamePadDown( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
+ virtual bool OnCapturedGamePadUp( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
+ virtual bool OnCapturedGamePadAnalog( IUIPanel *pPanel, const GamePadData_t &code ) = 0;
+};
+
+class CDefaultInputCapture : public IInputCapture
+{
+public:
+ // keyboard
+ virtual bool OnCapturedKeyDown( panorama::IUIPanel *pPanel, const panorama::KeyData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedKeyUp( panorama::IUIPanel *pPanel, const panorama::KeyData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedKeyTyped( panorama::IUIPanel *pPanel, const panorama::KeyData_t &unichar ) OVERRIDE { return false; }
+
+ // mouse
+ virtual bool OnCapturedMouseMove( panorama::IUIPanel *pPanel ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseButtonDown( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseButtonUp( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseButtonDoubleClick( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseButtonTripleClick( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedMouseWheel( panorama::IUIPanel *pPanel, const panorama::MouseData_t &code ) OVERRIDE { return false; }
+
+ // gamepad
+ virtual bool OnCapturedGamePadDown( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedGamePadUp( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
+ virtual bool OnCapturedGamePadAnalog( panorama::IUIPanel *pPanel, const panorama::GamePadData_t &code ) OVERRIDE { return false; }
+};
+
+//
+// Handles per top level window focus
+//
+class IUIWindowInput
+{
+public:
+ virtual bool InputEvent( InputMessage_t &msg, bool bNewEvent = true ) = 0;
+
+ // Receive mouse move events, in window coordinate space
+ virtual void OnMouseMove( float flMouseX, float flMouseY, bool bSynthesized = false ) = 0;
+
+ // current mouse coordinates and visibility
+ virtual void GetSurfaceMousePosition( float &x, float &y ) = 0;
+ virtual bool BCursorVisible() = 0;
+ virtual void WakeupMouseCursor() = 0;
+ virtual void FadeOutCursorNow() = 0;
+
+ // gamepad state
+ virtual int GetNumGamepadsConnected() = 0;
+ virtual bool BWasGamepadConnectedThisSession() = 0;
+ virtual bool BWasGamepadUsedThisSession() = 0;
+ virtual bool BWasSteamControllerConnectedThisSession() = 0;
+ virtual bool BWasSteamControllerUsedThisSession() = 0;
+
+ // tracking of last input type
+ virtual bool BWasGamepadLastInputSource() = 0;
+ virtual bool BWasMouseLastInputSource() = 0;
+ virtual bool BWasKeyboardOrMouseLastInputSource() = 0;
+
+ // Get the last input source
+ virtual EPanelEventSource_t GetLastPanelEventSource() = 0;
+
+ // Keyboard / mouse info
+ virtual bool BWasKeyboardOrMouseUsedThisSession() = 0;
+ virtual bool BWasMouseMovedThisSession() = 0;
+
+ // top level OS window support
+ virtual void GotWindowFocus() = 0;
+ virtual void LostWindowFocus() = 0;
+ virtual bool BHasWindowFocus() = 0;
+
+ // Window can temporarily disable all input, used for overlay when the game is focused, but overlay inactive
+ virtual bool BAllowInput( InputMessage_t &msg ) = 0;
+
+ // panel management
+ virtual void SetInputFocus( IUIPanel *pPanel, bool bScrollParentToFit, bool bChangeContextIfNeeded ) = 0;
+ virtual bool SetInputFocusContext( IUIPanel *pPanelInContext ) = 0;
+ virtual void PopInputContext() = 0;
+ virtual IUIPanel *GetInputFocusContext() = 0;
+ virtual IUIPanel *GetInputFocus() = 0;
+ virtual IUIPanel *GetMouseHover() = 0;
+ virtual void PanelDeleted( IUIPanel *pPanel, IUIPanel *pParent ) = 0;
+
+ // input hooks
+ virtual void HookPanelInput( IUIPanel *pPanel, IInputCapture *pInputCapture ) = 0;
+ virtual void RemovePanelInputHook( IUIPanel *pPanel, IInputCapture *pInputCapture ) = 0;
+
+ // set this panel to always (or stop) getting MouseMove events
+ virtual void AddMouseTrackingPanel( IUIPanel *pPanel ) = 0;
+ virtual void RemoveMouseTrackingPanel( IUIPanel *pPanel ) = 0;
+
+ // Are we currently inside a set input focus call
+ virtual bool BInSetInputFocusTraverse() = 0;
+
+ // Queue a panel focus event to occur once we finish with setting input focus
+ virtual void QueuePanelFocusEvent( IUIPanel *pPanel, CPanoramaSymbol symPanelEvent ) = 0;
+
+ // reset any mouse movement count as we just hid the cursor
+ virtual void ResetMouseMoveCount() = 0;
+
+ // Get focus panel at time of last mouse down
+ virtual IUIPanel *GetFocusOnLastMouseDown() = 0;
+};
+
+
+//
+// Handles key/mouse/gamepad input and dispatches to appropriate panels
+//
+class IUIInput
+{
+public:
+ virtual void Initialize( IUISettings *pSettings ) = 0;
+
+ // Not ifdef'd or specific to windows. v_key ended up as a common
+ // denominator in lots of code (overlay as an example)
+ // 0x00 for error in mapping. There is no 0x00 VKEY
+ virtual uint16 KeyCodeToWindowsVKey( const KeyCode inKey ) = 0;
+
+ // KEY_NONE will come back on error.
+ virtual KeyCode WindowsVKeyToKeyCode( uint16 inKey ) = 0;
+
+#ifdef SOURCE2_PANORAMA
+ virtual ButtonCode_t KeyCodeToButtonCode( const KeyCode inKey ) = 0;
+ virtual ButtonCode_t MouseCodeToButtonCode( const MouseCode inKey ) = 0;
+#endif
+
+ // kb/mouse input
+ virtual bool InputEvent( InputMessage_t &msg ) = 0;
+
+ // used to capture all input
+ virtual void SetInputCapture( IInputCapture *pCapture ) = 0;
+ virtual void ReleaseInputCapture( IInputCapture *pCapture ) = 0;
+ virtual CUtlVector< IInputCapture * > &GetInputCapture() = 0;
+
+ // Checks whether gamepads are connected
+ virtual int GetNumGamepadsConnected() const = 0;
+
+ // did any gamepad have input since we last asked
+ virtual bool BWasGamepadOrSteamControllerActive() = 0;
+
+ // flags to tell steam controller layer which buttons to treat as mouse and not disable cursor on seeing
+ virtual void SetSteamPadButtonsToTreatAsMouse( uint64 ulButtonMask ) = 0;
+
+ // if a gamepad is connected then its friendly name
+ virtual const char *PchGamePadName() = 0;
+
+ // return true if we are emulating a gamepad using a simple joystick, so we have less input functionality available
+ virtual bool BEmulatingGamePadWithJoystick() = 0;
+
+ // helper for gamepad codes, returns values that are inside the deadzone for this joystick
+ virtual float GetDeadZoneValue( GamePadCode code ) = 0;
+
+ // translate an event into the gamepad key bound to it, XK_NULL if not bound
+ virtual const GamePadCode GetGamePadBindForEvent( const char *pchEvent, const IUIPanel *pFromPanel ) = 0;
+
+ // is capslock on
+ virtual bool BIsCapsLockOn() = 0;
+
+ // If we're trying to show help text for a controller, which type of controller is most relevant (ie., most recently
+ // used, exists, etc.)? You probably don't want to call this directly but instead listen for ActiveControllerTypeChanged.
+ virtual EActiveControllerType GetActiveControllerType() const = 0;
+
+ // Get count of actively connected Steam controllers
+ virtual uint32 GetSteamControllerCount() const = 0;
+
+ // Get the time a steam controller was last assigned/used
+ virtual float GetLastSteamControllerActiveTime() const = 0;
+
+ // Get the time a non-steam controller was last assigned/used
+ virtual float GetLastGamePadControllerActiveTime() const = 0;
+
+ // Get the ID of the steam controller currently sending events to the window
+ virtual int GetLastSteamControllerActiveIndex() const = 0;
+
+ // Pulse haptic feedback on active gamepad/steam controller if supported
+ virtual void PulseActiveControllerHaptic( IUIEngine::EHapticFeedbackPosition ePosition, IUIEngine::EHapticFeedbackStrength eStrength ) = 0;
+
+ // Is finger actively down on steam controller right pad? Probably means mouse emulation in use.
+ virtual bool BIsFingerDownOnSteamControllerRightPad() const = 0;
+
+ // Register a file path to look for keybindings
+ virtual void RegisterKeyBindingsFile( const char *pszFilePath ) = 0;
+
+ // Force a reload of the keybindings
+ virtual void ReloadKeyBindings() = 0;
+
+ // Private APIs for remote gamepad input, called on a separate network thread
+ virtual void RemoteGamepadAttached( int nGamepadID ) = 0;
+ virtual void RemoteGamepadDetached( int nGamepadID ) = 0;
+ virtual void SetRemoteGamepadAxis( int nGamepadID, int nAxis, int nValue ) = 0;
+ virtual void SetRemoteGamepadButton( int nGamepadID, int nButton, int nValue ) = 0;
+
+ // Turn off whatever (wireless) controller was last active
+ virtual void TurnOffActiveController() = 0;
+
+ // Get gamepad code value from textual name for config files, event code, etc
+ virtual panorama::GamePadCode GamePadCodeFromName( const char * pchGamePadCode ) = 0;
+
+ // Check if two gamepad codes are the 'same' button but on different vendor devices
+ virtual bool BIsGamePadCodeEquivalentIgnoringVendor( GamePadCode a, GamePadCode b ) = 0;
+};
+
+} // namespace panorama
+
+#endif // IUIINPUT_H
diff --git a/public/panorama/input/keycodes.h b/public/panorama/input/keycodes.h
new file mode 100644
index 0000000..b1085a2
--- /dev/null
+++ b/public/panorama/input/keycodes.h
@@ -0,0 +1,158 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef KEYCODES_H
+#define KEYCODES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+enum ModifierCode
+{
+ MODIFIER_NONE = 0x0,
+ MODIFIER_LCONTROL = 0x01,
+ MODIFIER_RCONTROL = 0x02,
+ MODIFIER_LALT = 0x04,
+ MODIFIER_RALT = 0x08,
+ MODIFIER_LSHIFT = 0x10,
+ MODIFIER_RSHIFT = 0x20,
+ MODIFIER_LWIN = 0x40,
+ MODIFIER_RWIN = 0x80,
+};
+
+enum KeyCode
+{
+ KEY_NONE = 0,
+ KEY_0,
+ KEY_1,
+ KEY_2,
+ KEY_3,
+ KEY_4,
+ KEY_5,
+ KEY_6,
+ KEY_7,
+ KEY_8,
+ KEY_9,
+ KEY_A,
+ KEY_B,
+ KEY_C,
+ KEY_D,
+ KEY_E,
+ KEY_F,
+ KEY_G,
+ KEY_H,
+ KEY_I,
+ KEY_J,
+ KEY_K,
+ KEY_L,
+ KEY_M,
+ KEY_N,
+ KEY_O,
+ KEY_P,
+ KEY_Q,
+ KEY_R,
+ KEY_S,
+ KEY_T,
+ KEY_U,
+ KEY_V,
+ KEY_W,
+ KEY_X,
+ KEY_Y,
+ KEY_Z,
+ KEY_PAD_0,
+ KEY_PAD_1,
+ KEY_PAD_2,
+ KEY_PAD_3,
+ KEY_PAD_4,
+ KEY_PAD_5,
+ KEY_PAD_6,
+ KEY_PAD_7,
+ KEY_PAD_8,
+ KEY_PAD_9,
+ KEY_PAD_DIVIDE,
+ KEY_PAD_MULTIPLY,
+ KEY_PAD_MINUS,
+ KEY_PAD_PLUS,
+ KEY_PAD_ENTER,
+ KEY_PAD_DECIMAL,
+ KEY_LBRACKET,
+ KEY_RBRACKET,
+ KEY_SEMICOLON,
+ KEY_APOSTROPHE,
+ KEY_BACKQUOTE,
+ KEY_COMMA,
+ KEY_PERIOD,
+ KEY_SLASH,
+ KEY_BACKSLASH,
+ KEY_MINUS,
+ KEY_EQUAL,
+ KEY_ENTER,
+ KEY_SPACE,
+ KEY_BACKSPACE,
+ KEY_TAB,
+ KEY_CAPSLOCK,
+ KEY_NUMLOCK,
+ KEY_ESCAPE,
+ KEY_SCROLLLOCK,
+ KEY_INSERT,
+ KEY_DELETE,
+ KEY_HOME,
+ KEY_END,
+ KEY_PAGEUP,
+ KEY_PAGEDOWN,
+ KEY_BREAK,
+ KEY_LSHIFT,
+ KEY_RSHIFT,
+ KEY_LALT,
+ KEY_RALT,
+ KEY_LCONTROL,
+ KEY_RCONTROL,
+ KEY_LWIN,
+ KEY_RWIN,
+ KEY_APP,
+ KEY_UP,
+ KEY_LEFT,
+ KEY_DOWN,
+ KEY_RIGHT,
+ KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ KEY_F7,
+ KEY_F8,
+ KEY_F9,
+ KEY_F10,
+ KEY_F11,
+ KEY_F12,
+ KEY_F13,
+ KEY_F14,
+ KEY_F15,
+ KEY_F16,
+ KEY_F17,
+ KEY_F18,
+ KEY_F19,
+ KEY_CAPSLOCKTOGGLE,
+ KEY_NUMLOCKTOGGLE,
+ KEY_SCROLLLOCKTOGGLE,
+ KEY_PRINTSCREEN,
+ KEY_VOLUME_MUTE,
+ KEY_VOLUME_DOWN,
+ KEY_VOLUME_UP,
+ KEY_MEDIA_NEXT_TRACK,
+ KEY_MEDIA_PREV_TRACK,
+ KEY_MEDIA_STOP,
+ KEY_MEDIA_PLAY_PAUSE,
+ KEY_LAST
+};
+
+} // namespace panorama
+
+#endif // KEYCODES_H \ No newline at end of file
diff --git a/public/panorama/input/mousecodes.h b/public/panorama/input/mousecodes.h
new file mode 100644
index 0000000..866b57f
--- /dev/null
+++ b/public/panorama/input/mousecodes.h
@@ -0,0 +1,29 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef MOUSECODES_H
+#define MOUSECODES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+enum MouseCode
+{
+ MOUSE_INVALID = -1,
+ MOUSE_LEFT = 0,
+ MOUSE_RIGHT,
+ MOUSE_MIDDLE,
+ MOUSE_4,
+ MOUSE_5,
+ MOUSE_LAST,
+};
+
+} // namespace panorama
+
+#endif // MOUSECODES_H \ No newline at end of file
diff --git a/public/panorama/input/mousecursors.h b/public/panorama/input/mousecursors.h
new file mode 100644
index 0000000..4338c7a
--- /dev/null
+++ b/public/panorama/input/mousecursors.h
@@ -0,0 +1,28 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef MOUSECURSORS_H
+#define MOUSECURSORS_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+enum EMouseCursors
+{
+ eMouseCursor_None = 0,
+ eMouseCursor_Arrow,
+ eMouseCursor_IBeam,
+ eMouseCursor_SizeWE,
+ eMouseCursor_SizeNS,
+ eMouseCursor_Last,
+};
+
+} // namespace panorama
+
+#endif // MOUSECURSORS_H
diff --git a/public/panorama/iuiengine.h b/public/panorama/iuiengine.h
new file mode 100644
index 0000000..6c40ef6
--- /dev/null
+++ b/public/panorama/iuiengine.h
@@ -0,0 +1,746 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUIENGINE_H
+#define IUIENGINE_H
+#pragma once
+
+#include "tier0/platform.h"
+
+#if defined( SOURCE2_PANORAMA )
+#include "tier0/platwindow.h"
+#endif
+
+#include "tier1/convar.h"
+#include "panorama.h"
+#include "./iuipanel.h"
+#include "utlsymbol.h"
+#include "panoramatypes.h"
+#include "iuilayoutmanager.h"
+#include "controls/panelhandle.h"
+#include "tier1/utllinkedlist.h"
+#include "tier1/utlstring.h"
+#include "tier1/utldelegate.h"
+#include "tier0/validator.h"
+#ifdef SOURCE_PANORAMA_FIXME
+ #include "tier1/UtlSortVector.h"
+#else
+ #include "tier1/utlsortvector.h"
+#endif
+#include "language.h"
+#include "panorama/layout/panel2dfactory.h"
+#include "iuistylefactory.h"
+#include "interface.h"
+#include "steam/isteamhttp.h"
+#include "iuifilesystem.h"
+
+#if !defined( SOURCE2_PANORAMA )
+#include "audio/iaudiointerface.h"
+#include <openvr.h>
+#endif
+
+#if _GNUC
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#endif
+#if defined( SOURCE2_PANORAMA )
+#include "../thirdparty/v8/include/v8.h"
+#else
+#include "tier0/memdbgoff.h"
+#include "../external/v8/include/v8.h"
+#include "tier0/memdbgon.h"
+#endif
+#if _GNUC
+#pragma GCC diagnostic pop
+#endif
+
+#ifdef SUPPORTS_AUDIO
+class IAudioOutputStream;
+#endif
+typedef uint64 GID_t;
+class KeyValues;
+#if !defined( SOURCE2_PANORAMA )
+class IHTMLChromeController;
+#endif
+
+typedef CUtlDelegate< void( GID_t, KeyValues *, void * ) > JSONWebAPIDelegate_t;
+
+#if defined( SOURCE2_PANORAMA )
+DECLARE_LOGGING_CHANNEL( LOG_PANORAMA );
+DECLARE_LOGGING_CHANNEL( LOG_PANORAMA_SCRIPT );
+#endif
+
+namespace v8
+{
+ class Isolate;
+}
+
+namespace panorama
+{
+
+// forward decl for engine components
+class CUIProtoBufMsgMemoryPoolMgr;
+class CUIRenderEngine;
+class IUIInput;
+class IUIEvent;
+class IUILocalization;
+class IUISoundSystem;
+class IUILayoutManager;
+class CMovieManager;
+class IUITextLayout;
+class IUISettings;
+class IUIWindow;
+class CPanelStyle;
+class IUIJSObject;
+
+typedef void * HAUDIOSAMPLE;
+
+class IUIEngineFrameListener
+{
+public:
+ virtual void OnPreFrame() = 0;
+ virtual void OnPostFrame() = 0;
+ virtual void OnEngineShutdown() = 0;
+};
+
+
+class CJSONWebAPIParams
+{
+public:
+
+ struct WebAPIParam_t
+ {
+ CUtlString strParamName;
+ CUtlString strParamValue;
+ };
+
+ CJSONWebAPIParams() { }
+
+ void AddParam( const char *pchParamName, const char *pchParamValue )
+ {
+ int iVec = m_vecParams.AddToTail();
+ WebAPIParam_t &param = m_vecParams[iVec];
+ param.strParamName = pchParamName;
+ param.strParamValue = pchParamValue;
+ }
+
+ CUtlVector<WebAPIParam_t> *AccessParams() { return &m_vecParams; }
+
+private:
+
+ CCopyableUtlVector< WebAPIParam_t > m_vecParams;
+};
+
+typedef void (*PanoramaFrameFunc_t)();
+
+typedef int JSGenericCallbackHandle_t;
+const JSGenericCallbackHandle_t JS_GENERIC_CALLBACK_HANDLE_INVALID = -1;
+
+struct RegisterJSScopeInfo_t
+{
+ const char *pName;
+ const char *pDescription;
+ int nEntries;
+};
+
+enum RegisterJSType_t : uint8
+{
+ k_ERegisterJSTypeUnknown,
+ k_ERegisterJSTypeInvalid,
+ k_ERegisterJSTypeVoid,
+ k_ERegisterJSTypeBool,
+ k_ERegisterJSTypeInt8,
+ k_ERegisterJSTypeUint8,
+ k_ERegisterJSTypeInt16,
+ k_ERegisterJSTypeUint16,
+ k_ERegisterJSTypeInt32,
+ k_ERegisterJSTypeUint32,
+ k_ERegisterJSTypeInt64,
+ k_ERegisterJSTypeUint64,
+ k_ERegisterJSTypeFloat,
+ k_ERegisterJSTypeDouble,
+ k_ERegisterJSTypeConstString,
+ k_ERegisterJSTypePanoramaSymbol,
+ k_ERegisterJSTypeRawV8Args,
+};
+
+struct RegisterJSEntryInfo_t
+{
+ enum
+ {
+ k_EGlobalFunction = 0x00000000,
+ k_EMethod = 0x00000001,
+ k_EAccessor = 0x00000002,
+ k_EAccessorReadOnly = 0x00000003,
+ k_EConstantValue = 0x00000004,
+ k_EEntryTypeMask = 0x0000000f,
+ };
+
+ const char *pName;
+ const char *pDescription;
+ uint32 unFlags;
+
+ // Return or value type.
+ RegisterJSType_t eDataType;
+
+ // Prototype information may not be known.
+ static const uint8 k_unNumParamsUnknown = 0xff;
+ uint8 unNumParams;
+
+ static const uint8 k_unMaxParams = 10;
+ RegisterJSType_t pParamTypes[k_unMaxParams];
+
+ uint32 GetEntryType() const
+ {
+ return unFlags & k_EEntryTypeMask;
+ }
+};
+
+//
+// Interface that needs to be implemented for game engines on all platforms
+//
+class IUIEngine
+{
+public:
+ enum ERenderTarget
+ {
+ // these assignments are important because they are cross-cast at the protobuf layer
+ k_ERenderToWindow = 1,
+ k_ERenderFullScreen = 2,
+ k_ERenderBorderlessFullScreenWindow = 3,
+ k_ERenderToOverlayTexture = 4,
+ k_ERenderToOverlaySharedTexture = 5,
+ k_ERenderToOverlaySteamWM = 6,
+ k_ERenderToLegacyVR = 7, // This one is used for the Steam Client's main interface and will die eventually
+ k_ERenderToOpenVROverlay = 8,
+
+ k_ERenderTargetUnset = 0,
+ };
+
+ enum EHapticFeedbackPosition
+ {
+ k_EHapticFeedbackPosition_Left,
+ k_EHapticFeedbackPosition_Right,
+ };
+
+ enum EHapticFeedbackStrength
+ {
+ k_EHapticFeedbackStrength_VeryLow,
+ k_EHapticFeedbackStrength_Low,
+ k_EHapticFeedbackStrength_Medium,
+ k_EHapticFeedbackStrength_High,
+ };
+
+ // return true if the states are different and a valid transition. Used to test fullscreen transition
+ static bool BValidRenderStateChange( ERenderTarget eCurrentRenderTarget, ERenderTarget eRequestedRenderTarget );
+ static bool BIsRenderingToTexture( ERenderTarget eTarget ) { return (eTarget == k_ERenderToOverlayTexture || eTarget == k_ERenderToOverlaySharedTexture || eTarget == k_ERenderToOpenVROverlay ); }
+ static bool BIsOverlayTarget( ERenderTarget eTarget )
+ {
+ return (eTarget == IUIEngine::k_ERenderToOverlayTexture ||
+ eTarget == IUIEngine::k_ERenderToOverlaySharedTexture ||
+ eTarget == IUIEngine::k_ERenderToOverlaySteamWM);
+ }
+ static bool BIsRenderingToLegacyVR( ERenderTarget eTarget ) { return (eTarget == k_ERenderToLegacyVR); }
+ static bool BIsRenderingToOpenVROverlay( ERenderTarget eTarget ) { return (eTarget == k_ERenderToOpenVROverlay); }
+ static bool BIsRenderingToFullScreen( ERenderTarget eTarget ) { return (eTarget == k_ERenderFullScreen); }
+
+public:
+ virtual ~IUIEngine() {}
+
+ // Starts up subsystems and makes engine ready for use, you need to call RegisterNamedLocalPath() for at least the <config> path first!
+#if defined( SOURCE2_PANORAMA )
+ virtual bool StartupSubsystems( IUISettings *psettings, PlatWindow_t hWindow ) = 0;
+#else
+ virtual bool StartupSubsystems( IUISettings *psettings, IHTMLChromeController *pHTMLController ) = 0;
+#endif
+
+ // Hookup convars
+ virtual void ConCommandInit( IConCommandBaseAccessor *pAccessor ) = 0;
+
+ // Shutdown
+ virtual void Shutdown() = 0;
+ virtual void RequestShutdown() = 0;
+
+ // Run will run frames and block, letting the UI engine control the whole frame loop.
+ virtual void Run() = 0;
+
+ // Run frame will run a single frame, letting you wrap the UI engine in an external frame loop
+ virtual void RunFrame() = 0;
+
+ // Will set the UI engine to aggressively limit frame rate it runs at to avoid resource usage
+ virtual void SetAggressiveFrameRateLimit( bool bLimit ) = 0;
+
+ virtual bool BIsRunning() = 0;
+ virtual bool BHasFocus() = 0;
+ virtual double GetCurrentFrameTime() = 0;
+
+#if !defined( SOURCE2_PANORAMA )
+ virtual IUIWindow *CreateNewWindow( const char *pchWindowTitle, uint32 width, uint32 height, ERenderTarget eRenderType, bool bFixedSurfaceSize, bool bEnforceWindowAspectRatio, bool bUseCustomMouseCursor, const char *pchMonitorName ) = 0;
+ virtual IUIWindow *CreateNewOverlayWindow( const char *pchWindowTitle, uint32 width, uint32 height, panorama::IUIEngine::ERenderTarget eTarget, bool bFixedSize, bool bDrawCustomMouseCursor ) = 0;
+ virtual IUIWindow *CreateNewOpenVROverlayWindow( uint32 width, uint32 height, vr::VROverlayHandle_t ulOverlayHandle ) = 0;
+#else
+ virtual IUIWindow *CreateNewUILayerWindow( uint32 xPos, uint32 yPos, uint32 width, uint32 height, bool bFixedSurfaceSize, bool bEnforceWindowAspectRatio, bool bUseCustomMouseCursor, bool bAcceptKBandMouse, const char *pName ) = 0;
+#endif
+
+ virtual IUITextLayout *CreateTextLayout( const char *pchText, const char *pchFontName, float flSize, float flLineHeight, EFontWeight weight, EFontStyle style, ETextAlign align, bool bWrap, bool bEllipsis, int nLetterSpacing, float flMaxWidth, float flMaxHeight ) = 0;
+ virtual IUITextLayout *CreateTextLayout( const wchar_t *pwchText, const char *pchFontName, float flSize, float flLineHeight, EFontWeight weight, EFontStyle style, ETextAlign align, bool bWrap, bool bEllipsis, int nLetterSpacing, float flMaxWidth, float flMaxHeight ) = 0;
+ virtual void FreeTextLayout( IUITextLayout *pLayout ) = 0;
+ virtual const CUtlSortVector< CUtlString > &GetSortedValidFontNames() = 0;
+
+
+ virtual IUIInput *UIInputEngine() = 0;
+ virtual IUILocalization *UILocalize() = 0;
+ virtual IUISoundSystem *UISoundSystem() = 0;
+ virtual IUISettings *UISettings() = 0;
+ virtual IUILayoutManager *UILayoutManager() = 0;
+ virtual IUIFileSystem *UIFileSystem() = 0;
+
+ virtual void RegisterFrameFunc( PanoramaFrameFunc_t frameFunc ) = 0;
+
+ virtual void ReloadLayoutFile( CPanoramaSymbol symPath ) = 0;
+ virtual void ToggleDebugMode() = 0;
+ virtual CUtlLinkedList<CUtlString> &GetConsoleHistory() = 0;
+
+ // panel management
+ virtual IUIPanel * CreatePanel() = 0;
+ virtual void PanelDestroyed( IUIPanel *pPanel, IUIPanel *pOldParent ) = 0;
+ virtual bool IsValidPanelPointer( const IUIPanel *pPanel ) = 0;
+ virtual PanelHandle_t GetPanelHandle( const IUIPanel *pPanel ) = 0;
+ virtual IUIPanel *GetPanelPtr( const PanelHandle_t &handle ) = 0;
+ virtual void CallBeforeStyleAndLayout( IUIPanel *pPanel ) = 0;
+
+ // registration for panel destroyed
+ typedef CUtlDelegate< void( const panorama::IUIPanel *, IUIPanel *pOldParent ) > PanelDestroyedDel_t;
+ virtual void RegisterForPanelDestroyed( PanelDestroyedDel_t del ) = 0;
+ virtual void UnregisterForPanelDestroyed( PanelDestroyedDel_t del ) = 0;
+
+ // Event management
+ virtual void RegisterEventHandler( CPanoramaSymbol symMsg, IUIPanel *pPanel, CUtlAbstractDelegate pFunc ) = 0;
+ virtual void UnregisterEventHandler( CPanoramaSymbol symMsg, IUIPanel *pPanel, CUtlAbstractDelegate pFunc ) = 0;
+ virtual void RegisterEventHandler( CPanoramaSymbol symMsg, IUIPanelClient *pPanel, CUtlAbstractDelegate pFunc ) = 0;
+ virtual void UnregisterEventHandler( CPanoramaSymbol symMsg, IUIPanelClient *pPanel, CUtlAbstractDelegate pFunc ) = 0;
+ virtual void UnregisterEventHandlersForPanel( IUIPanel *pPanel ) = 0;
+ virtual void RegisterForUnhandledEvent( CPanoramaSymbol symMsg, CUtlAbstractDelegate pFunc ) = 0;
+ virtual void UnregisterForUnhandledEvent( CPanoramaSymbol symMsg, CUtlAbstractDelegate pFunc ) = 0;
+ virtual bool BHaveEventHandlersRegisteredForType( CPanoramaSymbol symPanelType ) = 0;
+ virtual void RegisterPanelTypeEventHandler( CPanoramaSymbol symMsg, CPanoramaSymbol symPanelType, CUtlAbstractDelegate pFunc, bool bThisPtrIsUIPanel = false ) = 0;
+ virtual bool DispatchEvent( IUIEvent *pEvent ) = 0;
+ virtual void DispatchEventAsync( float flDelay, IUIEvent *pEvent ) = 0;
+ virtual bool BAnyHandlerRegisteredForEvent( const CPanoramaSymbol &symEvent ) = 0;
+ virtual CPanoramaSymbol GetLastDispatchedEventSymbol() = 0;
+ virtual IUIPanel *GetLastDispatchedEventTargetPanel() = 0;
+
+ // Event filtering
+ virtual void RegisterEventFilter( CUtlAbstractDelegate pFunc ) = 0;
+ virtual void UnregisterEventFilter( CUtlAbstractDelegate pFunc ) = 0;
+
+ // Repaints all windows immediately, queuing for animation/render threads
+ virtual void LayoutAndPaintWindows() = 0;
+
+ // Get install path for the application
+ virtual const char *GetApplicationInstallPath() = 0;
+
+ // Get the userdata path for the application
+ virtual const char *GetApplicationUserDataPath() = 0;
+
+ // Register a named local path (executable-relative, readonly on POSIX) for resources, should be something like {images} or {movies}
+ virtual void RegisterNamedLocalPath( const char *pathName, const char *pchLocalPath, bool bWatchForFileChanges, bool bAddToOverwriteIfExists = false ) = 0;
+
+ // Register a named userdata path (userdata-relative, writable on POSIX) for local read/write storage like {config}
+ virtual void RegisterNamedUserPath( const char *pathName, const char *pchUserPath, bool bWatchForFileChanges, bool bAddToOverwriteIfExists = false ) = 0;
+
+ // Register the path to load custom vfont files from
+ virtual void RegisterCustomFontPath( const char *pchFontPath ) = 0;
+
+ // Get the local path for a named path like {images} or {movies}
+ virtual const char *GetLocalPathForNamedPath( const char *pathName ) = 0;
+
+ // Get the local path for a named path like {images} or {movies} combined with the relative pathname
+ // and also following up the possible overwritten paths
+ virtual void GetLocalPathForRelativePath( const char *pchLocalPathName, const char *pchRelativePathname, CUtlString &strLocalPath ) = 0;
+
+ // Register for a named hostname in http:// paths like {steamcommunity}
+ virtual void RegisterNamedRemoteHost( const char *hostName, const char*pchRemoteHost ) = 0;
+
+ // Get the named host for a named remote host like {steamcommunity}
+ virtual const char *GetRemoteHostForNamedHost( const char *hostName ) = 0;
+
+ // Register an additional X-Header to be sent when requesting layout from the web
+ virtual void RegisterXHeader( const char *pchHeaderName, const char *pchHeaderValue ) = 0;
+
+ // Get the current count of registers X-Headers
+ virtual int GetXHeaderCount() const = 0;
+
+ // Get the name and value for the given indexed X-Header
+ virtual void GetXHeader( int i, CUtlString &strName, CUtlString &strValue ) const = 0;
+
+ // Set the cookie header to use for the named remote host
+ virtual void SetCookieHeaderForNamedRemoteHost( const char *hostName, const CUtlVector<CUtlString> &vecCookies ) = 0;
+
+ // Sets the cookie header to use for the remote host (doesn't require named host use)
+ virtual void SetCookieHeaderForRemoteHost( const char *hostName, const CUtlVector<CUtlString> &vecCookies ) = 0;
+
+ // Get the cookie header string that should be used for the remote host
+ virtual const CUtlVector<CUtlString> &GetCookieHeadersForNamedRemoteHost( const char *namedRemoteHost ) = 0;
+
+ // Get the cookie header string that should be used for the remote host
+ virtual const CUtlVector<CUtlString> &GetCookieHeadersForRemoteHost( const char *hostName ) = 0;
+
+ // Gets the value of a cookie. Returns false if the cookie does not exist.
+ virtual bool GetCookieValueForRemoteHost( const char *hostName, const char *cookieName, CUtlString *pstrCookieValue ) = 0;
+
+#if defined( SOURCE2_PANORAMA ) || defined( PANORAMA_PUBLIC_STEAM_SDK )
+ virtual ISteamHTMLSurface *AccessHTMLController() = 0;
+#else
+ virtual IHTMLChromeController *AccessHTMLController() = 0;
+#endif
+
+ // native message box. Used usually for development.
+ enum ENativeMessageBoxType_t
+ {
+ k_ENativeMessageOk = 1,
+ k_ENativeMessageYesNo = 2
+ };
+ virtual bool ShowNativeTopMostMessageBox( const char *pchMsg, const char *pchTitle, ENativeMessageBoxType_t eType ) = 0;
+
+ // Add a listener callback for pre/post frame events
+ virtual void AddFrameListener( IUIEngineFrameListener *pListener ) = 0;
+
+ // Remove a listener callback for pre/post frame events
+ virtual void RemoveFrameListener( IUIEngineFrameListener *pListener ) = 0;
+
+ // storage for mouse can activate info
+ virtual void RegisterMouseCanActivateParent( IUIPanel *pPanel, const char *pchParent ) = 0;
+ virtual void UnregisterMouseCanActivateParent( IUIPanel *pPanel ) = 0;
+ virtual const char *GetMouseCanActivateParent( IUIPanel *pPanel ) = 0;
+
+ // See if any window owned by the ui engine has focus
+ virtual bool BAnyWindowHasFocus() = 0;
+
+ // See if any window owned by the ui engine is visible and has focus, sometimes overlay windows have focus but are not visible
+ // and you generally don't want to consider them as focused then
+ virtual bool BAnyVisibleWindowHasFocus() = 0;
+
+ // See if any overlay window owned by the ui engine has focus
+ virtual bool BAnyOverlayWindowHasFocus() = 0;
+
+ // Get the focused window, there should really be only one, if some bug allows multiple the first found is returned
+ virtual IUIWindow *GetFocusedWindow() = 0;
+
+ // Get the last time any input event happened across any of our windows
+ virtual double GetLastInputTime() = 0;
+
+ // Called internally from input layer to update last input time to current frame
+ virtual void UpdateLastInputTime() = 0;
+
+ // Clipboard access
+ virtual void CopyToClipboard( const char *pchTextUTF8 ) = 0;
+ virtual void GetClipboardText( CUtlString &strUTF8 ) = 0;
+
+ // Input locale support
+ virtual ELanguage GetDisplayLanguage() = 0;
+ virtual ELanguage GetCurrentInputLocale() = 0;
+ virtual bool BHaveInputLocale( ELanguage language ) = 0;
+ virtual void SetInputLocale( ELanguage language ) = 0;
+
+ // Overlay tracking
+ virtual bool BHasOverlayForApp( uint64 gameID, uint64 ulPID ) = 0;
+ virtual void TrackOverlayForApp( uint64 gameID, uint64 ulPID, void * pOverlay ) = 0;
+ virtual void DeleteOverlayInstanceForApp( uint64 gameID, uint64 dwPID, void * pOverlay ) = 0;
+ virtual void *OverlayForApp( uint64 gameID, uint64 ulPID ) = 0;
+
+ // GPU Information
+ virtual bool BGetGPUInformation( char *rgchGPUDesc, uint32 unGPUDescBytes, uint64 *pulDedicatedGPUMem, uint64 *pulDedicatedSystemMem, uint64 *pulSharedMem ) = 0;
+
+ // Pool allocations for panel styles
+ virtual IUIPanelStyle *AllocPanelStyle( IUIPanel *pStyle, float flUIScaleFactor ) = 0;
+ virtual void FreePanelStyle( IUIPanelStyle *pPanel ) = 0;
+
+ virtual void SetPanelWaitingAsyncDelete( IUIPanel *pPanel ) = 0;
+ virtual bool BIsPanelWaitingAsyncDelete( IUIPanel *pPanel ) = 0;
+
+ virtual void PulseActiveControllerHaptic( EHapticFeedbackPosition ePosition, EHapticFeedbackStrength eStrength ) = 0;
+
+ virtual void MarkLayerToRepaintThreadSafe( uint64 ulCompositionLayerID ) = 0;
+
+ virtual void AddDirectoryChangeWatch( const char *pchPath ) = 0;
+
+ // Get how many lines to scroll for mouse wheel
+ virtual uint32 GetWheelScrollLines() = 0;
+
+ // Execute some javascript in the given panel context
+ virtual void RunScript( IUIPanel *pPanelContext, const char *pchScriptString, const char *pchSourceFilename, int nSourceBeginLine, int nSourceBeginCol, bool bPrintRetValue ) = 0;
+
+ // Expose a new object type/template to javascript with the given name,
+ // the function pointer passed should setup member accssors/methods with the functions
+ // from uijsregistration.h
+ virtual void ExposeObjectTypeToJavaScript( const char *pchObjectTypeName, CUtlAbstractDelegate &del ) = 0;
+
+ // Expose an instance of an object type as a global with specified name to javascript
+ virtual void ExposeGlobalObjectToJavaScript( const char *pchJSVarName, void *pInstance, const char *pchJsTypeName, bool bTrueGlobal = false ) = 0;
+
+ virtual void ClearGlobalObjectForJavaScript( const char *pchJSVarName, void *pInstance ) = 0;
+
+ virtual void DeleteJSObjectInstance( IUIJSObject *pInstance ) = 0;
+
+ // Get panel that contains the javascript context
+ virtual panorama::IUIPanel *GetPanelForJavaScriptContext( v8::Context *pContext ) = 0;
+
+ // Get javascript context for a panel (may be NULL)
+ virtual v8::Persistent<v8::Context> *GetJavaScriptContextForPanel( panorama::IUIPanel *pPanel ) = 0;
+
+ // Helper to spew exceptions to console
+ virtual void OutputJSExceptionToConsole( v8::TryCatch &try_catch, IUIPanel *pPanelContext ) = 0;
+
+ // Add a function template to global namespace, by default this is really panorama., but you can specify to make it really global as well
+ virtual void AddGlobalV8FunctionTemplate( const char *pchJSFuncName, v8::Handle< v8::FunctionTemplate > *pFunc, bool bTrueGlobal = false ) = 0;
+
+ // Get global v8 context
+ virtual v8::Persistent<v8::Context> &GetV8GlobalContext() = 0;
+
+ // Access the current object template we are setting up
+ virtual v8::Handle<v8::ObjectTemplate> GetCurrentV8ObjectTemplateToSetup() = 0;
+
+ // Allow access to the proto buf msg memory pool
+ virtual CUIProtoBufMsgMemoryPoolMgr *MsgMemoryPoolMgr() = 0;
+
+ // Allow access to style factory interface
+ virtual IUIStyleFactory *UIStyleFactory() = 0;
+
+ // Various code that uses JS needs this
+ virtual v8::Isolate * GetV8Isolate() = 0;
+
+ // Create a V8 object to wrap a panel
+ virtual v8::Persistent<v8::Object> *CreateV8PanelInstance( IUIPanel *pPanel ) = 0;
+
+ // Helper to create a JS object to wrap a given panel style
+ virtual v8::Persistent<v8::Object> *CreateV8PanelStyleInstance( IUIPanelStyle *pPanelStyle ) = 0;
+
+ // Helper to create JS object for given js object type
+ virtual v8::Persistent<v8::Object> *CreateV8ObjectInstance( const char *pchObjectType, void *pActualObject, IUIJSObject *pJSObject ) = 0;
+
+ // Create JSON web api job, use the helpers in uiwebapiclient.h directly instead, this is there for them to use internally
+ virtual uint32 InitiateAsyncJSONWebAPIRequest( EHTTPMethod eMethod, CUtlString strURL, IUIPanel *pCallbackTargetPanel, void *pContext, CJSONWebAPIParams *pParams = NULL, HTTPCookieContainerHandle hCookieContainer = INVALID_HTTPCOOKIE_HANDLE ) = 0;
+
+ // Create JSON web api job, use the helpers in uiwebapiclient.h directly instead, this is there for them to use internally
+ virtual uint32 InitiateAsyncJSONWebAPIRequest( EHTTPMethod eMethod, CUtlString strURL, JSONWebAPIDelegate_t callback, void *pContext, CJSONWebAPIParams *pParams = NULL, HTTPCookieContainerHandle hCookieContainer = INVALID_HTTPCOOKIE_HANDLE ) = 0;
+
+ // Cancel previously created web api request job
+ virtual void CancelAsyncJSONWebAPIRequest( uint32 requestID ) = 0;
+
+ // Resolves a path that may contain named path portions, etc, to a full local path
+ virtual CUtlString ResolvePath( const char *pchPath ) = 0;
+
+ // Used internally by initialization code to register events with framework
+ virtual void RegisterEventWithEngine( CPanoramaSymbol symEvent, UIEventFactory factory ) = 0;
+
+ // Check if a symbol is a valid event name
+ virtual bool IsValidEventName( const CPanoramaSymbol symEvent ) = 0;
+
+ // Check if a symbol is a valid panel event name
+ virtual bool IsValidPanelEvent( const CPanoramaSymbol symEvent, int *pParams ) = 0;
+
+ // Create input event from symbol, internal framework use
+ virtual IUIEvent *CreateInputEventFromSymbol( CPanoramaSymbol symEvent, IUIPanel *pPanel, EPanelEventSource_t eSource, int nRepeats ) = 0;
+
+ // Create an event from a string representation
+ virtual IUIEvent *CreateEventFromString( IUIPanel *pCreatingPanel, const char *pchEvent, const char **pchEventEnd ) = 0;
+
+ // Used internally by initialization code to register panels with framework
+ virtual void RegisterPanelFactoryWithEngine( CPanoramaSymbol symPanelType, CPanel2DFactory *pFactory ) = 0;
+
+ // Is the panel type registered
+ virtual bool BRegisteredPanelType( CPanoramaSymbol symPanelType ) = 0;
+
+ // Factory func for creating panels
+ virtual IUIPanelClient *CreatePanel( CPanoramaSymbol symName, const char *pchID, panorama::IUIPanel *parent ) = 0;
+
+ // Create debugger window
+ virtual void CreateDebuggerWindow() = 0;
+
+ // Close debugger window
+ virtual void CloseDebuggerWindow() = 0;
+
+ // Register any delegate to run at specified time, be sure to use CancelScheduledDelgate if you delete the object the delgate runs on, etc.
+ virtual int RegisterScheduledDelegate( double flTargetFrameTime, CUtlDelegate< void() > del ) = 0;
+
+ // Cancel a scheduled delegate by index returned from RegisterScheduledDelegate
+ virtual void CancelScheduledDelegate( int iScheduleIndex ) = 0;
+
+ // Return the last frame time for which we already ran scheduled delegates
+ virtual double GetLastScheduledDelegateRunTime() = 0;
+
+ // CPanoramaSymbol support for cross DLL symbols
+ virtual UtlSymId_t MakeSymbol( const char *pchText ) = 0;
+
+ // CPanoramaSymbol support for cross DLL symbols
+ virtual const char * ResolveSymbol( const UtlSymId_t sym ) = 0;
+
+ // Interface to allow animation/render threads to queue a decrement of a ref count on an object next frame in the main thread
+ virtual void QueueDecrementRefNextFrame( CRefCount *pRefCountObj ) = 0;
+
+ // Register a V8 callback function associated with a given UI panel
+ virtual JSGenericCallbackHandle_t RegisterJSGenericCallback( panorama::IUIPanel *pContextPanel, v8::Handle< v8::Function > callbackFunc ) = 0;
+
+ // Invoke a callback previously registered with the system. Returns false if the handle has expired (the context panel is gone, or it was explicitly unregistered)
+ virtual bool InvokeJSGenericCallback( JSGenericCallbackHandle_t nHandle, int nArgs = 0, v8::Handle< v8::Value > *pArgs = NULL, v8::Handle< v8::Value > *pOutRetVal = NULL ) = 0;
+
+ // Explicitly remove the callback from the system (future invokes on the handle will do nothing and return false)
+ virtual void UnregisterJSGenericCallback( JSGenericCallbackHandle_t nHandle ) = 0;
+
+ // Return the number of scopes, such as classes, that JS functions
+ // have been registered in.
+ virtual int GetNumRegisterJSScopes() = 0;
+
+ // Return information on a JS registration scope.
+ virtual void GetRegisterJSScopeInfo( int nScope, RegisterJSScopeInfo_t *pInfo ) = 0;
+
+ // Return information on a specific entry in a JS registration scope,
+ // such as a method in a class scope.
+ virtual void GetRegisterJSEntryInfo( int nScope, int nEntry, RegisterJSEntryInfo_t *pInfo ) = 0;
+
+ // Open a new scope for JS registrations.
+ virtual int StartRegisterJSScope( const char *pName, const char *pDesc = NULL ) = 0;
+
+ // Close current JS registration scope.
+ virtual void EndRegisterJSScope() = 0;
+
+ // If there is a current JS registration scope allocate a new entry
+ // and fill it out. If there is no scope, which is possible as
+ // recording registration info is only enabled in certain places,
+ // this will return -1.
+ virtual int NewRegisterJSEntry( const char *pName, uint32 unFlags, const char *pDesc = NULL, RegisterJSType_t eDataType = k_ERegisterJSTypeUnknown ) = 0;
+
+ // If there is a current JS registration entry set the parameter
+ // type information in it. Silently ignores -1 entry indices
+ // so this can be called safely when there is no scope.
+ virtual void SetRegisterJSEntryParams( int nEntry, uint8 unNumParams, RegisterJSType_t *pParamTypes ) = 0;
+
+ // Invalidate cached copies of all layout/style/script files (used eg. by the game when search paths change)
+ // (Does NOT rebuild or reload any existing UI, just causes subsequent references to the files to load from scratch.)
+ virtual void ClearFileCache() = 0;
+
+ // Spew the current list of all cached files and their refcounts (for debugging)
+ virtual void PrintCacheStatus() = 0;
+
+ // get a list of all the windows owned by the engine
+ virtual void GetWindowsForDebugger( CUtlVector<IUIWindow *> &vecWindows ) = 0;
+
+ // Turn on paint count tracking for panels
+ virtual void SetPaintCountTrackingEnabled( bool bEnablePaintCountTracking ) = 0;
+
+ // Is paint count tracking on for panels
+ virtual bool GetPaintCountTrackingEnabled() = 0;
+
+ // Increment paint count tracking for panels
+ virtual void IncrementPaintCountForPanel( uint64 ulPanelPtrValue, bool bRequiredCompositionLayer, double flFrameTime ) = 0;
+
+ // Get panel paint info for the panel
+ virtual void GetPanelPaintInfo( uint64 ulPanelPtrValue, uint32 &unPaintCount, bool &bRequiredCompositionLayer, double &flFrameTimeLastPaint ) = 0;
+
+ // Returns whether any windows exist for the UI engine
+ virtual bool BHasAnyWindows() = 0;
+
+#ifdef DBGFLAG_VALIDATE
+ // Memory validation related interfaces
+ virtual bool PrepareForValidate() = 0;
+ virtual bool ResumeFromValidate() = 0;
+ virtual void Validate( CValidator &validator, const tchar *pchName ) = 0;
+#endif
+
+#if defined( SOURCE2_PANORAMA )
+ virtual void TextEntryFocusChange( IUIPanel *pPanel ) = 0;
+ virtual void TextEntryInvalid( IUIPanel *pPanel ) = 0;
+#endif
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper for render state transitions, returns true if a state
+// change is being requested, and it is valid. Helper for fullscreen switching.
+//-----------------------------------------------------------------------------
+inline bool IUIEngine::BValidRenderStateChange( ERenderTarget eCurrentRenderTarget, ERenderTarget eRequestedRenderTarget )
+{
+ if( eCurrentRenderTarget == eRequestedRenderTarget )
+ return false;
+
+ // if we are in a mode that can switch...
+ if( eCurrentRenderTarget == IUIEngine::k_ERenderFullScreen || eCurrentRenderTarget == IUIEngine::k_ERenderToWindow )
+ {
+ switch( eRequestedRenderTarget ) // test if request is for a state that can be switched to
+ {
+ case IUIEngine::k_ERenderFullScreen:
+ case IUIEngine::k_ERenderToWindow:
+ return true; // we can change
+ default:
+ return false; // not so much
+ }
+ }
+
+ // render to texture toggled shared vs copied texture
+ if( BIsRenderingToTexture( eCurrentRenderTarget ) &&
+ BIsRenderingToTexture( eRequestedRenderTarget ) &&
+ (eCurrentRenderTarget != eRequestedRenderTarget) )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+#ifndef PANORAMA_EXPORTS
+extern IUIEngine *g_pUIEngineSingleton;
+extern CSysModule *g_PanoramaModule;
+
+inline IUIEngine *UIEngine() { return g_pUIEngineSingleton; }
+inline IUILocalization *UILocalize() { return UIEngine()->UILocalize(); }
+inline IUISoundSystem *UISoundSystem() { return UIEngine()->UISoundSystem(); }
+inline IUIInput *UIInputEngine() { return UIEngine() ? UIEngine()->UIInputEngine() : NULL; }
+#else
+IUIEngine *UIEngine();
+IUILocalization *UILocalize();
+IUIInput *UIInputEngine();
+IUISoundSystem *UISoundSystem();
+#endif
+
+#ifdef DBGFLAG_VALIDATE
+PANORAMA_INTERFACE void ValidateStaticsInternal( CValidator &validator );
+#endif
+
+PANORAMA_INTERFACE IUIEngine *CreatePanoramaUIEngineInternal();
+
+extern void RegisterEventTypesWithEngine( IUIEngine *pEngine );
+
+#ifndef PANORAMA_EXPORTS
+extern bool LoadPanoramaModule( const char *pchPanoramaModulePath );
+extern void UnloadPanoramaModule();
+
+extern IUIEngine *CreatePanoramaUIEngine();
+extern void ConnectPanoramaUIEngine( IUIEngine * );
+extern void ShutdownPanoramaUIEngine( IUIEngine * );
+
+#ifdef DBGFLAG_VALIDATE
+extern void ValidateStatics( CValidator &validator );
+#endif
+#endif
+
+
+// To expose a generic object via UIEngine()->ExposeObjectTypeToJavaScript() you should derive from this interface
+// the GetTypeName member should return the same type name you register as exposed
+class IUIJSObject
+{
+public:
+ ~IUIJSObject()
+ {
+ UIEngine()->DeleteJSObjectInstance( this );
+ }
+
+ virtual const char *GetJSTypeName() = 0;
+};
+
+
+} // namespace panorama
+
+#endif // IUIENGINE_H
diff --git a/public/panorama/iuifilesystem.h b/public/panorama/iuifilesystem.h
new file mode 100644
index 0000000..10aaf42
--- /dev/null
+++ b/public/panorama/iuifilesystem.h
@@ -0,0 +1,51 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUIFILESYSTEM_H
+#define IUIFILESYSTEM_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "panoramatypes.h"
+#include "utlbuffer.h"
+
+namespace panorama
+{
+
+typedef void( __cdecl *FileChangeCallback_t )( const char *pFullPath );
+
+//-----------------------------------------------------------------------------
+// Purpose: FileSystem support
+//-----------------------------------------------------------------------------
+
+typedef void (LoadFileIntoBufferCallback_t)( const char * pchFile, CUtlBuffer &buf, bool bSuccess );
+
+class IUIFileSystem
+{
+public:
+ // fully load the file into the buffer object
+ virtual bool LoadFileIntoBuffer( const char *pchFile, CUtlBuffer &buf, bool bText, FileChangeCallback_t fileChangeCallback = NULL ) = 0;
+
+ virtual void LoadFileIntoBufferAsync( const char *pchFile, CUtlBuffer &buf, bool bText, CUtlDelegate< LoadFileIntoBufferCallback_t > del ) = 0;
+
+ // replace this file with the contents of the buffer object
+ virtual bool SaveBufferToFile( CUtlBuffer &buf, const char *pchFile ) = 0;
+
+ // return true if this file is on disk (or in a resource file)
+ virtual bool FileExists( const char *pchFile ) = 0;
+
+ virtual bool RestoreContentFilename( const char *pchFile, CUtlString &fixedFilename ) { return false; }
+ virtual bool RestoreResourceFilename( const char *pchFile, CUtlString &fixedFilename ) { return false; }
+
+ // Run frame on main thread
+ virtual void RunFrame() = 0;
+};
+
+
+}
+#endif // IUIFILESYSTEM_H
diff --git a/public/panorama/iuilayoutmanager.h b/public/panorama/iuilayoutmanager.h
new file mode 100644
index 0000000..3d67cdb
--- /dev/null
+++ b/public/panorama/iuilayoutmanager.h
@@ -0,0 +1,64 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUILAYOUTMANAGER_H
+#define IUILAYOUTMANAGER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panoramatypes.h"
+#include "panoramasymbol.h"
+#include "layout/stylefiletypes.h"
+
+namespace panorama
+{
+
+class CStyleAnimation;
+
+class IUILayoutFile
+{
+public:
+ virtual bool BReplaceDefines( CPanoramaSymbol symStyleFile, char *rgchBuffer, uint cubBuffer ) = 0;
+ virtual void BuildMatchingStyleList( CUtlVector< CascadeStyleFileInfo_t > &vecStyles, const CPanelIdentifiers &panelID, IUILayoutFile *pPreviousLayoutFile ) = 0;
+
+ virtual CPanoramaSymbol GetStyleFileSymbol( int i ) const = 0;
+ virtual CPanoramaSymbol GetLayoutFileSymbol() const = 0;
+
+ virtual const CStyleAnimation *GetAnimation( CPanoramaSymbol symName ) = 0;
+
+ virtual const char *GetDefine( const char *pchName ) = 0;
+
+ virtual bool ApplyMatchedStylesToPanelStyle( IUIPanelStyle *pPanelStyle, const CUtlVector< CascadeStyleFileInfo_t > &vecStyles, EStyleRepaint &eRepaint, bool &bInheritablePropertiesChanged ) = 0;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Public interface to layout mamanger. Manages layout files, styles, etc.
+//-----------------------------------------------------------------------------
+class IUILayoutManager
+{
+public:
+
+ // in memory updates
+ enum EUpdateStyleType
+ {
+ k_EUpdateStyleStyle = 0,
+ k_EUpdateStyleKeyframes = 1,
+ };
+
+ virtual IUILayoutFile *GetLayoutFile( const char *pchFile, bool bPartialLayout ) = 0;
+ virtual IUILayoutFile *GetLayoutFile( CPanoramaSymbol symPath ) = 0;
+ virtual void SaveInMemoryFiles() = 0;
+ virtual void RevertInMemoryFiles() = 0;
+ virtual bool BHasFilesInMemory() const = 0;
+ virtual bool LoadStyleIntoBuffer( CPanoramaSymbol symFile, CUtlBuffer &buffer ) = 0;
+ virtual bool UpdateStyleInMemory( EUpdateStyleType eUpdateType, CPanoramaSymbol symStyleFile, uint unLocation, const char *pchUpdatedStyle ) = 0;
+ virtual bool BConvertHTTPPathToLocalP4Path( const char *pchFile, CUtlString &strOut ) = 0;
+};
+
+} // namespace panorama
+
+#endif // IUILAYOUTMANAGER_H \ No newline at end of file
diff --git a/public/panorama/iuipanel.h b/public/panorama/iuipanel.h
new file mode 100644
index 0000000..06efcd7
--- /dev/null
+++ b/public/panorama/iuipanel.h
@@ -0,0 +1,578 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUIPANEL_H
+#define IUIPANEL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panoramatypes.h"
+#include "panoramasymbol.h"
+#include "iuirenderengine.h"
+#include "layout/stylefiletypes.h"
+#include "layout/uilength.h"
+#include "tier1/utlstring.h"
+
+namespace panorama
+{
+
+class CLayoutFile;
+class IUIPanelStyle;
+class IUIPanelClient;
+class IUIWindow;
+class IUIImageManager;
+class IUI3DSurface;
+class IUIEvent;
+class IUIScrollBar;
+typedef panorama::IUIPanelClient * ClientPanelPtr_t;
+typedef CUtlVector< panorama::IUIEvent * > VecUIEvents_t;
+
+//-----------------------------------------------------------------------------
+// Purpose: Used to provide property info to debugger for output
+//-----------------------------------------------------------------------------
+struct DebugPropertyOutput_t
+{
+ DebugPropertyOutput_t() {}
+ DebugPropertyOutput_t( const char *pchName, const char *pchValue ) : m_strName( pchName ), m_strValue( pchValue ) {}
+
+ CUtlString m_strName;
+ CUtlString m_strValue;
+};
+
+
+enum ScrollBehavior_t
+{
+ SCROLL_BEHAVIOR_SCROLL_MINIMUM_DISTANCE = 0,
+ SCROLL_BEHAVIOR_SCROLL_TO_TOPLEFT_EDGE,
+ SCROLL_BEHAVIOR_SCROLL_TO_BOTTOMRIGHT_EDGE,
+ SCROLL_BEHAVIOR_SCROLL_TO_CENTER,
+
+ SCROLL_BEHAVIOR_DEFAULT = SCROLL_BEHAVIOR_SCROLL_MINIMUM_DISTANCE,
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Basic panel interface exposing operations used inside of panorama, rather
+// than operations that are part of building/laying out controls in the panorama_client module
+//-----------------------------------------------------------------------------
+class IUIPanel
+{
+public:
+ virtual ~IUIPanel() {}
+
+ // Initialize panel
+ virtual void Initialize( IUIWindow *window, IUIPanel *parent, const char *pchID, uint32 ePanelFlags ) = 0;
+
+ // Initialize a cloned panel from ourself
+ virtual void InitClonedPanel( IUIPanel *pClone ) = 0;
+
+ // Do panel2d event type registrations
+ virtual void RegisterEventHandlersOnPanel2DType( CPanoramaSymbol symPanelType ) = 0;
+
+ // Shutdown panel, should only happen right before actual deletion
+ virtual void Shutdown() = 0;
+
+ // Fire panel loaded event and mark us as now loaded, images and other panels may call this late
+ virtual void FirePanelLoadedEvent() = 0;
+
+ // Gets client type pointer value
+ virtual void SetClientPtr( panorama::IUIPanelClient *pPtr ) = 0;
+ virtual panorama::IUIPanelClient * ClientPtr() const = 0;
+
+ // Set panel id
+ virtual void SetID( const char *pchID ) = 0;
+
+ // Get panel id
+ virtual const char *GetID() const = 0;
+
+ // Get panel type, which really calls back into client panel object
+ virtual CPanoramaSymbol GetPanelType() const = 0;
+
+ // Check for valid panel id
+ virtual bool BHasID() const = 0;
+
+ // sets & loads the layout file for this panel
+ virtual bool BLoadLayout( const char *pchFile, bool bOverrideExisting = false, bool bPartialLayout = false ) = 0;
+
+ // sets & loads the layout for this panel
+ virtual bool BLoadLayoutFromString( const char *pchXMLString, bool bOverrideExisting = false, bool bPartialLayout = false ) = 0;
+
+ // sets loads the layout file for this panel, asynchronously supporting remote http:// paths
+ virtual void LoadLayoutAsync( const char *pchFile, bool bOverrideExisting = false, bool bPartialLayout = false ) = 0;
+
+ // loads the layout file for this panel, asynchronously supporting remote http:// paths in css within
+ virtual void LoadLayoutFromStringAsync( const char *pchXMLString, bool bOverrideExisting, bool bPartialLayout = false ) = 0;
+
+ // Check if the panel has loaded layout
+ virtual bool IsLoaded() const = 0;
+
+ // Set panel's immediate parent
+ virtual void SetParent( panorama::IUIPanel *pParent ) = 0;
+
+ // Get panel's immediate parent
+ virtual panorama::IUIPanel *GetParent() const = 0;
+
+ // Get panel's parent window
+ virtual panorama::IUIWindow *GetParentWindow() const = 0;
+
+ // Set panel visibility
+ virtual void SetVisible( bool bVisible ) = 0;
+
+ // Is the panel visible (not accounting for opacity)
+ virtual bool BIsVisible() const = 0;
+
+ // Is the panel transparent (may be 'visible' and affect layout, but fully transparent)
+ virtual bool BIsTransparent() const = 0;
+
+ // Set the layout file this panel is loaded from based on a parent, shouldn't need this directly normally
+ virtual void SetLayoutLoadedFromParent( panorama::IUIPanel *pParent ) = 0;
+
+ // Returns the layout file for this panel (ie, the one it loaded if any)
+ virtual panorama::CPanoramaSymbol GetLayoutFile() const = 0;
+
+ // Returns layout file that loaded us which may have been loaded by an ancestor rather than direct parent
+ virtual panorama::CPanoramaSymbol GetLayoutFileLoadedFrom() const = 0;
+
+ // Get the current reload count for the panel's layout file - can be used to detect when a reload has occurred
+ // Returns -1 if no layout file.
+ virtual int GetLayoutFileReloadCount() const = 0;
+
+ // searches only immediate children
+ virtual panorama::IUIPanel *FindChild( const char *pchID ) = 0;
+
+ // searches all children even outside layout file scope
+ virtual panorama::IUIPanel *FindChildTraverse( const char *pchID ) = 0;
+
+ // searches any children created from our layout file
+ virtual IUIPanel *FindChildInLayoutFile( const char *pchID ) = 0;
+
+ // searches any panel created from our layout file (so parents or children!)
+ virtual IUIPanel *FindPanelInLayoutFile( const char *pchID ) = 0;
+
+ // Check if this panel is a descendant of the passed panel
+ virtual bool IsDescendantOf( const panorama::IUIPanel *pPanel ) const = 0;
+
+ // Remove and delete all children from panel
+ virtual void RemoveAndDeleteChildren() = 0;
+
+ // Remove and delete all children matching type
+ virtual void RemoveAndDeleteChildrenOfType( CPanoramaSymbol symPanelType ) = 0;
+
+ // Child access
+ virtual int GetChildCount() const = 0;
+ virtual IUIPanel *GetChild( int i ) const = 0;
+ virtual IUIPanel *GetFirstChild() const = 0;
+ virtual IUIPanel *GetLastChild() const = 0;
+
+ // Return index of child in creation/panel vector order (also default tab order)
+ virtual int GetChildIndex( const IUIPanel *pChild ) const = 0;
+
+ // Get child count of specific type
+ virtual uint32 GetChildCountOfType( CPanoramaSymbol symPanelType ) = 0;
+
+ // For special children to be rendered in debugger
+ virtual int GetHiddenChildCount() const = 0;
+ virtual IUIPanel *GetHiddenChild( int i ) = 0;
+
+ // Find ancestor with matching id
+ virtual IUIPanel *FindAncestor( const char *pchID ) = 0;
+
+ // Set the panels repaint state
+ virtual void SetRepaint( panorama::EPanelRepaint eRepaintNeeded ) = 0;
+
+ // Check if we should draw this child
+ virtual bool BShouldDrawChild( panorama::IUIPanel *pChild ) = 0;
+
+ // Apply layout file to panel
+ virtual bool BAppyLayoutFile( panorama::CLayoutFile *pLayoutFile, CUtlVector< panorama::IUIPanel * > *pvecExistingPanels ) = 0;
+
+ // Enable or disable background movies on panel
+ virtual void EnableBackgroundMovies( bool bEnabled ) = 0;
+
+ // Access panel's style information
+ virtual panorama::IUIPanelStyle * AccessIUIStyle() = 0;
+
+ // Returns potentially dirty styles data, use for setting during initial construction/setup - or if you want to explicitly ignore transitions, but never for getting and generally not for setting!
+ virtual panorama::IUIPanelStyle *AccessIUIStyleDirty() = 0;
+
+ // Apply styles on the panel, resolving them all fully and updating actual panel style
+ virtual void ApplyStyles( bool bTraverse ) = 0;
+
+ // Set that we want an on styles changed event when styles are applied even if styles aren't actually dirty
+ virtual void SetOnStylesChangedNeeded() = 0;
+
+ // Access all children directly
+ virtual CUtlVector<panorama::IUIPanel *> const &AccessChildren() = 0;
+
+ // Measure self and children. First pass of layout
+ virtual void DesiredLayoutSizeTraverse( float flMaxWidth, float flMaxHeight ) = 0;
+ virtual void DesiredLayoutSizeTraverse( float *pflDesiredWidth, float *pflDesiredHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions ) = 0;
+
+ // Tell us what your content size is
+ virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions ) = 0;
+
+ // Arrange children. Second pass of layout
+ virtual void LayoutTraverse( float x, float y, float flFinalWidth, float flFinalHeight ) = 0;
+
+ // Tell us how to actually layout children
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight ) = 0;
+
+ // called by flowing and custom layout passes to set position. Will properly handle transition being applied with styles
+ virtual void SetPositionFromLayoutTraverse( CUILength x, CUILength y, CUILength z ) = 0;
+
+ // methods to invalid certain parts of layout
+ virtual void InvalidateSizeAndPosition() = 0;
+ virtual void InvalidatePosition() = 0;
+ virtual void SetActiveSizeAndPositionTransition() = 0;
+ virtual void SetActivePositionTransition() = 0;
+ virtual bool IsSizeValid() = 0;
+ virtual bool IsPositionValid() = 0;
+ virtual bool IsChildSizeValid() = 0;
+ virtual bool IsChildPositionValid() = 0;
+ virtual bool IsSizeTransitioning() = 0;
+ virtual bool IsPositionTransitioning() = 0;
+ virtual bool IsChildPositionTransitioning() = 0;
+ virtual bool IsChildSizeTransitioning() = 0;
+ virtual void TransitionPositionApplied( bool bImmediate ) = 0;
+
+ // size getters
+ virtual float GetDesiredLayoutWidth() const = 0;
+ virtual float GetDesiredLayoutHeight() const = 0;
+
+ // Content size is what our contents actually take up, not accounting for fixed/relative
+ // size set on us in styles which affect desired layout size
+ virtual float GetContentWidth() const = 0;
+ virtual float GetContentHeight() const = 0;
+
+ // Actual size is the size given to the panel after layout, hopefully as big as its desired size.
+ // Actual size does NOT include margins (which are really in the parent).
+ virtual float GetActualLayoutWidth() const = 0;
+ virtual float GetActualLayoutHeight() const = 0;
+
+ // Render size is the size of the content for rendering, this is either the actual layout size, or if
+ // that is smaller than the content size + padding then it's the content size + padding.
+ virtual float GetActualRenderWidth() = 0;
+ virtual float GetActualRenderHeight() = 0;
+
+ // Offset will include position, alignment, and margin adjustments
+ virtual float GetActualXOffset() const = 0;
+ virtual float GetActualYOffset() const = 0;
+
+ // returns offset for drawing minus position
+ virtual float GetRawActualXOffset() const = 0;
+ virtual float GetRawActualYOffset() const = 0;
+
+ // Offset to apply to contents for scrolling
+ virtual float GetContentsYScrollOffset() const = 0;
+ virtual float GetContentsXScrollOffset() const = 0;
+ virtual float GetContentsYScrollOffsetTarget() const = 0;
+ virtual float GetContentsXScrollOffsetTarget() const = 0;
+ virtual double GetContentsXScrollTransitionStart() const = 0;
+ virtual double GetContentsYScrollTransitionStart() const = 0;
+ virtual float GetInterpolatedXScrollOffset() = 0;
+ virtual float GetInterpolatedYScrollOffset() = 0;
+
+ // Can the panel scroll further?
+ virtual bool BCanScrollUp() = 0;
+ virtual bool BCanScrollDown() = 0;
+ virtual bool BCanScrollLeft() = 0;
+ virtual bool BCanScrollRight() = 0;
+
+ // style class management
+ virtual void AddClass( const char *pchName ) = 0;
+ virtual void AddClass( CPanoramaSymbol symbol ) = 0;
+ virtual void AddClasses( const char *pchName ) = 0;
+ virtual void AddClasses( CPanoramaSymbol *pSymbols, uint cSymbols ) = 0;
+ virtual void RemoveClass( const char *pchName ) = 0;
+ virtual void RemoveClass( CPanoramaSymbol symName ) = 0;
+ virtual void RemoveClasses( const CPanoramaSymbol *pSymbols, uint cSymbols ) = 0;
+ virtual void RemoveClasses( const char *pchName ) = 0;
+ virtual void RemoveAllClasses() = 0;
+ virtual const CUtlVector< CPanoramaSymbol > &GetClasses() const = 0;
+ virtual bool BHasClass( const char *pchName ) = 0;
+ virtual bool BHasClass( CPanoramaSymbol symName ) = 0;
+ virtual bool BAscendantHasClass( const char *pchName ) = 0;
+ virtual bool BAscendantHasClass( CPanoramaSymbol symName ) = 0;
+ virtual void ToggleClass( const char *pchName ) = 0;
+ virtual void ToggleClass( CPanoramaSymbol symName ) = 0;
+ virtual void SetHasClass( const char *pchName, bool bHasClass ) = 0;
+ virtual void SetHasClass( CPanoramaSymbol symName, bool bHasClass ) = 0;
+ virtual void SwitchClass( const char *pchAttribute, const char *pchName ) = 0;
+ virtual void SwitchClass( const char *pchAttribute, CPanoramaSymbol symName ) = 0;
+
+ virtual bool BAcceptsInput() = 0;
+ virtual void SetAcceptsInput( bool bAllowInput ) = 0;
+ virtual bool BAcceptsFocus() const = 0;
+ virtual void SetAcceptsFocus( bool bAllowFocus ) = 0;
+ // true if it would normally sink input, but may not right now if disabled
+ virtual bool BCanAcceptInput() = 0;
+ virtual void SetDefaultFocus( const char *pchChildID ) = 0;
+ virtual const char *GetDefaultFocus() const = 0;
+ virtual void SetDisableFocusOnMouseDown( bool bDisable ) = 0;
+ virtual bool BFocusOnMouseDown() = 0;
+
+ // Should this panel be the top of an input hierarchy and keep track of focus within itself, not losing focus when a panel in some
+ // other hierarchy changes focus? Use this for panels that are peers like friends vs browser vs mainmenu in tenfoot
+ virtual bool BTopOfInputContext() = 0;
+ virtual void SetTopOfInputContext( bool bIsTopOfInputContext ) = 0;
+
+ virtual IUIPanel *GetParentInputContext() = 0;
+
+ // Get the default input focus child within this panel, may be null
+ virtual IUIPanel *GetDefaultInputFocus() = 0;
+
+ // Set focus to this panel, which will auto-scroll it into full view as well if parent has overflow: scroll
+ virtual bool SetFocus() = 0;
+
+ // Set the focus to this panel in it's input context, but do not make the context change if some other context currently
+ // has focus
+ virtual bool UpdateFocusInContext() = 0;
+
+ // Set the focus in response to receiving hover (on panels that a parent sets childfocusonhover), this will
+ // never scroll the parent.
+ virtual bool SetFocusDueToHover() = 0;
+
+ virtual void SetInputContextFocus() = 0;
+
+ // retrieve the style flags (map to CSS psuedo-classes) for this panel
+ virtual uint GetStyleFlags() const = 0;
+ virtual void AddStyleFlag( EStyleFlags eStyleFlag ) = 0;
+ virtual void RemoveStyleFlag( EStyleFlags eStyleFlag ) = 0;
+ virtual bool IsInspected() const = 0;
+ virtual bool BHasHoverStyle() const = 0;
+ virtual void SetSelected( bool bSelected ) = 0;
+ virtual bool IsSelected() const = 0;
+ virtual bool BHasKeyFocus() const = 0;
+ virtual bool BHasDescendantKeyFocus() const = 0;
+ virtual bool IsLayoutLoading() const = 0;
+
+ // enable/disable
+ virtual void SetEnabled( bool bEnabled ) = 0;
+ virtual bool IsEnabled() const = 0;
+
+ virtual bool IsActivationEnabled() = 0;
+
+ // Set activation disabled on this panel, input/focus still generally work, but Activate events won't be handled, useful to prevent a button
+ // being clicked when out of focus, but leave it able to be focused for later activation or such
+ virtual void SetActivationEnabled( bool bEnabled ) = 0;
+
+ // Set all our immediate children enabled/disabled
+ virtual void SetAllChildrenActivationEnabled( bool bEnabled ) = 0;
+
+ // Enable/disable hit testing of this panel, you may want a parent that is never hit test that has a large region, but clicks
+ // just pass through to other things behind it. Children may still hit test.
+ virtual void SetHitTestEnabled( bool bEnabled ) = 0;
+ virtual bool BHitTestEnabled() const = 0;
+ virtual void SetHitTestEnabledTraverse( bool bEnabled ) = 0;
+
+ // drag/drop
+ virtual void SetDraggable( bool bEnabled ) = 0;
+ virtual bool IsDraggable() const = 0;
+
+ // the input namespace to use for this panel
+ virtual const char *GetInputNamespace() const = 0;
+
+ virtual void SetInputNamespace( const char *pchNamespace ) = 0;
+
+ // Mark styles dirty for the panel
+ virtual void MarkStylesDirty( bool bIncludeChildren ) = 0;
+
+ // Check if styles are dirty for the panel
+ virtual bool BStylesDirty() const = 0;
+
+ // Check if styles are possibly dirty for any of our children
+ virtual bool BChildStylesDirty() = 0;
+
+ // Parse panel event for this panel
+ virtual bool BParsePanelEvent( CPanoramaSymbol symPanelEvent, const char *pchValue ) = 0;
+
+ // Check if panel event is set on panel for event type
+ virtual bool BIsPanelEventSet( CPanoramaSymbol symPanelEvent ) = 0;
+
+ // Check if the event is a valid panel event type
+ virtual bool BIsPanelEvent( CPanoramaSymbol symPanelEvent ) const = 0;
+
+ // Dispatch the panel event if the panel has something set for it now
+ virtual bool DispatchPanelEvent( CPanoramaSymbol symPanelEvent ) = 0;
+
+ // Get the containing panel for this panels javascript context
+ virtual panorama::IUIPanel *GetJavaScriptContextParent() const = 0;
+
+ // Accessor for appropriate image manager for panel
+ virtual panorama::IUIImageManager* UIImageManager() = 0;
+
+ // Accessor for appropriate 3d surface interface for this panel
+ virtual panorama::IUIRenderEngine *UIRenderEngine() = 0;
+
+ // Explicit call to paint the panel and all it's children, normally called internally by window
+ virtual void PaintTraverse() = 0;
+
+ // Tab index setting
+ virtual void SetTabIndex( float flTabIndex ) = 0;
+ virtual float GetTabIndex() const = 0;
+ virtual void SetSelectionPosition( float flXPos, float flYPos ) = 0;
+ virtual void SetSelectionPositionX( float flXPos ) = 0;
+ virtual void SetSelectionPositionY( float flYPos ) = 0;
+ virtual float GetSelectionPositionX() const = 0;
+ virtual float GetSelectionPositionY() const = 0;
+
+ // Tab index and selection position backing values rather than interpreted (ie. will return k_flSelectionPosAuto rather than the auto-calculated value)
+ virtual float GetTabIndex_Raw() const = 0;
+ virtual float GetSelectionPositionX_Raw() const = 0;
+ virtual float GetSelectionPositionY_Raw() const = 0;
+
+ // Tell the panel to set focus to the next panel in specified movement/order method
+ virtual bool SetFocusToNextPanel( int nRepeats, EFocusMoveDirection moveType, bool bAllowWrap, float flTabIndexCurrent, float flXPosCurrent, float flYPosCurrent, float flXStart, float flYStart ) = 0;
+ virtual bool SetInputFocusToFirstOrLastChildInFocusOrder( EFocusMoveDirection moveType, float flXStart, float flYStart ) = 0;
+
+ // Is this panel a selection pos repeat boundary?
+ virtual bool BSelectionPosVerticalBoundary() = 0;
+ virtual bool BSelectionPosHorizontalBoundary() = 0;
+
+ // controls if clicking on an unfocused panel should set focus
+ virtual void SetChildFocusOnHover( bool bEnable ) = 0;
+ virtual bool GetChildFocusOnHover() = 0;
+
+ // Panel scrolling
+ virtual void ScrollToTop() = 0;
+ virtual void ScrollToBottom() = 0;
+ virtual void ScrollToLeftEdge() = 0;
+ virtual void ScrollToRightEdge() = 0;
+ virtual void ScrollParentToMakePanelFit( ScrollBehavior_t behavior = SCROLL_BEHAVIOR_DEFAULT, bool bImmediateScroll = false ) = 0;
+ virtual void ScrollToFitRegion( float x0, float x1, float y0, float y1, ScrollBehavior_t behavior = SCROLL_BEHAVIOR_DEFAULT, bool bDirectParentScrollOnly = false, bool bImmediateScroll = false ) = 0;
+ virtual bool BCanSeeInParentScroll() = 0;
+
+ virtual void OnScrollPositionChanged() = 0;
+ virtual void SetSendChildScrolledIntoViewEvents( bool bSendChildReadyEvents ) = 0; // this must be enabled on your parent for ScrolledIntoView events to fire and IsScrolledIntoView state to be set
+ virtual bool OnCheckChildrenScrolledIntoView() = 0;
+ virtual void FireScrolledIntoViewEvent() = 0;
+ virtual void FireScrolledOutOfViewEvent() = 0;
+ virtual bool IsScrolledIntoView() const = 0;
+
+ // Direct child management
+ virtual void SortChildren( int( __cdecl *pfnCompare )(const ClientPanelPtr_t *, const ClientPanelPtr_t *) ) = 0;
+
+ // child management, use with caution! normally always managed internally.
+ virtual void AddChild( IUIPanel *pChild ) = 0;
+
+ // child management, use with caution! normally always managed internally. Returns child index we inserted at.
+ virtual int AddChildSorted( bool( __cdecl *pfnLessFunc )(ClientPanelPtr_t const &p1, ClientPanelPtr_t const &p2), IUIPanel *pChild ) = 0;
+
+ // child management, use with caution! normally always managed internally.
+ virtual void RemoveChild( IUIPanel *pChild ) = 0;
+
+ // Move child after another child
+ virtual void MoveChildAfter( IUIPanel *pChildToMove, IUIPanel *pBefore ) = 0;
+
+ // Move child before another child
+ virtual void MoveChildBefore( IUIPanel *pChildToMove, IUIPanel *pAfter ) = 0;
+
+ virtual void SetMouseCanActivate( EMouseCanActivate eMouseCanActivate, const char *pchOptionalParent = NULL ) = 0;
+ virtual EMouseCanActivate GetMouseCanActivate() = 0;
+ virtual IUIPanel *FindParentForMouseCanActivate() = 0;
+
+ virtual bool BReloadLayout( CPanoramaSymbol symPath ) = 0;
+
+ virtual void ReloadStyleFileTraverse( CPanoramaSymbol symPath ) = 0;
+
+ virtual bool BHasOnActivateEvent() = 0;
+ virtual bool BHasOnMouseActivateEvent() = 0;
+
+ // Called to ask us to setup object template for Javascript, you can implement this in a child class and then call
+ // the base method (so all the normal panel2d stuff gets exposed), plus call the various RegisterJS helpers yourself
+ // to expose additional panel type specific data/methods.
+ virtual void SetupJavascriptObjectTemplate() = 0;
+
+ virtual void SetLayoutFile( CPanoramaSymbol symLayoutFile ) = 0;
+
+ // Low level build matching style list for debugger use
+ virtual bool BBuildMatchingStyleList( CUtlVector< CascadeStyleFileInfo_t > *pvecStyles ) = 0;
+
+ // Getter for panel attributes
+ virtual int GetAttribute( const char *pchAttrName, int nDefaultValue ) = 0;
+
+ // Getter for panel attributes
+ virtual const char *GetAttribute( const char *pchAttrName, const char * pchDefaultValue ) = 0;
+
+ // Getter for panel attributes
+ virtual uint32 GetAttribute( const char *pchAttrName, uint32 unDefaultValue ) = 0;
+
+ // Getter for panel attributes
+ virtual uint64 GetAttribute( const char *pchAttrName, uint64 unDefaultValue ) = 0;
+
+ // Setter for panel attributes
+ virtual void SetAttribute( const char *pchAttrName, int nValue ) = 0;
+
+ // Setter for panel attributes
+ virtual void SetAttribute( const char *pchAttrName, const char * pchValue ) = 0;
+
+ // Setter for panel attributes
+ virtual void SetAttribute( const char *pchAttrName, uint32 unValue ) = 0;
+
+ // Setter for panel attributes
+ virtual void SetAttribute( const char *pchAttrName, uint64 unValue ) = 0;
+
+ // Set animation property on panel
+ virtual void SetAnimation( const char *pchAnimationName, float flDuration, float flDelay, EAnimationTimingFunction eTimingFunc, EAnimationDirection eDirection, float flIterations ) = 0;
+
+ // Force an immediate update of the visibility list on our window for our current visibility
+ virtual void UpdateVisibility( bool bUseDirtyStyles ) = 0;
+
+ // Base class implementation for valid XML properties to be set
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) = 0;
+
+ // Builds a string of properties and values to display in the debugger
+ virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties ) = 0;
+
+ // Populates a vector with all immediate children matching a class
+ virtual void FindChildrenWithClass( const char *pchClass, CUtlVector<IUIPanel *> &vecMatchingChildren ) = 0;
+
+ // Populates a vector with all children matching a class
+ virtual void FindChildrenWithClassTraverse( const char *pchClass, CUtlVector<IUIPanel *> &vecMatchingChildren ) = 0;
+
+ // Play focus change sound accounting for fast scroll volume fade effects, etc
+ virtual void PlayFocusChangeSound( int nRepeats, float flPan ) = 0;
+
+ // Clear all panel events
+ virtual void ClearPanelEvents() = 0;
+
+ // Clear specific panel event
+ virtual void ClearPanelEvents( CPanoramaSymbol symPanelEvent ) = 0;
+
+ // panel events
+ virtual void SetPanelEvent( CPanoramaSymbol symPanelEvent, IUIEvent *pEvent ) = 0;
+ virtual void SetPanelEvent( CPanoramaSymbol symPanelEvent, VecUIEvents_t *pEvents ) = 0;
+
+ // Should analog stick be able to scroll this panel?
+ virtual bool BEnableAnalogStickScrolling() = 0;
+
+ // Set mouse tracking state
+ virtual void SetMouseTracking( bool bState ) = 0;
+
+ // Should only be called in the very limited cases where we are creating scrollbars within a layout pass,
+ // exposed for HTML but should really only be used inside UIPanel normally
+ virtual void SetInScrollbarConstruction( bool bConstructing ) = 0;
+
+ // Get the scrollbar for this panel if it exists
+ virtual IUIScrollBar *GetVerticalScrollBar() = 0;
+ virtual IUIScrollBar *GetHorizontalScrollBar() = 0;
+
+ // Get panel events set on panel
+ virtual VecUIEvents_t * GetPanelEvents( CPanoramaSymbol symEvent ) = 0;
+
+ // Has this panel ever been layed out
+ virtual bool BHasBeenLayedOut() const = 0;
+
+ // Callback that styles have cleaned up some transitions, we should update cached state about what styles are present
+ virtual void OnStyleTransitionsCleanup() = 0;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const char *pchName ) = 0;
+#endif
+};
+
+}
+#endif // IUIPANEL_H
diff --git a/public/panorama/iuipanelclient.h b/public/panorama/iuipanelclient.h
new file mode 100644
index 0000000..168b914
--- /dev/null
+++ b/public/panorama/iuipanelclient.h
@@ -0,0 +1,192 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUIPANELCLIENT_H
+#define IUIPANELCLIENT_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panoramatypes.h"
+#include "panoramasymbol.h"
+#include "input/mousecursors.h"
+#include "input/iuiinput.h"
+
+namespace panorama
+{
+
+class IUIPanelStyle;
+class IUIScrollBar;
+
+//-----------------------------------------------------------------------------
+// Purpose: Struct containing a panel property info parsed from a layout file
+//-----------------------------------------------------------------------------
+struct ParsedPanelProperty_t
+{
+ CPanoramaSymbol m_symName;
+ const char *m_pchValue;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Client side of panel interface, this is what client code implementing controls
+// must provide to the core UI engine in terms of a callback interface
+//-----------------------------------------------------------------------------
+class IUIPanelClient
+{
+public:
+
+ // Access the panorama side UI panel interface for the client panel
+ virtual IUIPanel *UIPanel() const = 0;
+
+ // Callback telling client/control code to delete the client panel object
+ virtual void OnDeletePanel() = 0;
+
+ // Get the panel type of a panel
+ virtual CPanoramaSymbol GetPanelType() const = 0;
+
+ // Paint the panels contents
+ virtual void Paint() = 0;
+
+ // override to change how this panel is measured
+ virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions ) = 0;
+
+ // override to change how the panel lays out it's children (instead of default css positioning/flow-children support)
+ virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight ) = 0;
+
+ // Direct key/input handling... better to use binds and events and to not directly
+ // override these in your panel in nearly all cases.
+ virtual bool OnKeyDown( const KeyData_t &code ) = 0;
+ virtual bool OnKeyUp( const KeyData_t & code ) = 0;
+ virtual bool OnKeyTyped( const KeyData_t &unichar ) = 0;
+ virtual bool OnGamePadDown( const GamePadData_t &code ) = 0;
+ virtual bool OnGamePadUp( const GamePadData_t &code ) = 0;
+ virtual bool OnGamePadAnalog( const GamePadData_t &code ) = 0;
+ virtual bool OnMouseButtonDown( const MouseData_t &code ) = 0;
+ virtual bool OnMouseButtonUp( const MouseData_t &code ) = 0;
+ virtual bool OnMouseButtonDoubleClick( const MouseData_t &code ) = 0;
+ virtual bool OnMouseButtonTripleClick( const MouseData_t &code ) = 0;
+ virtual bool OnMouseWheel( const MouseData_t &code ) = 0;
+ virtual void OnMouseMove( float flMouseX, float flMouseY ) = 0;
+ virtual bool OnClick( IUIPanel *pPanel, const MouseData_t &code ) = 0;
+
+ // Override to make a panel allow new panel event symbols in XML
+ virtual bool BIsClientPanelEvent( CPanoramaSymbol symProperty ) = 0;
+
+ // Override to handle new properties from xml on your panel
+ virtual bool BSetProperties( const CUtlVector< ParsedPanelProperty_t > &vecProperties ) = 0;
+
+ // Override to handle new properties from xml on your panel
+ virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) = 0;
+
+ // Should the panel event be applied only after all children are created as well?
+ virtual bool BIsDelayedProperty( CPanoramaSymbol symProperty ) = 0;
+
+ // Callback before children of this panel change
+ virtual void OnBeforeChildrenChanged() = 0;
+
+ // Callback for when a child of this panel is removed
+ virtual void OnRemoveChild( IUIPanel *pChild ) = 0;
+
+ // Callback after children of this panel change
+ virtual void OnAfterChildrenChanged() = 0;
+
+ // Callback on panel getting initialized from layout file
+ virtual void OnInitializedFromLayout() = 0;
+
+ // Callback when styles are changing for this panel
+ virtual void OnStylesChanged() = 0;
+
+ // Callback when styles are changing for an immediate child of this panel
+ virtual void OnChildStylesChanged() = 0;
+
+ // Callback when visibility of the panel is changing
+ virtual void OnVisibilityChanged() = 0;
+
+ // Callback which allows panels to override focus movement behavior, this is called before the base
+ // framework behavior is executed and returning true will prevent the base behavior from occuring.
+ virtual bool OnSetFocusToNextPanel( int nRepeats, panorama::EFocusMoveDirection moveType, bool bAllowWrap, float flTabIndexCurrent, float flXPosCurrent, float flYPosCurrent, float flXStart, float fYStart ) = 0;
+
+ // Allows overriding the parent who will be considered by the localization system for dialog variables,
+ // dropdowns do this to allow the dropdown to have dialog vars set that then impact the created popup menu for
+ // the actual list... You should almost never need this... try to avoid!
+ virtual IUIPanel *GetLocalizationParent() const = 0;
+
+ // Allows panels that know they may draw outside their bounds to tell us to create a clip layer,
+ // we don't always do this since it can be expensive
+ virtual bool BRequiresContentClipLayer() = 0;
+
+ // Callback you must first register for with UIEngine()->CallBeforeStyleAndLayout() if you need it
+ virtual void OnCallBeforeStyleAndLayout() = 0;
+
+ // bugbug jmccaskey - DELETE ME
+ // Callback when a panel event gets set, DO NOT USE, DELETE THIS AS SOON AS WE CAN, ITS HARMFUL
+ virtual void OnPanelEventSet( CPanoramaSymbol symEvent ) = 0;
+
+ // Override to set appropriate mouse cursor when hovering over this panel
+ virtual EMouseCursors GetMouseCursor() = 0;
+
+ // Callback when UI scale factor changes, which may affect panel contents sizing/layout
+ virtual void OnUIScaleFactorChanged( float flScaleFactor ) = 0;
+
+ // Called to ask us to setup object template for Javascript, you can implement this in a child class and then call
+ // the base method (so all the normal panel2d stuff gets exposed), plus call the various RegisterJS helpers yourself
+ // to expose additional panel type specific data/methods.
+ virtual void SetupJavascriptObjectTemplate() = 0;
+
+ // Callback to client panel to create a scrollbar
+ virtual IUIScrollBar *CreateNewVerticalScrollBar( float flInitialScrollPos ) = 0;
+
+ // Callback to client panel to create a scrollbar
+ virtual IUIScrollBar *CreateNewHorizontalScrollBar( float flInitialScrollPos ) = 0;
+
+ // Callback to hide tooltip if it's visible
+ virtual void HideTooltip() = 0;
+
+ // Override getting default input focus
+ virtual IUIPanel *OnGetDefaultInputFocus() = 0;
+
+ virtual void GetPositionWithinAncestor( CPanel2D *pAncestor, float *pflX, float *pflY ) = 0;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) = 0;
+#endif
+};
+
+class IUIScrollBar
+{
+public:
+
+ virtual IUIPanel* UIPanel() = 0;
+ virtual IUIPanelClient* ClientPtr() = 0;
+
+ virtual void Normalize( bool bImmediateThumbUpdate = false ) = 0;
+
+ virtual void SetRangeMinMax( float flRangeMin, float flRangeMax ) = 0;
+
+ virtual float GetRangeSize() const = 0;
+ virtual float GetRangeMin() const = 0;
+ virtual float GetRangeMax() const = 0;
+
+ // Set the window size
+ virtual void SetScrollWindowSize( float flWindowSize ) = 0;
+
+ // Get scroll window size
+ virtual float GetScrollWindowSize() = 0;
+
+ // Set the current window position
+ virtual void SetScrollWindowPosition( float flWindowPos, bool bImmediateMove = false ) = 0;
+
+ virtual float GetLastScrollTime() = 0;
+
+ // Get scroll window position
+ virtual float GetScrollWindowPosition() = 0;
+
+ // Return true if the user is manually dragging the scrollbar with the mouse
+ virtual bool BLastMoveImmediate() = 0;
+};
+
+}
+#endif // IUIPANELCLIENT_H
diff --git a/public/panorama/iuipanelstyle.h b/public/panorama/iuipanelstyle.h
new file mode 100644
index 0000000..2063fc8
--- /dev/null
+++ b/public/panorama/iuipanelstyle.h
@@ -0,0 +1,242 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUIPANELSTYLE_H
+#define IUIPANELSTYLE_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panoramatypes.h"
+#include "panorama/layout/uilength.h"
+#include "mathlib/beziercurve.h"
+#include "layout/stylesymbol.h"
+#include "layout/backgroundimage.h"
+#include "transformations.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Individual transition property data
+//-----------------------------------------------------------------------------
+struct TransitionProperty_t
+{
+ panorama::CStyleSymbol m_symProperty;
+
+ double m_flTransitionSeconds;
+ double m_flTransitionDelaySeconds;
+ EAnimationTimingFunction m_eTimingFunction;
+ CCubicBezierCurve< Vector2D > m_CubicBezier;
+
+ bool operator==(const TransitionProperty_t &rhs) const
+ {
+ return (m_symProperty == rhs.m_symProperty && m_flTransitionSeconds == rhs.m_flTransitionSeconds &&
+ m_flTransitionDelaySeconds == rhs.m_flTransitionDelaySeconds && m_eTimingFunction == rhs.m_eTimingFunction
+ && (m_eTimingFunction != k_EAnimationCustomBezier ||
+ (m_CubicBezier.ControlPoint( 0 ) == rhs.m_CubicBezier.ControlPoint( 0 ) &&
+ m_CubicBezier.ControlPoint( 1 ) == rhs.m_CubicBezier.ControlPoint( 1 ) &&
+ m_CubicBezier.ControlPoint( 2 ) == rhs.m_CubicBezier.ControlPoint( 2 ) &&
+ m_CubicBezier.ControlPoint( 3 ) == rhs.m_CubicBezier.ControlPoint( 3 )
+ )
+ ));
+ }
+
+ bool operator!=(const TransitionProperty_t &rhs) const { return !(*this == rhs); }
+};
+
+struct StyleEntry_t
+{
+ CStyleSymbol m_StyleSymbol;
+ CStyleProperty *m_pStyleProperty;
+};
+
+struct PropertyInTransition_t;
+class CActiveAnimation;
+
+//-----------------------------------------------------------------------------
+// Purpose: Basic panel interface exposing operations used inside of panorama, rather
+// than operations that are part of building/laying out controls in the panorama_client module
+//-----------------------------------------------------------------------------
+class IUIPanelStyle
+{
+public:
+
+ // Clear the styles
+ virtual void Clear() = 0;
+
+ // Get the UI scale factor, this is a property of windows, but since we can have a panel
+ // style with no explicit panel/window (text ranges) we have to set it into this class as well.
+ virtual float GetUIScaleFactor() = 0;
+
+ // Checks if the property has any style data at all, base, transition, or animation.
+ // Useful to early out any work related to the stype when painting.
+ virtual bool BHasAnyStyleDataForProperty( CStyleSymbol hSymbolProperty ) = 0;
+
+ virtual void GetPosition( panorama::CUILength &x, panorama::CUILength &y, panorama::CUILength &z, bool bIncludeUIScaleFactor = true ) = 0;
+ virtual void GetInterpolatedPosition( panorama::CUILength &x, panorama::CUILength &y, panorama::CUILength &z, bool bFinal, bool bIncludeUIScaleFactor = true ) = 0;
+ virtual void SetPosition( panorama::CUILength x, panorama::CUILength y, panorama::CUILength z, bool bPreScaledByUIScaleFactor = false ) = 0;
+ virtual void SetPositionWithoutTransition( panorama::CUILength x, panorama::CUILength y, panorama::CUILength z, bool bPreScaledByUIScaleFactor = false ) = 0;
+
+ virtual void GetPerspectiveOrigin( panorama::CUILength &x, panorama::CUILength &y, bool &bInvert ) = 0;
+ virtual void SetPerspectiveOrigin( panorama::CUILength &x, panorama::CUILength &y, bool &bInvert ) = 0;
+
+ virtual void GetTransformOrigin( panorama::CUILength &x, panorama::CUILength &y, bool &bParentLayerRelative ) = 0;
+ virtual void SetTransformOrigin( panorama::CUILength &x, panorama::CUILength &y, bool bParentLayerRelative ) = 0;
+
+ virtual void GetPerspective( float &perspective ) = 0;
+ virtual void SetPerspective( float perspective ) = 0;
+
+ virtual void GetZIndex( float &zindex ) = 0;
+ virtual void SetZIndex( float zIndex ) = 0;
+
+ virtual void GetOverflow( panorama::EOverflowValue &eHorizontal, panorama::EOverflowValue &eVertical ) = 0;
+ virtual void SetOverflow( const panorama::EOverflowValue eHorizontal, const panorama::EOverflowValue eVertical ) = 0;
+
+ virtual void SetTransform3D( const CUtlVector<CTransform3D *> &vecTransforms ) = 0;
+ virtual void SetTransform3DWithoutTransition( const CUtlVector<CTransform3D *> &vecTransforms ) = 0;
+ virtual VMatrix GetTransform3DMatrix() = 0;
+
+ virtual void GetOpacity( float &opacity ) = 0;
+ virtual void SetOpacity( float opacity ) = 0;
+
+ virtual void SetScale2DCentered( float flX, float flY ) = 0;
+
+ virtual void SetRotate2DCentered( float flDegrees ) = 0;
+
+ virtual void GetDesaturation( float &desaturation ) = 0;
+ virtual void SetDesaturation( float desaturation ) = 0;
+
+ virtual void GetGaussianBlur( float &passes, float &stddevhor, float &stddevver ) = 0;
+ virtual void SetGaussianBlur( float passes, float stddevhor, float stddevver ) = 0;
+
+ virtual void GetOpacityMaskImage( IImageSource *& pImage, float *pflOpacityMaskOpacity ) = 0;
+
+ virtual void GetWashColor( Color &c ) = 0;
+ virtual void SetWashColor( const Color &c ) = 0;
+
+ virtual EMixBlendMode GetMixBlendMode() = 0;
+
+ virtual ETextureSampleMode GetTexturesSampleMode() = 0;
+
+ virtual void SetBackgroundColor( const char *pchColor ) = 0;
+ virtual void SetSimpleBackgroundColor( const Color &c ) = 0;
+ virtual bool GetSimpleBackgroundColor( Color &c ) = 0;
+
+ virtual void SetForegroundColor( const char *pchColor ) = 0;
+ virtual void SetSimpleForegroundColor( const Color &c ) = 0;
+ virtual bool GetSimpleForegroundColor( Color &c ) = 0;
+
+ virtual void SetFontStyle( const char *pchFontFamily, float flSize, EFontStyle style, EFontWeight weight ) = 0;
+ virtual void GetFontStyle( const char **pchFontFamily, float &flSize, EFontStyle &style, EFontWeight &weight ) = 0;
+ virtual void GetFontStyleNoDefaults( const char **pchFontFamily, float &flSize, EFontStyle &style, EFontWeight &weight ) = 0;
+ virtual void GetForegroundFillBrushCollectionMsg( CMsgFillBrushCollection &msg, float flRenderWidth, float flRenderHeight ) = 0;
+ virtual void GetLineHeight( float &flLineHeight ) = 0;
+ virtual void GetTextAlign( ETextAlign &align ) = 0;
+ virtual void GetTextDecoration( ETextDecoration &decoration ) = 0;
+ virtual void GetTextTransform( ETextTransform &transform ) = 0;
+ virtual void GetTextLetterSpacing( int &spacing ) = 0;
+
+ virtual bool BHasPossibleBackgroundColor() = 0;
+
+ virtual void GetWidth( panorama::CUILength &width ) = 0;
+ virtual void SetWidth( panorama::CUILength width ) = 0;
+ virtual void GetHeight( panorama::CUILength &height ) = 0;
+ virtual void SetHeight( panorama::CUILength height ) = 0;
+ virtual void GetMinWidth( panorama::CUILength &minWidth ) = 0;
+ virtual void GetMinHeight( panorama::CUILength &minHeight ) = 0;
+ virtual void GetMaxWidth( panorama::CUILength &maxWidth ) = 0;
+ virtual void GetMaxHeight( panorama::CUILength &maxHeight ) = 0;
+ virtual void GetInterpolatedWidth( panorama::CUILength &width, bool bFinal ) = 0;
+ virtual void GetInterpolatedHeight( panorama::CUILength &height, bool bFinal ) = 0;
+ virtual void GetInterpolatedMaxWidth( panorama::CUILength &width, bool bFinal ) = 0;
+ virtual void GetInterpolatedMaxHeight( panorama::CUILength &height, bool bFinal ) = 0;
+
+ virtual void GetVisibility( bool &bVisible ) = 0;
+ virtual void SetVisibility( bool bVisible ) = 0;
+
+ virtual void GetFlowChildren( panorama::EFlowDirection &eFlowDirection ) = 0;
+ virtual void SetFlowChildren( panorama::EFlowDirection eFlowDirection ) = 0;
+
+ virtual void GetInterpolatedBorderWidth( panorama::CUILength &left, panorama::CUILength &top, panorama::CUILength &right, panorama::CUILength &bottom, bool bFinal ) = 0;
+
+ virtual void GetWhitespaceWrap( bool &bWrap ) = 0;
+ virtual void GetTextOverflow( bool &bEllipsis ) = 0;
+
+ // Content inset is padding+border-width
+ virtual void GetContentInset( float flBoxWidth, float flBoxHeight, bool bFinalDimensions, float &left, float &top, float &right, float &bottom ) = 0;
+
+ // You shouldn't need this outside layout code normally you want GetContentInset instead!
+ virtual void GetPadding( panorama::CUILength &left, panorama::CUILength &top, panorama::CUILength &right, panorama::CUILength &bottom ) = 0;
+
+ virtual void GetMargin( panorama::CUILength &left, panorama::CUILength &top, panorama::CUILength &right, panorama::CUILength &bottom ) = 0;
+ virtual void GetMargin( float flBoxWidth, float flBoxHeight, float &left, float &top, float &right, float &bottom ) = 0;
+ virtual void SetMargin( panorama::CUILength &left, panorama::CUILength &top, panorama::CUILength &right, panorama::CUILength &bottom ) = 0;
+
+ virtual CUtlVector< CBackgroundImageLayer * > *GetBackgroundImages() = 0;
+ virtual void SetBackgroundImages( const CUtlVector< CBackgroundImageLayer * > &vecLayers ) = 0;
+
+ virtual void GetAlignment( EHorizontalAlignment &eHorizontalAlignment, EVerticalAlignment &eVerticalAlignment ) = 0;
+
+ virtual void SetTooltipPositions( const EContextUIPosition( &eTooltipPositions )[ 4 ] ) = 0;
+ virtual void GetTooltipPositions( EContextUIPosition( &eTooltipPositions )[ 4 ] ) = 0;
+ virtual void SetTooltipBodyPosition( const panorama::CUILength &horizontalPosition, const panorama::CUILength &verticalPosition ) = 0;
+ virtual void GetTooltipBodyPosition( panorama::CUILength &horizontalPosition, panorama::CUILength &verticalPosition ) = 0;
+ virtual void SetTooltipArrowPosition( const panorama::CUILength &horizontalPosition, const panorama::CUILength &verticalPosition ) = 0;
+ virtual void GetTooltipArrowPosition( panorama::CUILength &horizontalPosition, panorama::CUILength &verticalPosition ) = 0;
+
+ virtual void SetContextMenuPositions( const EContextUIPosition( &eContextMenuPositions )[ 4 ] ) = 0;
+ virtual void GetContextMenuPositions( EContextUIPosition( &eContextMenuPositions )[ 4 ] ) = 0;
+ virtual void SetContextMenuBodyPosition( const panorama::CUILength &horizontalPosition, const panorama::CUILength &verticalPosition ) = 0;
+ virtual void GetContextMenuBodyPosition( panorama::CUILength &horizontalPosition, panorama::CUILength &verticalPosition ) = 0;
+ virtual void SetContextMenuArrowPosition( const panorama::CUILength &horizontalPosition, const panorama::CUILength &verticalPosition ) = 0;
+ virtual void GetContextMenuArrowPosition( panorama::CUILength &horizontalPosition, panorama::CUILength &verticalPosition ) = 0;
+
+ virtual void GetAnimationNames( CUtlVector< CPanoramaSymbol > *pvecAnimations ) = 0;
+ virtual void ResetAnimations() = 0;
+
+ // Get actual parent sizes, which we need to convert some % units to px
+ virtual float GetParentActualRenderWidth() = 0;
+ virtual float GetParentActualRenderHeight() = 0;
+
+ // Checks if the property has any data for transition
+ virtual bool BHasAnyTransition() = 0;
+
+ // Checks if this panel has any active transitions or animations
+ virtual bool BHasAnyTransitionOrAnimation( bool bExcludeStylesImpactingOnlyCompositing ) = 0;
+
+ virtual bool BHasAnimatingBackground() = 0;
+
+ // Checks if the panel is completely transparent, and has no current animation/transition of opacity.
+ // If this is true it means we don't need to draw the panel.
+ virtual bool BIsTransparentWithNoOpacityTransition() = 0;
+
+ // Set a new UI scale factor from the one we constructed with
+ virtual void SetUIScaleFactor( float flScaleFactor ) = 0;
+
+ // Set transition properties
+ virtual void SetTransitionProperties( const CUtlVector< TransitionProperty_t > &vecTransitionProperties ) = 0;
+
+ // Get animation control curve points
+ virtual void GetAnimationCurveControlPoints( EAnimationTimingFunction eTransitionEffect, Vector2D vecPoints[4] ) = 0;
+
+ // Low level search for property info for debugger use
+ virtual void FindPropertyInfo( CStyleSymbol hSymbol, CStyleProperty **ppProperty, PropertyInTransition_t **ppTransitionData, CUtlVector< CActiveAnimation * > *pvecAnimations ) = 0;
+
+ virtual const CUtlVector<StyleEntry_t> &PropertiesSetFromElement() const = 0;
+ virtual const CStyleProperty *GetPropertyNoInherit( CStyleSymbol symProperty ) = 0;
+
+ // properties set on element style (set from code)
+ virtual bool BPropertySetFromElement( CStyleSymbol symProperty ) const = 0;
+ virtual void ClearPropertySetFromElement( CStyleSymbol symProperty ) = 0;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName ) = 0;
+#endif
+};
+
+}
+#endif // IUIPANELSTYLE_H
diff --git a/public/panorama/iuirenderengine.h b/public/panorama/iuirenderengine.h
new file mode 100644
index 0000000..741a900
--- /dev/null
+++ b/public/panorama/iuirenderengine.h
@@ -0,0 +1,165 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUIRENDERENGINE_H
+#define IUIRENDERENGINE_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panoramatypes.h"
+#include "tier1/refcount.h"
+#if defined( SOURCE2_PANORAMA )
+class IRenderContext;
+#include "rendermessages.pb.h"
+class IRenderContext;
+#else
+#include "../../panorama/renderer/rendermessages.pb.h"
+#endif
+
+class CMsgFillBrushCollection;
+
+namespace panorama
+{
+
+enum E2DTextureFormat
+{
+ k_EFormatRGBA8,
+ k_EFormatBGRA8,
+ k_EFormatBGR8, // 8 bits per channel, last 8 bits in the dword are ignored
+ k_EFormatA8,
+ k_EFormatYUV420,
+ k_EFormatR16G16B16A16,
+ k_EFormatDXT1,
+ k_EFormatDXT5,
+};
+
+
+enum EAlphaChannelType
+{
+ k_EAlphaChannelType_None,
+ k_EAlphaChannelType_Normal,
+ k_EAlphaChannelType_PreMultiplied,
+};
+
+
+//
+// Class to represent all textures
+//
+class IUITexture
+{
+public:
+
+ virtual ~IUITexture() { }
+
+ virtual uint32 GetTextureID() = 0;
+ virtual uint32 GetOriginalWidth() { return GetTextureWidth(); }
+ virtual uint32 GetOriginalHeight() { return GetTextureHeight(); }
+ virtual uint32 GetTextureWidth() = 0;
+ virtual uint32 GetTextureHeight() = 0;
+ virtual uint32 GetStride() = 0;
+ virtual E2DTextureFormat GetFormat() = 0;
+ virtual EAlphaChannelType GetAlphaChannelType() = 0;
+ virtual bool BIsReady() = 0;
+};
+
+
+//
+// Class to handle double buffered textures of various standard formats (RGBA8, BGRA8, alpha-premulitplied/or-not, etc)
+//
+class IUIDoubleBufferedTexture : public IUITexture
+{
+public:
+ virtual ~IUIDoubleBufferedTexture() {}
+
+ // Update the data for rendering next frame
+ virtual int32 UpdateTextureData( void *pTextureData ) = 0;
+};
+
+
+//
+// YUV420 textures are special, because they need 3 textures one for Y, U, and V, and then
+// they need special rendering rules in a pixel shader to scale/color convert.
+//
+class IUIDoubleBufferedYUV420Texture : public IUITexture
+{
+public:
+ virtual ~IUIDoubleBufferedYUV420Texture() {}
+
+ // Update the YUV420 data for rendering next frame
+ virtual bool BUpdateTextureData( void *pYBuffer, void *pUBuffer, void *pVBuffer, uint unStrideY, uint unStrideU, uint unStrideV ) = 0;
+};
+
+//
+// Render thread callback object interface
+//
+#if defined( SOURCE2_PANORAMA )
+class CRenderThreadCallback : public CRefCount
+{
+public:
+
+ // Callback function to override and perform direct rendering within
+ virtual void RenderThreadCallback(ISceneView *pSceneView, IRenderContext **pRenderContext, ISceneLayer *pSceneLayer, float x0, float y0, float x1, float y1) = 0;
+
+};
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose: Interface to do drawing onto windows. This is the full publically exposed
+// drawing interface that new panel types can use for drawing, the implementation has
+// more stuff available inside the framework.
+//-----------------------------------------------------------------------------
+class IUIRenderEngine
+{
+public:
+
+ // Draw a filled quad
+ virtual void DrawFilledRect( float x0, float y0, float x1, float y1, const CMsgFillBrushCollection &c, EAntialiasing antialiasing = k_EAntialisingEnabled ) = 0;
+
+ // Draw a textured quad
+ virtual void DrawTexturedRect( uint32 unTextureID, ETextureSampleMode eSampleMode, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1 ) = 0;
+
+ // Draw text (utf-8 input)
+ virtual void DrawTextRegion( const char *pchText, const char *pchFontName, const CMsgFillBrushCollection &c, float flSize, float flLineHeight, EFontWeight weight, EFontStyle style, ETextAlign align, ETextDecoration decoration, bool bWrap, bool bEllipsis, int nLetterSpacing, float x0, float y0, float x1, float y1, ::google::protobuf::RepeatedPtrField< ::CMsgTextRangeFormat > *pmsgRangeFormats ) = 0;
+
+ // Draw text (wchar input)
+ virtual void DrawTextRegion( const wchar_t *pchText, const char *pchFontName, const CMsgFillBrushCollection &c, float flSize, float flLineHeight, EFontWeight weight, EFontStyle style, ETextAlign align, ETextDecoration decoration, bool bWrap, bool bEllipsis, int nLetterSpacing, float x0, float y0, float x1, float y1, ::google::protobuf::RepeatedPtrField< ::CMsgTextRangeFormat > *pmsgRangeFormats ) = 0;
+
+ // Draw one of the special syncronized textures
+ virtual void DrawSyncronizedTexturedRect( uint32 unTextureID, ETextureSampleMode eSampleMode, int32 unSerialize, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1 ) = 0;
+
+ // Queue a texture delete, won't actually delete until the layout threads active frame next reaches rendering
+ virtual void QueueDeleteTexture( IUITexture *pTexture ) = 0;
+
+ // Called to create a texture, you call this directly on the main thread and the returned texture interface is thread safe,
+ // so you can access its id/size and delete it from the main thread as well. Drawing calls are not synchronized with texture creation,
+ // but the contract is you must create the texture before attempting to draw for it's id.
+ virtual bool BCreateTexture( IUITexture **pTextureOutput, void *pubTextureData, uint32 unWidth, uint32 unHeight, uint32 unStride, E2DTextureFormat eFormat, EAlphaChannelType eAlphaChannelType ) = 0;
+
+#if defined( SOURCE2_PANORAMA )
+ virtual bool BCreateTexture( IUITexture **pTextureOutput, const char *pResourceFile ) = 0;
+
+ // Tell the render thread to call the panel back on the specified method, which will then be able to do
+ // direct render system calls on the render thread
+ virtual void RequestRenderCallback( CRenderThreadCallback *pCallbackObj, float x0, float y0, float x1, float y1,
+ float flPaddingLeft, float flPaddingRight, float flPaddingTop, float flPaddingBottom, bool bNeedsRedrawEveryFrame ) = 0;
+#endif
+
+ // Called to create a double buffered texture, you call this directly on the main thread
+ // and the returned texture interface is thread safe, so you can update the texture data directly. The textures are
+ // double buffered, so it should be hard to block the render thread, but some locking does occur. Unlike normal texture
+ // drawing your draw calls are not synchronized with texture data updates, so you could end up skipping frames or such.
+ virtual bool BCreateDoubleBufferedTexture( IUIDoubleBufferedTexture **pDoubleBufferedOutput, uint32 unWidth, uint32 unHeight, uint32 unStride, E2DTextureFormat eFormat, EAlphaChannelType eAlphaChannelType, bool bSerializedUploads ) = 0;
+
+ // Called to create a double buffered YUV420 texture (for movie rendering), you call this directly on the main thread
+ // and the returned texture interface is thread safe, so you can update the texture data directly. The textures are
+ // double buffered, so it should be hard to block the render thread, but some locking does occur. Unlike normal texture
+ // drawing your draw calls are not synchronized with texture data updates, so you could end up skipping frames or such.
+ virtual bool BCreateDoubleBufferedYUV420Texture( IUIDoubleBufferedYUV420Texture **pDoubleBufferedYUV420Output, uint32 unWidth, uint32 unHeight ) = 0;
+};
+
+}
+#endif // IUIRENDERENGINE_H
diff --git a/public/panorama/iuisoundsystem.h b/public/panorama/iuisoundsystem.h
new file mode 100644
index 0000000..fbd19d6
--- /dev/null
+++ b/public/panorama/iuisoundsystem.h
@@ -0,0 +1,91 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUISOUNDSYSTEM_H
+#define IUISOUNDSYSTEM_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#if !defined( SOURCE2_PANORAMA )
+#include "audio/iaudiointerface.h"
+#endif
+
+#ifdef SUPPORTS_AUDIO
+class IAudioOutputStream;
+#endif
+
+namespace panorama
+{
+
+typedef void * HAUDIOSAMPLE;
+
+//
+// Interface that handles sound
+//
+class IUISoundSystem
+{
+public:
+ virtual ~IUISoundSystem() {}
+
+ // Play a sound referenced by name.
+ // flVolume should be 0.0 to 1.0, 0.5 would equal -10DB. volume is modulated by the mixer volume for the specified sound type.
+ // flVolumePan sets the position on mono samples, or panning on stereo, 0.0 is full left, 1.0 is full right, 0.5 is no attenuation.
+ // flRepeats sets the number of times to repeat the sound, 0.0f will result in infinite
+ virtual HAUDIOSAMPLE PlaySound( const char *pchSoundName, ESoundType soundType,
+ float flVolume = 1.0f, float flVolumePan = 0.5f, float flRepeats = 1.0f ) = 0;
+
+ // Set the base volume / panning for the sound sample
+ virtual void SetSoundSampleVolumePan( HAUDIOSAMPLE hSample, float flVolume, float flVolumePan ) = 0;
+
+ // Fade out the sound sample and stop it
+ virtual void FadeOutAndStopSoundSample( HAUDIOSAMPLE hSample, float flFadeOutSeconds ) = 0;
+
+ // Set a volume ramp that will change the volume of the sample smoothly, note that this acts as a filter and scales the volume from
+ // the base set when playing or with SetSoundSampleVolumePan, the base is not actually modified and still must be set as audible for
+ // this ramp to have any impact.
+ virtual void VolumeRampSoundSample( HAUDIOSAMPLE hSample, float flVolumeTarget, float flTransitionSeconds ) = 0;
+
+ // retrieves the user-specified sound volume for the specified sound type.
+ //
+ // Normally you don't need to use this as PlaySound auto-applies the right volume;
+ // but it is needed on raw audio streams created with CreateAudioOutputStream.
+ //
+ // The value returned here honors the muted state.
+ virtual float GetSoundVolume( ESoundType soundType ) = 0;
+
+ // here you can set the volume for the specified sound type programmatically
+ virtual void SetSoundVolume( ESoundType soundType, float flVolume ) = 0;
+
+ // and you can set a global mute state
+ virtual void SetSoundMuted( bool bMute ) = 0;
+
+#ifdef SUPPORTS_AUDIO
+ virtual IAudioOutputStream *CreateAudioOutputStream( int nRate, int nChannels, int nBits ) = 0;
+ virtual void FreeAudioOutputStream( IAudioOutputStream *pStream ) = 0;
+#endif
+
+ // Push that the system now requires a larger mix ahead buffer to prevent skipping, "large" is somewhat undefined
+ // at this level, but you are trading off latency on sounds beginning to get a bigger buffer pre-mixed by miles
+ // to avoid skipping/stuttering.
+ virtual void PushAudioBigMixAheadBuffer() = 0;
+
+ // Pop that the system now requires a larger mix ahead buffer to prevent skipping, "large" is somewhat undefined
+ // at this level, but you are trading off latency on sounds beginning to get a bigger buffer pre-mixed by miles
+ // to avoid skipping/stuttering. Popping moves back towards the lower latency setup once nothing needs the no-skipping
+ // larger buffer setup.
+ virtual void PopAudioBigMixAheadBuffer() = 0;
+
+ // Give time to audio service
+ virtual void ServiceAudio() = 0;
+
+ // Consider pausing audio based on the last time audio was started. Used when the app loses focus.
+ virtual void ConsiderPausingAudio() = 0;
+};
+
+} // namespace panorama
+
+#endif // IUISOUNDSYSTEM_H
diff --git a/public/panorama/iuistylefactory.h b/public/panorama/iuistylefactory.h
new file mode 100644
index 0000000..235052e
--- /dev/null
+++ b/public/panorama/iuistylefactory.h
@@ -0,0 +1,52 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUISTYLEFACTORY_H
+#define IUISTYLEFACTORY_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panoramatypes.h"
+#include "layout/stylesymbol.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Public interface for style factory (usuable in client code)
+//-----------------------------------------------------------------------------
+class IUIStyleFactory
+{
+public:
+
+ virtual bool BRegisteredProperty( panorama::CStyleSymbol symName ) = 0;
+ virtual CStyleSymbol GetPropertyNameForAlias( panorama::CStyleSymbol symName ) = 0;
+ virtual CStyleProperty *CreateStyleProperty( panorama::CStyleSymbol symName ) = 0;
+ virtual void FreeStyleProperty( panorama::CStyleProperty *pProperty ) = 0;
+ virtual const CUtlVector< CUtlString > &GetSortedPropertyAndAliasNames() = 0;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Sort comparator
+//-----------------------------------------------------------------------------
+inline int CompareStylePropertyName( const CUtlString *plhs, const CUtlString *prhs )
+{
+ return V_strcmp( plhs->Get(), prhs->Get() );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Less than function
+//-----------------------------------------------------------------------------
+inline bool StylePropertyNameLessThan( const CUtlString &lhs, const CUtlString &rhs, void *pContext )
+{
+ return CompareStylePropertyName( &lhs, &rhs ) < 0;
+}
+
+
+}
+#endif // IUISTYLEFACTORY_H \ No newline at end of file
diff --git a/public/panorama/iuiwindow.h b/public/panorama/iuiwindow.h
new file mode 100644
index 0000000..da80f5b
--- /dev/null
+++ b/public/panorama/iuiwindow.h
@@ -0,0 +1,205 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUIWINDOW_H
+#define IUIWINDOW_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "panoramatypes.h"
+#include "iuirenderengine.h"
+
+#if defined( SOURCE2_PANORAMA )
+#include "rendersystem/irendercontext.h"
+#include "scenesystem/isceneview.h"
+#endif
+
+class CSharedMemStream;
+
+namespace panorama
+{
+
+class CLayoutFile;
+class IUIPanelStyle;
+class IUIOverlayWindow;
+class IUIWindowInput;
+
+//-----------------------------------------------------------------------------
+// Purpose: Basic window interface exposing operations used inside of panorama, rather
+// than operations that are part of building/laying out controls in the panorama_client module
+//-----------------------------------------------------------------------------
+class IUIWindow
+{
+public:
+
+#if defined( SOURCE2_PANORAMA )
+ virtual void RenderWindow( ISceneView *pView, IRenderContext *pRenderContext, ISceneLayer *pLayer ) = 0;
+#endif
+
+ // Delete the window object
+ virtual void Delete() = 0;
+
+ // Access input system for the window
+ virtual IUIWindowInput *UIWindowInput() = 0;
+
+ // Access the rendering interface you use to draw onto this window
+ virtual IUIRenderEngine * UIRenderEngine() = 0;
+
+ // Set scaling factor that applies to all x/y values in the UI for the window, used so we can
+ // author content at say 1080p but pass 0.6666666f for this to render in 720p on cards with poor
+ // fill rates or TVs without 1080p support.
+ virtual void SetUIScaleFactor( float flScaleFactor ) = 0;
+ virtual float GetUIScaleFactor() = 0;
+
+ // Check if the mouse cursor is currently visible within the window
+ virtual bool BCursorVisible() = 0;
+
+ // Get the surface width for the window, this may be larger or smaller than the actual window if we are rendering lower res and scaling output for instance
+ virtual uint32 GetSurfaceWidth() = 0;
+
+ // Get the surface height for the window, this may be larger or smaller than the actual window if we are rendering lower res and scaling output for instance
+ virtual uint32 GetSurfaceHeight() = 0;
+
+ // Get the actual window width
+ virtual uint32 GetWindowWidth() = 0;
+
+ // Get the actual window height
+ virtual uint32 GetWindowHeight() = 0;
+
+ // Get the client area of the window, minus window borders, etc
+ virtual void GetClientDimensions( float &width, float &height ) = 0;
+
+ // Handle resize event, window has resized, backing surface needs to now resize to match
+ virtual void OnWindowResize( uint32 width, uint32 height ) = 0;
+
+ // Set window position on screen
+ virtual void SetWindowPosition( float x, float y ) = 0;
+
+ // Get window position on screen
+ virtual void GetWindowPosition( float &x, float &y ) = 0;
+
+ // bForceful in this call means try to bypass OS rules that may prevent focus (like our app wasn't last to receive input),
+ // use this sparingly and only if we really know stealing focus from some other app is what the user definately desires!
+ virtual void Activate( bool bForceful ) = 0;
+
+ // Check if this window has focus currently
+ virtual bool BHasFocus() = 0;
+
+ // Get the number of visible top level panels in the window
+ virtual uint32 GetNumVisibleTopLevelPanels() const = 0;
+
+ // Access list of visible panels
+ virtual const CUtlLinkedList< IUIPanel* > &GetTopLevelVisiblePanels() const = 0;
+
+ // Check if mouse is over the window
+ virtual bool IsMouseOver() = 0;
+
+ // Helper for letting client code tell us about daisywheel usage
+ virtual void RecordDaisyWheelUsage( float flEntryTimeInSeconds, int nWordsEntered, bool bViaKeyboard, bool bViaGamepad ) = 0;
+
+ // Helper for tracking daisywheel usage
+ virtual void GetDaisyWheelWPM( int &nWordsTyped, float &flMixedWPM, float &flKeyboardOnlyWPM, float &flGamepadOnlyWPM ) = 0;
+
+ // Check if the window is inside it's own layout pass
+ virtual bool BIsWindowInLayoutPass() = 0;
+
+ // Set a context ptr that is attached to the window, just lets other code (panels) that
+ // has access to the window access some shared state across the window.
+ virtual void SetContextPtr( void *pv ) = 0;
+
+ // Get context ptr value for this window,
+ virtual void * GetContextPtr() const = 0;
+
+ virtual bool BIsOverlay() = 0;
+ virtual bool BIsSteamWMOverlay() = 0;
+
+ // Get low level native window handle, used by streaming, should generally not be something you use
+ virtual void* GetNativeWindowHandle() = 0;
+
+ // Add a class to every top level panel in the window
+ virtual void AddClass( const char *pchName ) = 0;
+
+ // Add a class from every top level panel in the window
+ virtual void RemoveClass( const char *pchName ) = 0;
+
+ virtual void SetInhibitInput( bool bInhibitInput ) = 0;
+ virtual void SetPreventForceWindowOnTop( bool bPreventForceTopLevel ) = 0;
+
+ // Fade out the mouse cursor immediately in this window
+ virtual void FadeOutCursorNow() = 0;
+
+ // Check if the cursor is currently fading out
+ virtual bool BCursorFadingOut() = 0;
+
+ // Wakeup and show the mouse cursor immediately
+ virtual void WakeupMouseCursor() = 0;
+
+ // Set a min FPS for the window, this actually just prevents setting the max lower
+ virtual void SetMinFPS( float flMinFPS ) = 0;
+
+ // Stats tracking
+ virtual void GetSessionFPSAverages( float &fpsPaint, float &fpsAnimation, float &fpsRender ) = 0;
+
+ // Stats tracking
+ virtual void GetNumPeriodsBelowMinFPS( int &nSlowPeriods ) = 0;
+
+ // access data about how the gamepad was used
+ virtual bool BWasGamepadConnectedThisSession() = 0;
+ virtual bool BWasGamepadUsedThisSession() = 0;
+
+ virtual bool BWasSteamControllerConnectedThisSession() = 0;
+ virtual bool BWasSteamControllerUsedThisSession() = 0;
+
+ // Access overlay window interface for this window, NULL on non Steam Overlay windows
+ virtual IUIOverlayWindow *GetOverlayInterface() = 0;
+
+ // Change visibility of this window
+ virtual bool BIsVisible() = 0;
+ virtual void SetVisible( bool bVisible ) = 0;
+
+ // Change the focus behavior for controls in this window
+ virtual EWindowFocusBehavior GetFocusBehavior() = 0;
+ virtual void SetFocusBehavior( EWindowFocusBehavior eFocusBehavior ) = 0;
+
+ virtual void OnDeviceLost() = 0;
+ virtual void OnDeviceRestored() = 0;
+ virtual bool BDeviceLost() = 0;
+
+ // Clears the GPU resources associated with the window before the next render frame
+ virtual void ClearGPUResourcesBeforeNextFrame() = 0;
+};
+
+
+//
+// Overlay window interface for Steam overlay specific windows
+//
+class IUIOverlayWindow
+{
+public:
+#if !defined( SOURCE2_PANORAMA )
+ virtual void PushOverlayRenderCmdStream( CSharedMemStream *pRenderStream, unsigned long dwPID, float flOpacity, EOverlayWindowAlignment alignment ) = 0;
+
+ virtual void SetFocus( bool bFocus ) = 0;
+
+ virtual bool SetGameProcessInfo( AppId_t nAppId, bool bCanSharedSurfaces, int32 eTextureFormat ) = 0;
+
+ virtual void SetInputEnabled( bool bEnabled ) = 0;
+
+ virtual void SetGameWindowSize( uint32 nWidth, uint32 nHeight ) = 0;
+
+ virtual void SetFixedSurfaceSize( uint32 unSurfaceWidth, uint32 unSurfaceHeight ) = 0;
+
+ virtual void OnMouseMove( float x, float y ) = 0;
+
+ virtual void OnMouseEnter() = 0;
+
+ virtual void SetLetterboxColor( Color c ) = 0;
+#endif
+};
+}
+#endif // IUIWINDOW_H
diff --git a/public/panorama/layout/backgroundimage.h b/public/panorama/layout/backgroundimage.h
new file mode 100644
index 0000000..6d3ded4
--- /dev/null
+++ b/public/panorama/layout/backgroundimage.h
@@ -0,0 +1,263 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef BACKGROUNDIMAGE_H
+#define BACKGROUNDIMAGE_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "csshelpers.h"
+#include "../data/panoramavideoplayer.h"
+#include "utlstring.h"
+#include "uilength.h"
+
+namespace panorama
+{
+
+class IImageSource;
+class CMovie;
+class CPanel2D;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Background position for background image
+//-----------------------------------------------------------------------------
+class CBackgroundPosition
+{
+public:
+ CBackgroundPosition();
+ ~CBackgroundPosition() {}
+
+
+ EHorizontalAlignment GetHorizontalAlignment() const { return m_eHorizontalAlignment; }
+ CUILength GetHorizontalLength() const { return m_horizontal; }
+ EVerticalAlignment GetVeriticalAlignment() const { return m_eVerticalAlignment; }
+ CUILength GetVerticalLength() const { return m_vertical; }
+
+ bool IsHorizontalSet() const
+ {
+ return ( m_eHorizontalAlignment != k_EHorizontalAlignmentUnset && m_horizontal.IsSet() );
+ }
+
+ bool IsVerticalSet() const
+ {
+ return ( m_eVerticalAlignment != k_EVerticalAlignmentUnset && m_vertical.IsSet() );
+ }
+
+ bool IsSet() const
+ {
+ return ( IsHorizontalSet() && IsVerticalSet() );
+ }
+
+ void Set( EHorizontalAlignment eHorizontal, const CUILength &horizontal, EVerticalAlignment eVertical, const CUILength &vertical );
+ void ResolveDefaultValues();
+ void ToString( CFmtStr1024 *pfmtBuffer );
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ m_horizontal.ScaleLengthValue( flScaleFactor );
+ m_vertical.ScaleLengthValue( flScaleFactor );
+ }
+
+ bool operator==( const CBackgroundPosition &rhs ) const
+ {
+ return ( m_eHorizontalAlignment == rhs.m_eHorizontalAlignment && m_horizontal == rhs.m_horizontal && m_eVerticalAlignment == rhs.m_eVerticalAlignment && m_vertical == rhs.m_vertical );
+ }
+
+ bool operator!=( const CBackgroundPosition &rhs ) const
+ {
+ return !( *this == rhs );
+ }
+
+private:
+ EHorizontalAlignment m_eHorizontalAlignment;
+ CUILength m_horizontal;
+
+ EVerticalAlignment m_eVerticalAlignment;
+ CUILength m_vertical;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Background images have a repeat in the x & y directions
+//-----------------------------------------------------------------------------
+class CBackgroundRepeat
+{
+public:
+ CBackgroundRepeat() { Set( k_EBackgroundRepeatUnset, k_EBackgroundRepeatUnset ); }
+ ~CBackgroundRepeat() {}
+
+ bool IsSet() const { return (m_eHorizontal != k_EBackgroundRepeatUnset && m_eVertical != k_EBackgroundRepeatUnset); }
+ void Set( EBackgroundRepeat eHorizontal, EBackgroundRepeat eVertical )
+ {
+ m_eHorizontal = eHorizontal;
+ m_eVertical = eVertical;
+ }
+
+ void ResolveDefaultValues()
+ {
+ if ( m_eHorizontal == k_EBackgroundRepeatUnset )
+ m_eHorizontal = k_EBackgroundRepeatRepeat;
+
+ if ( m_eVertical == k_EBackgroundRepeatUnset )
+ m_eVertical = k_EBackgroundRepeatRepeat;
+ }
+
+ EBackgroundRepeat GetHorizontal() const { return m_eHorizontal; }
+ EBackgroundRepeat GetVertical() const { return m_eVertical; }
+
+ bool operator==( const CBackgroundRepeat &rhs ) const
+ {
+ return ( m_eHorizontal == rhs.m_eHorizontal && m_eVertical == rhs.m_eVertical );
+ }
+
+ bool operator!=( const CBackgroundRepeat &rhs ) const
+ {
+ return !( *this == rhs );
+ }
+
+private:
+ EBackgroundRepeat m_eHorizontal;
+ EBackgroundRepeat m_eVertical;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Can have multiple background image layers, each contains the following
+//-----------------------------------------------------------------------------
+class CBackgroundImageLayer
+{
+private:
+ enum EImagePath
+ {
+ k_EImagePathUnset,
+ k_EImagePathNone,
+ k_EImagePathSet
+ };
+
+public:
+
+ CBackgroundImageLayer();
+ ~CBackgroundImageLayer();
+
+ void SetPathUnset()
+ {
+ m_eImagePath = k_EImagePathUnset;
+ m_sURLPath.Clear();
+ }
+
+ void SetPathToNone()
+ {
+ m_eImagePath = m_eImagePath;
+ m_sURLPath.Clear();
+ }
+
+ void SetPath( const char *pchPath )
+ {
+ m_eImagePath = k_EImagePathSet;
+ m_sURLPath = pchPath;
+ }
+
+ bool IsPathSet() { return (m_eImagePath != k_EImagePathUnset); }
+ bool IsPathNone() { return (m_eImagePath == k_EImagePathNone); }
+ const char *GetPath() { return m_sURLPath.String(); }
+
+ // from background-position
+ const CBackgroundPosition &GetPosition() { return m_position; }
+ void SetPosition( const CBackgroundPosition &position ) { m_position = position; }
+
+ const CUILength &GetWidth() { return m_width; }
+ const CUILength &GetHeight() { return m_height; }
+ void SetBackgroundSize( const CUILength &width, const CUILength &height )
+ {
+ m_width = width;
+ m_height = height;
+ m_eBackgroundSizeConstant = k_EBackgroundSizeConstantNone;
+ }
+
+ EBackgroundSizeConstant GetBackgroundSizeConstant() { return m_eBackgroundSizeConstant; }
+ void SetBackgroundSize( EBackgroundSizeConstant eConstant )
+ {
+ Assert( eConstant != k_EBackgroundSizeConstantNone );
+ m_eBackgroundSizeConstant = eConstant;
+ m_width.SetLength( k_flFloatAuto );
+ m_height.SetLength( k_flFloatAuto );
+ }
+
+ CBackgroundRepeat GetRepeat() { return m_repeat; }
+ void SetRepeat( const CBackgroundRepeat &repeat ) { m_repeat = repeat; }
+
+ IImageSource *GetImage() { return m_pImage; }
+ CVideoPlayerPtr GetMovie() { return m_pVideoPlayer; }
+
+ bool IsCompletelyUnset()
+ {
+ return (m_eImagePath == k_EImagePathUnset && !m_position.IsSet() && !m_width.IsSet() && !m_height.IsSet() && !m_repeat.IsSet() );
+ }
+
+ bool IsSet()
+ {
+ return (m_eImagePath != k_EImagePathUnset && m_position.IsSet() && m_width.IsSet() && m_height.IsSet() && m_repeat.IsSet() );
+ }
+
+ void ResolveDefaultValues();
+ void ApplyUIScaleFactor( float flScaleFactor );
+ void OnAppliedToPanel( IUIPanel *pPanel );
+ void MergeTo( CBackgroundImageLayer *pTarget );
+ void ToString( CFmtStr1024 *pfmtBuffer );
+
+ // comparison operators
+ bool operator==( const CBackgroundImageLayer &rhs ) const
+ {
+ return ( m_eImagePath == rhs.m_eImagePath && m_sURLPath == rhs.m_sURLPath && m_position == rhs.m_position &&
+ m_width == rhs.m_width&& m_height == rhs.m_height && m_repeat == rhs.m_repeat && m_eBackgroundSizeConstant == rhs.m_eBackgroundSizeConstant );
+ }
+
+ bool operator!=( const CBackgroundImageLayer &rhs ) const
+ {
+ return !( *this == rhs );
+ }
+
+ // helpers for drawing
+ void CalculateFinalDimensions( float *pflWidth, float *pflHeight, float flPanelWidth, float flPanelHeight, float flScaleFactor );
+ void CalculateFinalPosition( float *px, float *py, float flWidthPanel, float flHeightPanel, float flWidthImage, float flHeightImage );
+ void CalculateFinalSpacing( float *px, float *py, float flWidthPanel, float flHeightPanel, float flWidthImage, float flHeightImage );
+
+ void Set( const CBackgroundImageLayer &rhs );
+
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+private:
+ CBackgroundImageLayer( const CBackgroundImageLayer &rhs );
+ CBackgroundImageLayer& operator=( const CBackgroundImageLayer &rhs ) const;
+
+ // from background-image
+ CUtlString m_sURLPath;
+ EImagePath m_eImagePath;
+
+ // from background-position
+ CBackgroundPosition m_position;
+
+ // from background-size
+ EBackgroundSizeConstant m_eBackgroundSizeConstant;
+ CUILength m_width;
+ CUILength m_height;
+
+ // from background-repeat
+ CBackgroundRepeat m_repeat;
+
+ // loaded when applied to a panel
+ IImageSource *m_pImage;
+ CVideoPlayerPtr m_pVideoPlayer;
+};
+
+} // namespace panorama
+
+#endif //BACKGROUNDIMAGE_H
diff --git a/public/panorama/layout/csshelpers.h b/public/panorama/layout/csshelpers.h
new file mode 100644
index 0000000..e18662a
--- /dev/null
+++ b/public/panorama/layout/csshelpers.h
@@ -0,0 +1,195 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef CSSHELPERS_H
+#define CSSHELPERS_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "float.h"
+#include "tier0/dbg.h"
+#include "tier1/utlvector.h"
+#include "mathlib/vmatrix.h"
+#include "mathlib/beziercurve.h"
+#include "uilength.h"
+#include "fillbrush.h"
+#include "fmtstr.h"
+#include "../text/iuitextlayout.h"
+#include "panorama/layout/stylesymbol.h"
+
+class CUtlString;
+class Color;
+class CUtlSymbol;
+
+namespace panorama
+{
+
+class CTransform3D;
+class CBackgroundPosition;
+class CBackgroundRepeat;
+
+const char k_rgchCSSDefaultTerm[] = { ' ', ';', '{', '}', ':' };
+const char k_rgchCSSAtRuleNameTerm[] = { ' ', ';', '{', '}' };
+const char k_rgchCSSSelectorTerm[] = { ';', '{', '}' };
+const char k_rgchCSSValueTerm[] = { ';', '{', '}' };
+const char k_rgchCSSValueTermOrEndOfString[] = { ';', '{', '}', '\0' };
+
+//-----------------------------------------------------------------------------
+// Purpose: defines
+//-----------------------------------------------------------------------------
+const int k_nCSSPropertyNameMax = 128;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: string to type routines
+//-----------------------------------------------------------------------------
+const char* PchNameFromEFontWeight( int nValue );
+const char* PchNameFromEFontStyle( int nValue );
+const char* PchNameFromETextAlign( int nValue );
+const char* PchNameFromETextDecoration( int nValue );
+const char *PchNameFromETextTransform( int nValue );
+const char* PchNameFromEAnimationTimingFunction( int nValue );
+const char *PchNameFromEHorizontalAlignment( EHorizontalAlignment eHorizontalAlignment );
+const char *PchNameFromEVerticalAlignment( EVerticalAlignment eVerticalAlignment );
+const char *PchNameFromEContextUIPosition( EContextUIPosition ePosition );
+const char *PchNameFromEBackgroundRepeat( int nValue );
+
+EFontWeight EFontWeightFromName( const char *pchName );
+EFontStyle EFontStyleFromName( const char *pchName );
+ETextAlign ETextAlignFromName( const char *pchName );
+ETextDecoration ETextDecorationFromName( const char *pchName );
+ETextTransform ETextTransformFromName( const char *pchName );
+EAnimationTimingFunction EAnimationTimingFunctionFromName( const char *pchName );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Common functions for dealing with CSS
+//-----------------------------------------------------------------------------
+namespace CSSHelpers
+{
+ bool BParseFillBrushCollection( CFillBrushCollection *pCollection, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseFillBrush( CFillBrush *pBrush, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseGradientColorStop( CGradientColorStop *pColorStop, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseGaussianBlur( float &flPasses, float &flStdDevHorizontal, float &flStdDevVertical, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseColor( Color *pColor, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseRect( CUILength *pTop, CUILength *pRight, CUILength *pBottom, CUILength *pLeft, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseNamedColor( Color *pColor, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseLength( float *pLength, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseNumber( float *pNumber, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseTime( double *pSeconds, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseIdent( char *rgchIdent, int cubIdent, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseIdentToSymbol( CPanoramaSymbol *pSymbol, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseIdentToStyleSymbol( panorama::CStyleSymbol *pSymbol, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseQuotedString( CUtlString &sOutput, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseURL( CUtlString &sPath, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParsePercent( float *pPercent, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseIntoUILengthForSizing( CUILength *pLength, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseIntoUILength( CUILength *pLength, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseIntoTwoUILengths( CUILength *pLength1, CUILength *pLength2, const char *pchString, const char **pchAfterParse, float flScalingFactor = 1.0f );
+ bool BParseTimingFunction( EAnimationTimingFunction *peTimingFunction, CCubicBezierCurve< Vector2D > *pCubicBezier, const char *pchString, const char **pchAfterParse );
+ bool BParseAnimationDirectionFunction( EAnimationDirection *peAnimationDirection, const char *pchString, const char **pchAfterParse );
+ bool BParseAngle( float *pDegrees, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseTransformFunction( CTransform3D **pTransform, const char *pchString, const char **pchAfterParse = NULL, float flScalingFactor = 1.0f );
+ bool BParseBorderStyle( EBorderStyle *pStyle, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseHorizontalAlignment( EHorizontalAlignment *eHorizontalAlignment, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseVerticalAlignment( EVerticalAlignment *eVerticalAlignment, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseBackgroundPosition( CBackgroundPosition *pPosition, const char *pchString, const char **pchAfterParse = NULL );
+ bool BParseBackgroundRepeat( CBackgroundRepeat *pBackgroundRepeat, const char *pchString, const char **pchAfterParse );
+ bool BParseFunctionName( CPanoramaSymbol &symFunctionNameOut, const char *pchString, const char **pchAfterParse = NULL );
+
+ template <typename T> bool BParseCommaSepList( CUtlVector< T, CUtlMemory<T> > *pvec, bool (*func)( T*, const char *, const char ** ), const char *pchString );
+ bool BParseCommaSepList( CUtlVector< EAnimationTimingFunction > *pvec, CUtlVector< CCubicBezierCurve< Vector2D > > *pvec2, bool (*func)( EAnimationTimingFunction *pvec, CCubicBezierCurve< Vector2D > *pvec2, const char *, const char ** ), const char *pchString );
+ template <typename T> bool BParseCommaSepListWithScaling( CUtlVector< T, CUtlMemory<T> > *pvec, bool (*func)( T*, const char *, const char **, float ), const char *pchString, float flScalingFactor );
+
+
+ const char *SkipSpaces( const char *pchString );
+ bool BSkipComma( const char *pchString, const char **pchAfterParse = NULL );
+ bool BSkipLeftParen( const char *pchString, const char **pchAfterParse = NULL );
+ bool BSkipRightParen( const char *pchString, const char **pchAfterParse = NULL );
+ bool BSkipQuote( const char *pchString, const char **pchAfterParse = NULL );
+ bool BSkipSlash( const char *pchString, const char **pchAfterParse = NULL );
+
+ void AppendUILength( CFmtStr1024 *pfmtBuffer, const CUILength &length );
+ void AppendFloat( CFmtStr1024 *pfmtBuffer, float flValue );
+ void AppendColor( CFmtStr1024 *pfmtBuffer, Color c );
+ void AppendTransform( CFmtStr1024 *pfmtBuffer, CTransform3D *pTransform );
+ void AppendTime( CFmtStr1024 *pfmtBuffer, float flValue );
+ void AppendFillBrushCollection( CFmtStr1024 *pfmtBuffer, const CFillBrushCollection &collection );
+ void AppendFillBrush( CFmtStr1024 *pfmtBuffer, const CFillBrush &brush );
+ void AppendGradientColorStop( CFmtStr1024 *pfmtBuffer, const CGradientColorStop &stops );
+ void AppendURL( CFmtStr1024 *pfmtBuffer, const char *pchURL );
+ void AppendLength( CFmtStr1024 *pfmtBuffer, float flValue );
+
+ bool BParseTrueFalse( const char *pchString, bool *pbValue );
+
+ bool EatCSSComment( CUtlBuffer &buffer );
+ void EatCSSIgnorables( CUtlBuffer &buffer );
+ bool BPeekCSSToken( CUtlBuffer &buffer, char *pchNextChar );
+ bool BReadCSSComment( CUtlBuffer &buffer, char *pchBuffer, uint cubBuffer );
+
+ bool BReadCSSToken( CUtlBuffer &buffer, char *pchToken, uint cubToken );
+ bool BReadCSSToken( CUtlBuffer &buffer, char *pchToken, uint cubToken, const char *pchStopAt, uint cchStopAt );
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper to parse comma separated lists with same value type
+//-----------------------------------------------------------------------------
+template <typename T> bool CSSHelpers::BParseCommaSepList( CUtlVector< T, CUtlMemory<T> > *pvec, bool (*func)( T*, const char *, const char ** ), const char *pchString )
+{
+ while ( *pchString != '\0' )
+ {
+ T val;
+ if ( !func( &val, pchString, &pchString ) )
+ return false;
+
+ pvec->AddToTail( val );
+
+ // done?
+ if ( !CSSHelpers::BSkipComma( pchString, &pchString ) )
+ {
+ // no comma, should be empty string
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if ( pchString[0] != '\0' )
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper to parse comma separated lists with same value type
+//-----------------------------------------------------------------------------
+template <typename T> bool CSSHelpers::BParseCommaSepListWithScaling( CUtlVector< T, CUtlMemory<T> > *pvec, bool (*func)( T*, const char *, const char **, float ), const char *pchString, float flScalingFactor )
+{
+ while ( *pchString != '\0' )
+ {
+ T val;
+ if ( !func( &val, pchString, &pchString, flScalingFactor ) )
+ return false;
+
+ pvec->AddToTail( val );
+
+ // done?
+ if ( !CSSHelpers::BSkipComma( pchString, &pchString ) )
+ {
+ // no comma, should be empty string
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if ( pchString[0] != '\0' )
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace panorama
+
+
+#endif //CSSHELPERS_H
diff --git a/public/panorama/layout/fillbrush.h b/public/panorama/layout/fillbrush.h
new file mode 100644
index 0000000..97d528b
--- /dev/null
+++ b/public/panorama/layout/fillbrush.h
@@ -0,0 +1,993 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose: Classes/types to represent fill brushes of varius types
+//
+//=============================================================================//
+
+#ifndef FILLBRUSH_H
+#define FILLBRUSH_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <float.h>
+#include "color.h"
+#include "utlvector.h"
+#include "uilength.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a gradient color stop value
+//-----------------------------------------------------------------------------
+class CGradientColorStop
+{
+public:
+
+ CGradientColorStop()
+ {
+ m_flPercent = 0.0f;
+ m_color = Color( 0, 0, 0, 0 );
+ }
+
+ CGradientColorStop( float flPercent, Color color )
+ {
+ m_flPercent = clamp( flPercent, 0.0f, 1.0f );
+ m_color = color;
+ }
+
+ void SetPosition( float flPercent )
+ {
+ m_flPercent = clamp( flPercent, 0.0f, 1.0f );
+ }
+
+ void SetColor( Color color )
+ {
+ m_color = color;
+ }
+
+ void SetColor( int r, int g, int b, int a )
+ {
+ m_color.SetColor( r, g, b, a );
+ }
+
+ float GetPosition() const { return m_flPercent; }
+ Color GetColor() const { return m_color; }
+
+ bool operator==( const CGradientColorStop &rhs ) const
+ {
+ return ( m_flPercent == rhs.m_flPercent && m_color == rhs.m_color );
+ }
+
+ bool operator!=( const CGradientColorStop &rhs ) const
+ {
+ return !(*this == rhs);
+ }
+
+private:
+
+ // 0.0->1.0f
+ float m_flPercent;
+
+ // rgba color
+ Color m_color;
+};
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a particle system
+//-----------------------------------------------------------------------------
+class CParticleSystem
+{
+public:
+
+ // Default constructor, sets empty system
+ CParticleSystem()
+ {
+ SetParticleSystem( Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ), 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ),
+ Vector( -9999999.0f, -9999999.0f, -9999999.0f ), Vector( 9999999.0f, 9999999.0f, 9999999.0f ),
+ Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 0.0f ),
+ Color( 0, 0, 0, 0 ), Color( 0, 0, 0, 0 ), Color( 0, 0, 0, 0 ), Color (0, 0, 0, 0 ), 1.0, 0.0f, 0.0f, 0.0f );
+ }
+
+ CParticleSystem( Vector vecBasePositon, Vector vecBasePositionVariance, float flSize, float flSizeVariance, float flParticlesPerSecond, float flParticlesPerSecondVariance,
+ float flLifeSpanSeconds, float flLifeSpanSecondsVariance, Vector vecInitialVelocity, Vector vecInitialVelocityVariance, Vector vecVelocityMin, Vector vecVelocityMax,
+ Vector vecGravityAcceleration, Vector vecGravityAccelerationParticleVariance,
+ Color colorStart, Color colorStartVariance, Color colorEnd, Color colorEndVariance, float flSharpness, float flSharpnessVariance, float flFlicker, float flFlickerVariance )
+ {
+ SetParticleSystem( vecBasePositon, vecBasePositionVariance, flSize, flSizeVariance, flParticlesPerSecond, flParticlesPerSecondVariance,
+ flLifeSpanSeconds, flLifeSpanSecondsVariance, vecInitialVelocity, vecInitialVelocityVariance, vecVelocityMin, vecVelocityMax,
+ vecGravityAcceleration, vecGravityAccelerationParticleVariance,
+ colorStart, colorStartVariance, colorEnd, colorEndVariance, flSharpness, flSharpnessVariance, flFlicker, flFlickerVariance );
+ }
+
+
+ void SetParticleSystem( Vector vecBasePositon, Vector vecBasePositionVariance, float flSize, float flSizeVariance, float flParticlesPerSecond, float flParticlesPerSecondVariance,
+ float flLifeSpanSeconds, float flLifeSpanSecondsVariance, Vector vecInitialVelocity, Vector vecInitialVelocityVariance, Vector vecVelocityMin, Vector vecVelocityMax,
+ Vector vecGravityAcceleration, Vector vecGravityAccelerationParticleVariance, Color colorStart, Color colorStartVariance, Color colorEnd, Color colorEndVariance,
+ float flSharpness, float flSharpnessVariance, float flFlicker, float flFlickerVariance )
+ {
+ m_vecBasePosition = vecBasePositon;
+ m_vecBasePositionVariance = vecBasePositionVariance;
+
+ m_flParticleSize = flSize;
+ m_flParticleSizeVariance = flSizeVariance;
+
+ m_flParticlesPerSecond = flParticlesPerSecond;
+ m_flParticlesPerSecondVariance = flParticlesPerSecondVariance;
+
+ m_flParticleLifeSpanSeconds = flLifeSpanSeconds;
+ m_flParticleLifeSpanSecondsVariance = flLifeSpanSecondsVariance;
+
+ m_vecParticleInitialVelocity = vecInitialVelocity;
+ m_vecParticleInitialVelocityVariance = vecInitialVelocityVariance;
+
+ m_vecVelocityMin = vecVelocityMin;
+ m_vecVelocityMax = vecVelocityMax;
+
+ m_vecGravityAcceleration = vecGravityAcceleration;
+ m_vecGravityAccelerationParticleVariance = vecGravityAccelerationParticleVariance;
+
+ m_colorStartRGBA = colorStart;
+ m_colorStartRGBAVariance = colorStartVariance;
+
+ m_colorEndRGBA = colorEnd;
+ m_colorEndRGBAVariance = colorEndVariance;
+
+ m_flSharpness = flSharpness;
+ m_flSharpnessVariance = flSharpnessVariance;
+
+ m_flFlicker = flFlicker;
+ m_flFlickerVariance = flFlickerVariance;
+ }
+
+
+ bool operator==( const CParticleSystem &rhs ) const
+ {
+ if ( m_vecBasePosition != rhs.m_vecBasePosition )
+ return false;
+
+ if ( m_vecBasePositionVariance != rhs.m_vecBasePositionVariance )
+ return false;
+
+ if ( m_flParticleSize != rhs.m_flParticleSize )
+ return false;
+
+ if ( m_flParticleSizeVariance != rhs.m_flParticleSizeVariance )
+ return false;
+
+ if ( m_flParticlesPerSecond != rhs.m_flParticlesPerSecond )
+ return false;
+
+ if ( m_flParticlesPerSecondVariance != rhs.m_flParticlesPerSecondVariance )
+ return false;
+
+ if ( m_flParticleLifeSpanSeconds != rhs.m_flParticleLifeSpanSeconds )
+ return false;
+
+ if ( m_flParticleLifeSpanSecondsVariance != rhs.m_flParticleLifeSpanSecondsVariance )
+ return false;
+
+ if ( m_vecParticleInitialVelocity != rhs.m_vecParticleInitialVelocity )
+ return false;
+
+ if ( m_vecParticleInitialVelocityVariance != rhs.m_vecParticleInitialVelocityVariance )
+ return false;
+
+ if ( m_vecGravityAcceleration != rhs.m_vecGravityAcceleration )
+ return false;
+
+ if ( m_vecGravityAccelerationParticleVariance != rhs.m_vecGravityAccelerationParticleVariance )
+ return false;
+
+ if ( m_colorStartRGBA != rhs.m_colorStartRGBA )
+ return false;
+
+ if ( m_colorStartRGBAVariance != rhs.m_colorStartRGBAVariance )
+ return false;
+
+ if ( m_colorEndRGBA != rhs.m_colorEndRGBA )
+ return false;
+
+ if ( m_colorEndRGBAVariance != rhs.m_colorEndRGBAVariance )
+ return false;
+
+ if ( m_flSharpness != rhs.m_flSharpness )
+ return false;
+
+ if ( m_flSharpnessVariance != rhs.m_flSharpnessVariance )
+ return false;
+
+ if ( m_flFlicker != rhs.m_flFlicker )
+ return false;
+
+ if ( m_flFlickerVariance != rhs.m_flFlickerVariance )
+ return false;
+
+ if ( m_vecVelocityMin != rhs.m_vecVelocityMin )
+ return false;
+
+ if ( m_vecVelocityMax != rhs.m_vecVelocityMax )
+ return false;
+
+ return true;
+ }
+
+ void Interpolate( float flProgress, CParticleSystem &target )
+ {
+ m_vecBasePosition.x = Lerp( flProgress, m_vecBasePosition.x, target.m_vecBasePosition.x );
+ m_vecBasePosition.y = Lerp( flProgress, m_vecBasePosition.y, target.m_vecBasePosition.y );
+ m_vecBasePosition.z = Lerp( flProgress, m_vecBasePosition.z, target.m_vecBasePosition.z );
+
+ m_vecBasePositionVariance.x = Lerp( flProgress, m_vecBasePositionVariance.x, target.m_vecBasePositionVariance.x );
+ m_vecBasePositionVariance.y = Lerp( flProgress, m_vecBasePositionVariance.y, target.m_vecBasePositionVariance.y );
+ m_vecBasePositionVariance.z = Lerp( flProgress, m_vecBasePositionVariance.z, target.m_vecBasePositionVariance.z );
+
+ m_flParticleSize = Lerp( flProgress, m_flParticleSize, target.m_flParticleSize );
+ m_flParticleSizeVariance = Lerp( flProgress, m_flParticleSizeVariance, target.m_flParticleSizeVariance );
+
+ m_flParticlesPerSecond = Lerp( flProgress, m_flParticlesPerSecond, target.m_flParticlesPerSecond );
+ m_flParticlesPerSecondVariance = Lerp( flProgress, m_flParticlesPerSecondVariance, target.m_flParticlesPerSecondVariance );
+
+ m_vecParticleInitialVelocity.x = Lerp( flProgress, m_vecParticleInitialVelocity.x, target.m_vecParticleInitialVelocity.x );
+ m_vecParticleInitialVelocity.y = Lerp( flProgress, m_vecParticleInitialVelocity.y, target.m_vecParticleInitialVelocity.y );
+ m_vecParticleInitialVelocity.z = Lerp( flProgress, m_vecParticleInitialVelocity.z, target.m_vecParticleInitialVelocity.z );
+
+ m_vecParticleInitialVelocityVariance.x = Lerp( flProgress, m_vecParticleInitialVelocityVariance.x, target.m_vecParticleInitialVelocityVariance.x );
+ m_vecParticleInitialVelocityVariance.y = Lerp( flProgress, m_vecParticleInitialVelocityVariance.y, target.m_vecParticleInitialVelocityVariance.y );
+ m_vecParticleInitialVelocityVariance.z = Lerp( flProgress, m_vecParticleInitialVelocityVariance.z, target.m_vecParticleInitialVelocityVariance.z );
+
+ m_vecVelocityMin.x = Lerp( flProgress, m_vecVelocityMin.x, target.m_vecVelocityMin.x );
+ m_vecVelocityMin.y = Lerp( flProgress, m_vecVelocityMin.y, target.m_vecVelocityMin.y );
+
+ m_vecVelocityMax.x = Lerp( flProgress, m_vecVelocityMax.x, target.m_vecVelocityMax.x );
+ m_vecVelocityMax.y = Lerp( flProgress, m_vecVelocityMax.y, target.m_vecVelocityMax.y );
+
+ m_vecGravityAcceleration.x = Lerp( flProgress, m_vecGravityAcceleration.x, target.m_vecGravityAcceleration.x );
+ m_vecGravityAcceleration.y = Lerp( flProgress, m_vecGravityAcceleration.y, target.m_vecGravityAcceleration.y );
+ m_vecGravityAcceleration.z = Lerp( flProgress, m_vecGravityAcceleration.z, target.m_vecGravityAcceleration.z );
+
+ m_vecGravityAccelerationParticleVariance.x = Lerp( flProgress, m_vecGravityAccelerationParticleVariance.x, target.m_vecGravityAccelerationParticleVariance.x );
+ m_vecGravityAccelerationParticleVariance.y = Lerp( flProgress, m_vecGravityAccelerationParticleVariance.y, target.m_vecGravityAccelerationParticleVariance.y );
+ m_vecGravityAccelerationParticleVariance.z = Lerp( flProgress, m_vecGravityAccelerationParticleVariance.z, target.m_vecGravityAccelerationParticleVariance.z );
+
+ m_colorStartRGBA.SetColor(
+ Lerp( flProgress, m_colorStartRGBA.r(), target.m_colorStartRGBA.r() ),
+ Lerp( flProgress, m_colorStartRGBA.g(), target.m_colorStartRGBA.g() ),
+ Lerp( flProgress, m_colorStartRGBA.b(), target.m_colorStartRGBA.b() ),
+ Lerp( flProgress, m_colorStartRGBA.a(), target.m_colorStartRGBA.a() )
+ );
+
+ m_colorStartRGBAVariance.SetColor(
+ Lerp( flProgress, m_colorStartRGBAVariance.r(), target.m_colorStartRGBAVariance.r() ),
+ Lerp( flProgress, m_colorStartRGBAVariance.g(), target.m_colorStartRGBAVariance.g() ),
+ Lerp( flProgress, m_colorStartRGBAVariance.b(), target.m_colorStartRGBAVariance.b() ),
+ Lerp( flProgress, m_colorStartRGBAVariance.a(), target.m_colorStartRGBAVariance.a() )
+ );
+
+ m_colorEndRGBA.SetColor(
+ Lerp( flProgress, m_colorEndRGBA.r(), target.m_colorEndRGBA.r() ),
+ Lerp( flProgress, m_colorEndRGBA.g(), target.m_colorEndRGBA.g() ),
+ Lerp( flProgress, m_colorEndRGBA.b(), target.m_colorEndRGBA.b() ),
+ Lerp( flProgress, m_colorEndRGBA.a(), target.m_colorEndRGBA.a() )
+ );
+
+ m_colorEndRGBAVariance.SetColor(
+ Lerp( flProgress, m_colorEndRGBAVariance.r(), target.m_colorEndRGBAVariance.r() ),
+ Lerp( flProgress, m_colorEndRGBAVariance.g(), target.m_colorEndRGBAVariance.g() ),
+ Lerp( flProgress, m_colorEndRGBAVariance.b(), target.m_colorEndRGBAVariance.b() ),
+ Lerp( flProgress, m_colorEndRGBAVariance.a(), target.m_colorEndRGBAVariance.a() )
+ );
+
+ m_flSharpness = Lerp( flProgress, m_flSharpness, target.m_flSharpness );
+ m_flSharpnessVariance = Lerp( flProgress, m_flSharpnessVariance, target.m_flSharpnessVariance );
+
+ m_flFlicker = Lerp( flProgress, m_flFlicker, target.m_flFlicker );
+ m_flFlickerVariance = Lerp( flProgress, m_flFlickerVariance, target.m_flFlickerVariance );
+
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ // Scale all X/Y size/position values
+ m_vecBasePosition.x *= flScaleFactor;
+ m_vecBasePosition.y *= flScaleFactor;
+
+ m_vecBasePositionVariance.x *= flScaleFactor;
+ m_vecBasePositionVariance.y *= flScaleFactor;
+
+ m_flParticleSize *= flScaleFactor;
+ m_flParticleSizeVariance *= flScaleFactor;
+
+ m_vecParticleInitialVelocity.x *= flScaleFactor;
+ m_vecParticleInitialVelocity.y *= flScaleFactor;
+
+ m_vecParticleInitialVelocityVariance.x *= flScaleFactor;
+ m_vecParticleInitialVelocityVariance.y *= flScaleFactor;
+
+ m_vecGravityAcceleration.x *= flScaleFactor;
+ m_vecGravityAcceleration.y *= flScaleFactor;
+
+ m_vecGravityAccelerationParticleVariance.x *= flScaleFactor;
+ m_vecGravityAccelerationParticleVariance.y *= flScaleFactor;
+
+ m_vecVelocityMin.x *= flScaleFactor;
+ m_vecVelocityMin.y *= flScaleFactor;
+
+ m_vecVelocityMax.x *= flScaleFactor;
+ m_vecVelocityMax.y *= flScaleFactor;
+ }
+
+ Vector GetBasePosition() const
+ {
+ return m_vecBasePosition;
+ }
+
+ Vector GetBasePositionVariance() const
+ {
+ return m_vecBasePositionVariance;
+ }
+
+ float GetParticleSize() const
+ {
+ return m_flParticleSize;
+ }
+
+ float GetParticleSizeVariance() const
+ {
+ return m_flParticleSizeVariance;
+ }
+
+ float GetParticlesPerSecond() const
+ {
+ return m_flParticlesPerSecond;
+ }
+
+ float GetParticlesPerSecondVariance() const
+ {
+ return m_flParticlesPerSecondVariance;
+ }
+
+ float GetParticleLifeSpanSeconds() const
+ {
+ return m_flParticleLifeSpanSeconds;
+ }
+
+ float GetParticleLifeSpanSecondsVariance() const
+ {
+ return m_flParticleLifeSpanSecondsVariance;
+ }
+
+ Vector GetParticleInitialVelocity() const
+ {
+ return m_vecParticleInitialVelocity;
+ }
+
+ Vector GetParticleInitialVelocityVariance() const
+ {
+ return m_vecParticleInitialVelocityVariance;
+ }
+
+ Vector GetParticleVelocityMin() const
+ {
+ return m_vecVelocityMin;
+ }
+
+ Vector GetParticleVelocityMax() const
+ {
+ return m_vecVelocityMax;
+ }
+
+ Vector GetGravityAcceleration() const
+ {
+ return m_vecGravityAcceleration;
+ }
+
+ Vector GetGravityAccelerationParticleVariance() const
+ {
+ return m_vecGravityAccelerationParticleVariance;
+ }
+
+ Color GetStartColor() const
+ {
+ return m_colorStartRGBA;
+ }
+
+ Color GetStartColorVariance() const
+ {
+ return m_colorStartRGBAVariance;
+ }
+
+ Color GetEndColor() const
+ {
+ return m_colorEndRGBA;
+ }
+
+ Color GetEndColorVariance() const
+ {
+ return m_colorEndRGBAVariance;
+ }
+
+ float GetSharpness() const
+ {
+ return m_flSharpness;
+ }
+
+ float GetSharpnessVariance() const
+ {
+ return m_flSharpnessVariance;
+ }
+
+ float GetFlicker() const
+ {
+ return m_flFlicker;
+ }
+
+ float GetFlickerVariance() const
+ {
+ return m_flFlickerVariance;
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ }
+#endif
+
+private:
+
+ Vector m_vecBasePosition;
+ Vector m_vecBasePositionVariance;
+
+ float m_flParticleSize;
+ float m_flParticleSizeVariance;
+
+ float m_flParticlesPerSecond;
+ float m_flParticlesPerSecondVariance;
+
+ float m_flParticleLifeSpanSeconds;
+ float m_flParticleLifeSpanSecondsVariance;
+
+ Vector m_vecParticleInitialVelocity;
+ Vector m_vecParticleInitialVelocityVariance;
+
+ Vector m_vecVelocityMin;
+ Vector m_vecVelocityMax;
+
+ Vector m_vecGravityAcceleration;
+ Vector m_vecGravityAccelerationParticleVariance;
+
+ Color m_colorStartRGBA;
+ Color m_colorStartRGBAVariance;
+
+ Color m_colorEndRGBA;
+ Color m_colorEndRGBAVariance;
+
+ float m_flSharpness;
+ float m_flSharpnessVariance;
+
+ float m_flFlicker;
+ float m_flFlickerVariance;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a linear gradient
+//-----------------------------------------------------------------------------
+class CLinearGradient
+{
+public:
+ CLinearGradient()
+ {
+ m_StartPoint[0].SetLength( 0.0 );
+ m_StartPoint[1].SetLength( 0.0 );
+ m_EndPoint[0].SetLength( 0.0 );
+ m_EndPoint[1].SetLength( 0.0 );
+ }
+
+ CLinearGradient( CUILength StartX, CUILength StartY, CUILength EndX, CUILength EndY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ SetGradient( StartX, StartY, EndX, EndY, vecStopColors );
+ }
+
+ void SetGradient( CUILength StartX, CUILength StartY, CUILength EndX, CUILength EndY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_StartPoint[0] = StartX;
+ m_StartPoint[1] = StartY;
+ m_EndPoint[0] = EndX;
+ m_EndPoint[1] = EndY;
+
+ m_vecStops.AddMultipleToTail( vecStopColors.Count(), vecStopColors.Base() );
+ }
+
+ void SetControlPoints( CUILength StartX, CUILength StartY, CUILength EndX, CUILength EndY )
+ {
+ m_StartPoint[0] = StartX;
+ m_StartPoint[1] = StartY;
+ m_EndPoint[0] = EndX;
+ m_EndPoint[1] = EndY;
+ }
+
+ void GetStartPoint( CUILength &startX, CUILength &startY ) const
+ {
+ startX = m_StartPoint[0];
+ startY = m_StartPoint[1];
+ }
+
+ void GetEndPoint( CUILength &endX, CUILength &endY ) const
+ {
+ endX = m_EndPoint[0];
+ endY = m_EndPoint[1];
+ }
+
+ const CUtlVector<CGradientColorStop> &AccessStopColors() const
+ {
+ return m_vecStops;
+ }
+
+ CUtlVector<CGradientColorStop> &AccessMutableStopColors()
+ {
+ return m_vecStops;
+ }
+
+ bool operator==( const CLinearGradient &rhs ) const
+ {
+ if ( m_StartPoint[0] != rhs.m_StartPoint[0] || m_StartPoint[1] != rhs.m_StartPoint[1] || m_EndPoint[0] != rhs.m_EndPoint[0] || m_EndPoint[1] != rhs.m_EndPoint[1] )
+ return false;
+
+ if ( m_vecStops.Count() != rhs.m_vecStops.Count() )
+ return false;
+
+ FOR_EACH_VEC( m_vecStops, i )
+ {
+ if ( m_vecStops[i] != rhs.m_vecStops[i] )
+ return false;
+ }
+
+ return true;
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ m_StartPoint[0].ScaleLengthValue( flScaleFactor );
+ m_StartPoint[1].ScaleLengthValue( flScaleFactor );
+ m_EndPoint[0].ScaleLengthValue( flScaleFactor );
+ m_EndPoint[1].ScaleLengthValue( flScaleFactor );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecStops );
+ }
+#endif
+
+private:
+
+ // Start/end point determine angle vector
+ CUILength m_StartPoint[2];
+ CUILength m_EndPoint[2];
+ CCopyableUtlVector<CGradientColorStop> m_vecStops;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a radial gradient
+//-----------------------------------------------------------------------------
+class CRadialGradient
+{
+public:
+ CRadialGradient()
+ {
+ m_Center[0].SetLength( 0.0 );
+ m_Center[1].SetLength( 0.0 );
+ m_Offset[0].SetLength( 0.0 );
+ m_Offset[1].SetLength( 0.0 );
+ m_Radius[0].SetLength( 0.0 );
+ m_Radius[1].SetLength( 0.0 );
+ }
+
+ CRadialGradient( CUILength centerX, CUILength centerY, CUILength offsetX, CUILength offsetY, CUILength radiusX, CUILength radiusY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ SetGradient( centerX, centerY, offsetX, offsetY, radiusX, radiusY, vecStopColors );
+ }
+
+ void SetGradient( CUILength centerX, CUILength centerY, CUILength offsetX, CUILength offsetY, CUILength radiusX, CUILength radiusY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_Center[0] = centerX;
+ m_Center[1] = centerY;
+ m_Offset[0] = offsetX;
+ m_Offset[1] = offsetY;
+ m_Radius[0] = radiusX;
+ m_Radius[1] = radiusY;
+
+ m_vecStops.AddMultipleToTail( vecStopColors.Count(), vecStopColors.Base() );
+ }
+
+ void GetCenterPoint( CUILength &centerX, CUILength &centerY ) const
+ {
+ centerX = m_Center[0];
+ centerY = m_Center[1];
+ }
+
+ void GetOffsetDistance( CUILength &offsetX, CUILength &offsetY ) const
+ {
+ offsetX = m_Offset[0];
+ offsetY = m_Offset[1];
+ }
+
+ void GetRadii( CUILength &radiusX, CUILength &radiusY ) const
+ {
+ radiusX = m_Radius[0];
+ radiusY = m_Radius[1];
+ }
+
+ void SetCenterPoint( const CUILength &x, const CUILength &y )
+ {
+ m_Center[0] = x;
+ m_Center[1] = y;
+ }
+
+ void SetOffsetDistance( const CUILength &x, const CUILength &y )
+ {
+ m_Offset[0] = x;
+ m_Offset[1] = y;
+ }
+
+ void SetRadii( const CUILength &x, const CUILength &y )
+ {
+ m_Radius[0] = x;
+ m_Radius[1] = y;
+ }
+
+ const CUtlVector<CGradientColorStop> &AccessStopColors() const
+ {
+ return m_vecStops;
+ }
+
+ CUtlVector<CGradientColorStop> &AccessMutableStopColors()
+ {
+ return m_vecStops;
+ }
+
+ bool operator==( const CRadialGradient &rhs ) const
+ {
+ if ( m_Center[0] != rhs.m_Center[0] || m_Center[1] != rhs.m_Center[1] ||
+ m_Offset[0] != rhs.m_Offset[0] || m_Offset[1] != rhs.m_Offset[1] ||
+ m_Radius[0] != rhs.m_Radius[0] || m_Radius[1] != rhs.m_Radius[1] )
+ {
+ return false;
+ }
+
+ if ( m_vecStops.Count() != rhs.m_vecStops.Count() )
+ return false;
+
+ FOR_EACH_VEC( m_vecStops, i )
+ {
+ if ( m_vecStops[i] != rhs.m_vecStops[i] )
+ return false;
+ }
+
+ return true;
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ m_Center[0].ScaleLengthValue( flScaleFactor );
+ m_Center[1].ScaleLengthValue( flScaleFactor );
+ m_Offset[0].ScaleLengthValue( flScaleFactor );
+ m_Offset[1].ScaleLengthValue( flScaleFactor );
+ m_Radius[0].ScaleLengthValue( flScaleFactor );
+ m_Radius[1].ScaleLengthValue( flScaleFactor );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecStops );
+ }
+#endif
+
+private:
+
+ // Start/end point determine angle vector
+ CUILength m_Center[2];
+ CUILength m_Offset[2];
+ CUILength m_Radius[2];
+ CCopyableUtlVector<CGradientColorStop> m_vecStops;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a fill color/stroke, may be a gradient
+//-----------------------------------------------------------------------------
+class CFillBrush
+{
+public:
+
+ // Types of strokes we support
+ enum EStrokeType
+ {
+ k_EStrokeTypeFillColor,
+ k_EStrokeTypeLinearGradient,
+ k_EStrokeTypeRadialGradient,
+ k_EStrokeTypeParticleSystem,
+ };
+
+ // Default constructor, sets transparent fill color
+ CFillBrush()
+ {
+ m_eType = k_EStrokeTypeFillColor;
+ m_FillColor.SetColor( 0, 0, 0, 0 );
+ }
+
+ // Constructor for standard color fill
+ CFillBrush( int r, int g, int b, int a )
+ {
+ m_eType = k_EStrokeTypeFillColor;
+ m_FillColor.SetColor( r, g, b, a );
+ }
+
+ // Constructor for linear gradient fill
+ CFillBrush( CUILength StartX, CUILength StartY, CUILength EndX, CUILength EndY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_eType = k_EStrokeTypeLinearGradient;
+ m_LinearGradient.SetGradient( StartX, StartY, EndX, EndY, vecStopColors );
+ }
+
+ // Constructor for radial gradient
+ CFillBrush( CUILength centerX, CUILength centerY, CUILength offsetX, CUILength offsetY, CUILength radiusX, CUILength radiusY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_eType = k_EStrokeTypeRadialGradient;
+ m_RadialGradient.SetGradient( centerX, centerY, offsetX, offsetY, radiusX, radiusY, vecStopColors );
+ }
+
+ // Constructor for particle system
+ CFillBrush( Vector vecBasePositon, Vector vecBasePositionVariance, float flSize, float flSizeVariance, float flParticlesPerSecond, float flParticlesPerSecondVariance,
+ float flLifeSpanSeconds, float flLifeSpanSecondsVariance, Vector vecInitialVelocity, Vector vecInitialVelocityVariance, Vector vecVelocityMin, Vector vecVelocityMax,
+ Vector vecGravityAcceleration, Vector vecGravityAccelerationParticleVariance,
+ Color colorStart, Color colorStartVariance, Color colorEnd, Color colorEndVariance, float flSharpness, float flSharpnessVariance, float flFlicker, float flFlickerVariance )
+ {
+ m_eType = k_EStrokeTypeParticleSystem;
+ m_ParticleSystem.SetParticleSystem( vecBasePositon, vecBasePositionVariance, flSize, flSizeVariance, flParticlesPerSecond, flParticlesPerSecondVariance,
+ flLifeSpanSeconds, flLifeSpanSecondsVariance, vecInitialVelocity, vecInitialVelocityVariance, vecVelocityMin, vecVelocityMax,
+ vecGravityAcceleration, vecGravityAccelerationParticleVariance,
+ colorStart, colorStartVariance, colorEnd, colorEndVariance, flSharpness, flSharpnessVariance, flFlicker, flFlickerVariance );
+ }
+
+ // Get type
+ EStrokeType GetType() const { return m_eType; }
+
+ // Set to a fill color value
+ void SetToFillColor( Color color )
+ {
+ m_eType = k_EStrokeTypeFillColor;
+ m_FillColor = color;
+ }
+
+ // Get fill color for fill stroke types
+ Color GetFillColor() const
+ {
+ Assert( m_eType == k_EStrokeTypeFillColor );
+ return m_FillColor;
+ }
+
+ // Set brush to a linear gradient value
+ void SetToLinearGradient( const CUILength &startX, const CUILength &startY, const CUILength &endX, const CUILength &endY, const CUtlVector<CGradientColorStop> &vecColorStops )
+ {
+ m_eType = k_EStrokeTypeLinearGradient;
+ m_LinearGradient.SetGradient( startX, startY, endX, endY, vecColorStops );
+ }
+
+ // Set to a radial gradient value
+ void SetToRadialGradient( CUILength centerX, CUILength centerY, CUILength offsetX, CUILength offsetY, CUILength radiusX, CUILength radiusY, const CUtlVector<CGradientColorStop> &vecStopColors )
+ {
+ m_eType = k_EStrokeTypeRadialGradient;
+ m_RadialGradient.SetGradient( centerX, centerY, offsetX, offsetY, radiusX, radiusY, vecStopColors );
+ }
+
+ // Set to particle system value
+ void SetToParticleSystem( Vector vecBasePositon, Vector vecBasePositionVariance, float flSize, float flSizeVariance, float flParticlesPerSecond, float flParticlesPerSecondVariance,
+ float flLifeSpanSeconds, float flLifeSpanSecondsVariance, Vector vecInitialVelocity, Vector vecInitialVelocityVariance, Vector vecVelocityMin, Vector vecVelocityMax,
+ Vector vecGravityAcceleration, Vector vecGravityAccelerationParticleVariance,
+ Color colorStart, Color colorStartVariance, Color colorEnd, Color colorEndVariance, float flSharpness, float flSharpnessVariance, float flFlicker, float flFlickerVariance )
+ {
+ m_eType = k_EStrokeTypeParticleSystem;
+ m_ParticleSystem.SetParticleSystem( vecBasePositon, vecBasePositionVariance, flSize, flSizeVariance, flParticlesPerSecond, flParticlesPerSecondVariance,
+ flLifeSpanSeconds, flLifeSpanSecondsVariance, vecInitialVelocity, vecInitialVelocityVariance, vecVelocityMin, vecVelocityMax, vecGravityAcceleration, vecGravityAccelerationParticleVariance,
+ colorStart, colorStartVariance, colorEnd, colorEndVariance, flSharpness, flSharpnessVariance, flFlicker, flFlickerVariance );
+ }
+
+ // Get start/end pos for linear gradient types
+ void GetStartAndEndPoints( CUILength &StartX, CUILength &StartY, CUILength &EndX, CUILength &EndY ) const
+ {
+ Assert( m_eType == k_EStrokeTypeLinearGradient );
+ m_LinearGradient.GetStartPoint( StartX, StartY );
+ m_LinearGradient.GetEndPoint( EndX, EndY );
+ }
+
+ // Access start/end pos for linear or radial gradient types
+ const CUtlVector<CGradientColorStop> &AccessStopColors() const
+ {
+ Assert( m_eType == k_EStrokeTypeLinearGradient || m_eType == k_EStrokeTypeRadialGradient );
+ if ( m_eType == k_EStrokeTypeLinearGradient )
+ return m_LinearGradient.AccessStopColors();
+
+ if ( m_eType == k_EStrokeTypeRadialGradient )
+ return m_RadialGradient.AccessStopColors();
+
+ // Otherwise this is bad, let's just return the hopefully empty linear vector
+ return m_LinearGradient.AccessStopColors();
+ }
+
+ // Get start/end pos for linear gradient types
+ void GetRadialGradientValues( CUILength &centerX, CUILength &centerY, CUILength &offsetX, CUILength &offsetY, CUILength &radiusX, CUILength &radiusY ) const
+ {
+ Assert( m_eType == k_EStrokeTypeRadialGradient );
+ m_RadialGradient.GetCenterPoint( centerX, centerY );
+ m_RadialGradient.GetOffsetDistance( offsetX, offsetY );
+ m_RadialGradient.GetRadii( radiusX, radiusY );
+ }
+
+ CParticleSystem * AccessParticleSystem()
+ {
+ Assert( m_eType == k_EStrokeTypeParticleSystem );
+ return &m_ParticleSystem;
+ }
+
+ bool Interpolate( float flActualWidth, float flActualHeight, CFillBrush &target, float flProgress );
+
+ bool operator==( const CFillBrush &rhs ) const
+ {
+ if ( m_eType != rhs.m_eType )
+ return false;
+
+ switch( m_eType )
+ {
+ case k_EStrokeTypeFillColor:
+ return m_FillColor == rhs.m_FillColor;
+ case k_EStrokeTypeLinearGradient:
+ return m_LinearGradient == rhs.m_LinearGradient;
+ case k_EStrokeTypeRadialGradient:
+ return m_RadialGradient == rhs.m_RadialGradient;
+ case k_EStrokeTypeParticleSystem:
+ return m_ParticleSystem == rhs.m_ParticleSystem;
+ default:
+ AssertMsg( false, "Invalid type on fillbrush" );
+ return false;
+ }
+ }
+
+ bool operator!=( const CFillBrush &rhs ) const
+ {
+ return !( *this == rhs );
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ if ( m_eType == k_EStrokeTypeLinearGradient )
+ m_LinearGradient.ScaleLengthValues( flScaleFactor );
+ else if ( m_eType == k_EStrokeTypeRadialGradient )
+ m_RadialGradient.ScaleLengthValues( flScaleFactor );
+ else if ( m_eType == k_EStrokeTypeParticleSystem )
+ m_ParticleSystem.ScaleLengthValues( flScaleFactor );
+
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_LinearGradient );
+ ValidateObj( m_RadialGradient );
+ ValidateObj( m_ParticleSystem );
+ }
+#endif
+private:
+
+ void ConvertToRadialGradient();
+ void ConvertToLinearGradient();
+ void NormalizeStopCount( CUtlVector<CGradientColorStop> &vec, int nStopsNeeded, Color defaultColor );
+
+ EStrokeType m_eType;
+
+ Color m_FillColor;
+ CLinearGradient m_LinearGradient;
+ CRadialGradient m_RadialGradient;
+ CParticleSystem m_ParticleSystem;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a collection of fill brushes, when filling geometry with
+// such a collection they should be applied in order and blended appropriately.
+//-----------------------------------------------------------------------------
+#define MAX_FILL_BRUSHES_PER_COLLECTION 8
+class CFillBrushCollection
+{
+public:
+
+
+ struct FillBrush_t
+ {
+ CFillBrush m_Brush;
+ float m_Opacity;
+
+ bool operator==( const FillBrush_t &rhs ) const { return (m_Brush == rhs.m_Brush && m_Opacity == rhs.m_Opacity); }
+ bool operator!=( const FillBrush_t &rhs ) const { return !(*this == rhs ); }
+ };
+
+ CFillBrushCollection() { }
+
+ // Get brush count
+ uint32 GetBrushCount() const { return m_vecFillBrushes.Count(); }
+
+ // Access brush vector directly
+ CUtlVectorFixed< FillBrush_t, MAX_FILL_BRUSHES_PER_COLLECTION > &AccessBrushes() { return m_vecFillBrushes; }
+ const CUtlVectorFixed< FillBrush_t, MAX_FILL_BRUSHES_PER_COLLECTION> &AccessBrushes() const { return m_vecFillBrushes; }
+
+ // Add brush to collection
+ void AddFillBrush( const CFillBrush &brush, float opacity = 1.0 )
+ {
+
+ int i = m_vecFillBrushes.AddToTail();
+ m_vecFillBrushes[i].m_Brush = brush;
+ m_vecFillBrushes[i].m_Opacity = opacity;
+ }
+
+ void ScaleLengthValues( float flScaleFactor )
+ {
+ FOR_EACH_VEC( m_vecFillBrushes, i )
+ {
+ m_vecFillBrushes[i].m_Brush.ScaleLengthValues( flScaleFactor );
+ }
+ }
+
+ int GetNumParticleSystems()
+ {
+ int nParticleSystems = 0;
+ FOR_EACH_VEC( m_vecFillBrushes, i )
+ {
+ if ( m_vecFillBrushes[i].m_Brush.GetType() == CFillBrush::k_EStrokeTypeParticleSystem )
+ ++nParticleSystems;
+ }
+
+ return nParticleSystems;
+ }
+
+ void Clear()
+ {
+ m_vecFillBrushes.RemoveAll();
+ }
+
+ // Interpolate between two fill brushes
+ void Interpolate( float flActualWidth, float flActualHeight, const CFillBrushCollection &target, float flProgress );
+ bool operator==( const CFillBrushCollection &rhs ) const;
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecFillBrushes );
+ FOR_EACH_VEC( m_vecFillBrushes, i )
+ {
+ ValidateObj( m_vecFillBrushes[i].m_Brush );
+ }
+ }
+#endif
+
+private:
+
+ CCopyableUtlVectorFixed< FillBrush_t, MAX_FILL_BRUSHES_PER_COLLECTION > m_vecFillBrushes;
+};
+
+} // namespace panorama
+
+#endif // FILLBRUSH_H \ No newline at end of file
diff --git a/public/panorama/layout/panel2dfactory.h b/public/panorama/layout/panel2dfactory.h
new file mode 100644
index 0000000..361004d
--- /dev/null
+++ b/public/panorama/layout/panel2dfactory.h
@@ -0,0 +1,111 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANEL2DFACTORY_H
+#define PANEL2DFACTORY_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "utlsymbol.h"
+#include "tier1/utlrbtree.h"
+#include "panorama/panoramasymbol.h"
+
+
+namespace panorama
+{
+class IUIPanel;
+class IUIPanelClient;
+class IUIEngine;
+class CPanel2DFactory;
+
+#ifdef DBGFLAG_VALIDATE
+void ValidatePanel2DFactory( CValidator &validator );
+#endif
+
+void RegisterPanelFactoriesWithEngine( IUIEngine *pEngine );
+
+//-----------------------------------------------------------------------------
+// Purpose: Used by DECLARE_PANEL2D_FACTORY macro to create a linked list of instancing functions
+//-----------------------------------------------------------------------------
+typedef panorama::IUIPanelClient *(*PANEL2DCREATEFUNC)(const char *pchName, panorama::IUIPanel *parent);
+typedef CPanoramaSymbol( *PANELSYMBOLFUNC )();
+class CPanel2DFactory
+{
+public:
+ CPanel2DFactory( CPanoramaSymbol *pSym, char const *pchLayoutName, PANEL2DCREATEFUNC func, void *pChrisBoydBS, PANELSYMBOLFUNC symParentFunc );
+
+ static bool BRegisteredLocalName( CUtlSymbol symName );
+ CPanoramaSymbol BaseClassSymbol() { return m_funcSymParent(); }
+
+private:
+ friend class CUIEngine;
+ IUIPanelClient *CreatePanelInternal( const char *pchID, panorama::IUIPanel *parent );
+
+ PANELSYMBOLFUNC m_funcSymParent;
+
+ PANEL2DCREATEFUNC m_funcCreate;
+};
+
+
+// This is the macro which implements creation of each type of panel. It creates a function which instances an object of the specified type
+// It them hooks that function up to the helper list so that objects can create the elements by name, with no header file dependency, etc.
+// Params: className = name of class to create
+// layoutName = name used in the layout file
+#define REGISTER_PANEL2D_FACTORY( className, layoutName ) \
+ panorama::CPanoramaSymbol className::m_symbol; \
+ static panorama::IUIPanelClient *Create_##layoutName( const char *pchID, panorama::IUIPanel *parent ) \
+ { \
+ return new className( ToPanel2D(parent), pchID ); \
+ }; \
+ namespace panorama { className *g_##layoutName##LinkerHack = NULL; } \
+ panorama::CPanel2DFactory g_##layoutName##_Helper( &className::m_symbol, #layoutName, Create_##layoutName, panorama::g_##layoutName##LinkerHack, &className::BaseClass::GetPanelSymbol );
+
+// Can be used to register a name so it can be used as a top level panel in XML, but can't be created through a layout file
+#define REGISTER_PANEL2D( className, layoutName ) \
+ panorama::CPanoramaSymbol className::m_symbol; \
+ namespace panorama { className *g_##layoutName##LinkerHack = NULL; } \
+ panorama::CPanel2DFactory g_##layoutName##_Helper( &className::m_symbol, #layoutName, NULL, panorama::g_##layoutName##LinkerHack, &className::BaseClass::GetPanelSymbol );
+
+
+// Can be used to reserve a panel name w/o a panel class
+#define REGISTER_PANEL_NAME( layoutName ) \
+ panorama::CPanoramaSymbol k_symPanel##layoutName; \
+ panorama::CPanoramaSymbol Get_##layoutName##_Symbol() { return k_symPanel##layoutName; } \
+ panorama::CPanel2DFactory g_##layoutName##_Helper( &k_symPanel##layoutName, #layoutName, NULL, NULL, &Get_##layoutName##_Symbol );
+
+
+
+#define DECLARE_PANEL2D( className, baseClassName ) \
+public: \
+ typedef baseClassName BaseClass; \
+ typedef className ThisClass; \
+ static panorama::CPanoramaSymbol m_symbol; \
+ \
+ static panorama::CPanoramaSymbol GetPanelSymbol() { return className::m_symbol; } \
+ virtual panorama::CPanoramaSymbol GetPanelType() const { return className::m_symbol; } \
+private:
+
+
+#define DECLARE_PANEL2D_NO_BASE( className ) \
+public: \
+ typedef className ThisClass; \
+ typedef className BaseClass; \
+ static panorama::CPanoramaSymbol m_symbol; \
+ \
+ static panorama::CPanoramaSymbol GetPanelSymbol() { return className::m_symbol; } \
+ virtual panorama::CPanoramaSymbol GetPanelType() const { return className::m_symbol; } \
+private:
+
+} // namespace panorama
+
+inline uint32 HashItem( const panorama::CPanoramaSymbol &item )
+{
+ return ::HashItem( (UtlSymId_t)item );
+}
+
+
+#endif // PANEL2DFACTORY_H \ No newline at end of file
diff --git a/public/panorama/layout/stylefiletypes.h b/public/panorama/layout/stylefiletypes.h
new file mode 100644
index 0000000..418d6ad
--- /dev/null
+++ b/public/panorama/layout/stylefiletypes.h
@@ -0,0 +1,61 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_STYLEFILETYPES_H
+#define PANORAMA_STYLEFILETYPES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "../iuipanel.h"
+
+namespace panorama
+{
+class IUILayoutFile;
+class IUIPanel;
+
+//-----------------------------------------------------------------------------
+// Purpose: Validate statics
+//-----------------------------------------------------------------------------
+#ifdef DBGFLAG_VALIDATE
+ void ValidateStylePropertyFactory( CValidator &validator );
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose: Used to sort styles to apply by cascade order
+//-----------------------------------------------------------------------------
+struct StyleFromFile_t;
+class CLayoutFile;
+struct CascadeStyleFileInfo_t
+{
+ const StyleFromFile_t *m_pStyleFromFile;
+ panorama::IUILayoutFile *m_pLayoutFile; // layout file
+ uint m_iStyleFile; // layout file index
+ uint m_unSelectorSpecificity; // score for this selector (high = overrides lower valued selectors)
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: All the info needed to identify a panel. Used when looking up a style w/o a IUIPanel*
+//-----------------------------------------------------------------------------
+class CPanelIdentifiers
+{
+public:
+ CPanelIdentifiers();
+ CPanelIdentifiers( IUIPanel *pPanel );
+
+ CPanoramaSymbol m_symPanelType;
+ uint m_unStyleFlags;
+ const CPanoramaSymbol *m_psymClasses;
+ uint m_csymClasses;
+ const char *m_pchID;
+ bool m_bTreatPanelAsParent;
+ IUIPanel *m_pPanel;
+};
+
+} // namespace panorama
+
+
+#endif //PANORAMA_STYLEFILETYPES_H
diff --git a/public/panorama/layout/stylesymbol.h b/public/panorama/layout/stylesymbol.h
new file mode 100644
index 0000000..c94286b
--- /dev/null
+++ b/public/panorama/layout/stylesymbol.h
@@ -0,0 +1,73 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef STYLESYMBOL_H
+#define STYLESYMBOL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#define MAX_PANORAMA_STYLE_SYMBOLS 128
+
+#include "tier0/validator.h"
+#include "utlsymbol.h"
+#include "utlvector.h"
+#ifdef SOURCE_PANORAMA_FIXME
+#include "UtlSortVector.h"
+#else
+#include "utlsortvector.h"
+#endif
+#include "utlstring.h"
+
+
+namespace panorama
+{
+
+ class CStyleProperty;
+
+ class CStyleSymbol
+ {
+ public:
+ // constructor, destructor
+ CStyleSymbol() : m_Id( 0xFF ) {}
+ CStyleSymbol( uint8 id ) : m_Id( id ) {}
+ CStyleSymbol( char const* pStr );
+ CStyleSymbol( char const* pStr, bool bCreateNew );
+ CStyleSymbol( CStyleSymbol const& sym ) : m_Id(sym.m_Id) {}
+
+ // operator=
+ CStyleSymbol& operator=( CStyleSymbol const& src ) { m_Id = src.m_Id; return *this; }
+
+ // operator==
+ bool operator==( CStyleSymbol const& src ) const { return m_Id == src.m_Id; }
+ bool operator==( char const* pStr ) const;
+
+ // operator !=
+ bool operator!=( CStyleSymbol const& src ) const { return m_Id != src.m_Id; }
+
+ // operator <
+ bool operator < (const CStyleSymbol &rhs ) const { return m_Id < rhs.m_Id; }
+
+
+ uint8 GetID() const { return m_Id; }
+
+ // Is valid?
+ bool IsValid() const { return m_Id != 0xFF; }
+
+ // Gets the string associated with the symbol
+ char const* String() const;
+
+ operator const char *() const { return String(); }
+
+ protected:
+ uint8 m_Id;
+ };
+
+ uint32 HashItem( const CStyleSymbol &item );
+
+} // namespace panorama
+
+#endif // STYLESYMBOL_H
diff --git a/public/panorama/layout/uilength.h b/public/panorama/layout/uilength.h
new file mode 100644
index 0000000..d6dad83
--- /dev/null
+++ b/public/panorama/layout/uilength.h
@@ -0,0 +1,147 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UILENGTH_H
+#define UILENGTH_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "float.h"
+#include "tier0/dbg.h"
+#include "tier1/utlvector.h"
+#include "mathlib/mathlib.h"
+#include "../panorama.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: defines
+//-----------------------------------------------------------------------------
+const float k_flFloatAuto = FLT_MAX;
+const float k_flFloatNotSet = FLT_MIN;
+
+// Sometimes we want to say "infinite width/height", but we can't use FLT_MAX as it's "auto"
+const float k_flMaxWidthOrHeight = 512000000.0f;
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents possible length values
+//-----------------------------------------------------------------------------
+class CUILength
+{
+public:
+ enum EUILengthTypes
+ {
+ k_EUILengthUnset,
+ k_EUILengthLength,
+ k_EUILengthPercent,
+ k_EUILengthFitChildren,
+ k_EUILengthFillParentFlow,
+ k_EUILengthHeightPercentage,
+ k_EUILengthWidthPercentage,
+ };
+
+ CUILength() : m_flValue( k_flFloatNotSet ), m_eType( k_EUILengthUnset ) {}
+ CUILength( float flValue, EUILengthTypes eType ) : m_flValue( flValue ), m_eType( eType ) {}
+
+ bool IsSet() const { return (m_eType != k_EUILengthUnset); }
+ bool IsLength() const { return (m_eType == k_EUILengthLength); }
+ bool IsPercent() const { return (m_eType == k_EUILengthPercent); }
+ bool IsFitChildren() const { return (m_eType == k_EUILengthFitChildren); }
+ bool IsFillParentFlow() const { return (m_eType == k_EUILengthFillParentFlow); }
+ bool IsHeightPercentage() const { return (m_eType == k_EUILengthHeightPercentage); }
+ bool IsWidthPercentage() const { return (m_eType == k_EUILengthWidthPercentage); }
+
+ float GetValue() const { return m_flValue; }
+ CUILength::EUILengthTypes GetType() const { return m_eType; }
+
+ void SetFitChildren() { Set( k_flFloatAuto, k_EUILengthFitChildren ); }
+ void SetLength( float flValue ) { Set( flValue, k_EUILengthLength ); }
+ void SetPercent( float flValue ) { Set( flValue, k_EUILengthPercent ); }
+ void SetFillParentFlow( float flWeight ) { Set( flWeight, k_EUILengthFillParentFlow ); }
+ void SetParentFlow( float flValue ) { Set( flValue, k_EUILengthFillParentFlow ); }
+ void SetHeightPercentage( float flValue ) { Set( flValue, k_EUILengthHeightPercentage ); }
+ void SetWidthPercentage( float flValue ) { Set( flValue, k_EUILengthWidthPercentage ); }
+
+ void Set( float flValue, EUILengthTypes eType )
+ {
+ m_flValue = flValue;
+ m_eType = eType;
+ }
+
+ void ConvertToLength( float flTotalLength )
+ {
+ if ( m_eType == k_EUILengthPercent )
+ Set( GetValueAsLength( flTotalLength ), k_EUILengthLength );
+ else
+ Assert( m_eType == k_EUILengthLength || m_eType == k_EUILengthUnset );
+ }
+
+ void ConvertToPercent( float flTotalLength )
+ {
+ if ( m_eType == k_EUILengthLength )
+ Set( m_flValue / flTotalLength * 100.0, k_EUILengthPercent );
+ else
+ Assert( m_eType == k_EUILengthPercent || m_eType == k_EUILengthUnset );
+ }
+
+ float GetValueAsLength( float flTotalLength ) const
+ {
+ float flRet = m_flValue;
+ if ( m_eType == k_EUILengthPercent )
+ flRet = m_flValue * flTotalLength / 100.0;
+ else
+ Assert( m_eType == k_EUILengthLength );
+
+ return flRet;
+ }
+
+ void ScaleLengthValue( float flScaleFactor )
+ {
+ if ( m_eType == k_EUILengthLength && m_flValue != k_flFloatAuto && m_flValue != k_flFloatNotSet )
+ {
+ // Don't make width/height values of 1.0 shrink, as things like 1 px horizontal rules will go invisible! Kind of hacky,
+ // but this mostly works without issue as we have so few things < 1px.
+ if ( fabsf( 1.0f - fabsf( m_flValue ) ) < 0.1f && flScaleFactor < 1.0f )
+ {
+ // Don't need to adjust
+ }
+ else
+ {
+ // If the original value was pixel aligned, try to keep that. This is important so text doesn't accumulate error layers down
+ // from us and thus get blurry. Can't apply this rule to all values though as things like a shadow offset of 5.5 can be common
+ // and the half pixel can be important for the shadow to balance on both sides of the layer.
+ if ( fabsf( m_flValue - (float)RoundFloatToInt( m_flValue ) ) < 0.001f )
+ m_flValue = (float)RoundFloatToInt( m_flValue * flScaleFactor );
+ else
+ m_flValue = m_flValue * flScaleFactor;
+ }
+ }
+ }
+
+ bool operator==( const CUILength &rhs ) const
+ {
+ return (m_flValue == rhs.m_flValue && m_eType == rhs.m_eType);
+ }
+
+ bool operator!=( const CUILength &rhs ) const
+ {
+ return !(*this == rhs);
+ }
+
+
+private:
+ float m_flValue;
+ EUILengthTypes m_eType;
+};
+
+// Helper for doing lerp on ui length values, converting % and such
+CUILength LerpUILength( float flProgress, CUILength start, CUILength end, float flPixelSize );
+
+} // namespace panorama
+
+#endif //UILENGTH_H \ No newline at end of file
diff --git a/public/panorama/localization/ilocalize.h b/public/panorama/localization/ilocalize.h
new file mode 100644
index 0000000..9de0d81
--- /dev/null
+++ b/public/panorama/localization/ilocalize.h
@@ -0,0 +1,406 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_ILOCALIZE_H
+#define PANORAMA_ILOCALIZE_H
+
+#include "language.h"
+#include "tier0/platform.h"
+#include "tier1/interface.h"
+#include "tier1/utlflags.h"
+#include "tier1/utlsymbol.h"
+#include "tier1/utlstring.h"
+#include "tier1/utlmap.h"
+#include "tier1/fileio.h"
+#include "tier1/utlpriorityqueue.h"
+#include "steam/steamtypes.h"
+#if defined( SOURCE2_PANORAMA )
+#include "currencyamount.h"
+#else
+#include "stime.h"
+#include "constants.h"
+#include "globals.h"
+#include "amount.h"
+#include "rtime.h"
+#endif
+#include "reliabletimer.h"
+#include "language.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: type of variable data we are supporting
+//-----------------------------------------------------------------------------
+enum EPanelKeyType
+{
+ k_ePanelVartype_None,
+ k_ePanelVartype_String,
+ k_ePanelVartype_Time,
+ k_ePanelVartype_Money,
+ k_ePanelVartype_Number,
+ k_ePanelVartype_Generic
+};
+
+// help function syntax for the generic key handler
+typedef const char *( *PFNLocalizeDialogVariableHandler )( const CUtlString &sStringValue, int nIntValue, const IUIPanel *pPanel, const char *pszKey, void *pUserData );
+
+enum EPanelKeyTimeModifiers
+{
+ k_ePanelKeyTimeModifiers_ShortDate = 1 << 0,
+ k_ePanelKeyTimeModifiers_LongDate = 1 << 1,
+ k_ePanelKeyTimeModifiers_ShortTime = 1 << 2,
+ k_ePanelKeyTimeModifiers_LongTime = 1 << 3,
+ k_ePanelKeyTimeModifiers_DateTime = 1 << 4,
+ k_ePanelKeyTimeModifiers_Relative = 1 << 5,
+ k_ePanelKeyTimeModifiers_Duration = 1 << 6,
+};
+
+enum EStringTruncationStyle
+{
+ k_eStringTruncationStyle_None,
+ k_eStringTruncationStyle_Rear, // prevent any chars being added above max length
+ k_eStringTruncationStyle_Front, // remove
+};
+
+enum EStringTransformStyle
+{
+ k_eStringTransformStyle_None,
+ k_eStringTransformStyle_Uppercase,
+ k_eStringTransformStyle_Lowercase,
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: callback interface to help measuring strings
+//-----------------------------------------------------------------------------
+class ILocalizationStringSizeResolver
+{
+public:
+ virtual ~ILocalizationStringSizeResolver() {}
+ virtual int ResolveStringLengthInPixels( const char *pchString ) = 0;
+};
+
+
+const uint32 k_nLocalizeMaxChars = (uint32)~0;
+
+class CPanelKeyValue;
+class CLocalization;
+class CPanel2D;
+
+//-----------------------------------------------------------------------------
+// Purpose: interface to final string data to display to users
+//-----------------------------------------------------------------------------
+class ILocalizationString
+{
+public:
+ virtual ~ILocalizationString() {}
+
+ // Get the length of the string in characters
+ virtual int Length() const = 0;
+ virtual bool IsEmpty() const = 0;
+
+ virtual const char *String() const = 0;
+ virtual const char *StringNoTransform() const = 0;
+ virtual operator const char *() const = 0;
+
+ // add this string on the end
+ virtual bool AppendText( const char *pchText ) = 0;
+ // done with this string, delete it
+ virtual void Release() const = 0;
+
+ virtual EStringTransformStyle GetTransformStyle() const = 0;
+ virtual const IUIPanel *GetOwningPanel() const = 0;
+ virtual uint32 GetMaxChars() const = 0;
+ virtual EStringTruncationStyle GetTruncationStyle() const = 0;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName ) = 0;
+#endif
+protected:
+ // internal loc engine helpers, you won't call these
+ friend class CLocalization;
+ virtual void Recalculate( const CUtlString *pString ) = 0;
+ virtual bool BContainsDialogVariable( const CPanelKeyValue &key ) = 0;
+};
+
+class CLocStringSafePointer
+{
+public:
+ CLocStringSafePointer()
+ {
+ m_pString = NULL;
+ }
+
+ CLocStringSafePointer( const ILocalizationString *pLocString )
+ {
+ m_pString = pLocString;
+ }
+
+ CLocStringSafePointer &operator =( const ILocalizationString *pString )
+ {
+ if ( m_pString == pString )
+ return *this;
+
+ Clear();
+
+ m_pString = const_cast<ILocalizationString *>( pString );
+
+ return *this;
+ }
+
+ const ILocalizationString *operator ->( ) const
+ {
+ return Get();
+ }
+
+ const ILocalizationString *operator *( ) const
+ {
+ return Get();
+ }
+
+ operator const ILocalizationString*( ) const
+ {
+ return Get();
+ }
+
+ ~CLocStringSafePointer()
+ {
+ Clear();
+ }
+
+ void Clear()
+ {
+ if ( m_pString )
+ {
+ m_pString->Release();
+ m_pString = NULL;
+ }
+ }
+
+ bool IsValid() { return m_pString != nullptr; }
+
+ const ILocalizationString *Get() const
+ {
+ return m_pString;
+ }
+
+private:
+ const ILocalizationString *m_pString;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: interface to localize strings
+//-----------------------------------------------------------------------------
+class IUILocalization
+{
+public:
+ // change the language used by the loc system
+ virtual bool SetLanguage( const char *pchLanguage ) = 0;
+#if defined( SOURCE2_PANORAMA )
+ // add a loc file to the system, in the form of <prefix>_<language>.txt , i.e dota_french.txt, the files will be loaded from the panorama/localization folder of your mod
+ virtual bool BLoadLocalizationFile( const char *pchFilePrefix ) = 0;
+#else
+ virtual ELanguage CurrentLanguage() = 0;
+#endif
+
+ virtual void InstallCustomDialogVariableHandler( const char *pchCustomHandlerName, PFNLocalizeDialogVariableHandler pfnLocalizeFunc, void *pUserData = NULL ) = 0;
+ virtual void RemoveCustomDialogVariableHandler( const char *pchCustomHandlerName ) = 0;
+
+ // find the string corresponding to this localization token, or if we don't find it then just return back the string wrapped in a loc object
+ virtual const ILocalizationString *PchFindToken( const IUIPanel *pPanel, const char *pchToken, const uint32 ccMax , EStringTruncationStyle eTrunkStyle, EStringTransformStyle eTransformStyle, bool bAllowDialogVariable = false ) = 0;
+
+ // give me a localize string wrapper around this string, don't try and apply token localizing on it though, but do optionally allow it to have dialog variables that we parse in it
+ // be careful allowing dialog variable parsing, you want to sanitize any user input before allowing it
+ virtual const ILocalizationString *PchSetString( const IUIPanel *pPanel, const char *pchText, const uint32 ccMax, EStringTruncationStyle eTrunkStyle, EStringTransformStyle eTransformStyle, bool bAllowDialogVariable, bool bStringAlreadyFullyParsed ) = 0;
+
+ virtual const ILocalizationString *ChangeTransformStyleAndRelease( const ILocalizationString *pLocalizationString, EStringTransformStyle eTranformStyle ) = 0;
+
+ // copy an existing loc string without altering the ref count on the current
+ virtual ILocalizationString *CloneString( const IUIPanel *pPanel, const ILocalizationString *pLocToken ) = 0;
+
+ // return the raw, un-parsed, value for this loc token, returns NULL if we didn't have this token in a loc file from disk
+ virtual const char *PchFindRawString( const char *pchToken ) = 0;
+
+ virtual bool SetDialogVariable( const IUIPanel *pPanel, const char *pchKey, const char *pchValue ) = 0;
+#if defined( SOURCE2_PANORAMA )
+ virtual bool SetDialogVariable( const IUIPanel *pPanel, const char *pchKey, time_t timeVal ) = 0;
+ virtual bool SetDialogVariable( const IUIPanel *pPanel, const char *pchKey, CCurrencyAmount amount ) = 0;
+#else
+ virtual bool SetDialogVariable( const IUIPanel *pPanel, const char *pchKey, CRTime timeVal ) = 0;
+ virtual bool SetDialogVariable( const IUIPanel *pPanel, const char *pchKey, CAmount amount ) = 0;
+#endif
+
+ virtual bool SetDialogVariable( const IUIPanel *pPanel, const char *pchKey, int nVal ) = 0;
+
+ // copy all the dialog vars to a new panel
+ virtual void CloneDialogVariables( const IUIPanel *pPanelFrom, IUIPanel *pPanelTo ) = 0;
+
+ // force a re-evaluation of a specific dialog variable
+ virtual void DirtyDialogVariable( const IUIPanel *pPanel, const char *pchKey ) = 0;
+
+
+ // given this loc string find the longest string in any language that we could display here and update to use it
+ virtual void SetLongestStringForToken( const ILocalizationString *pLocalizationString, ILocalizationStringSizeResolver *pResolver ) = 0;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Wrapper around ILocalizationString that will take care of making
+// a copy if it ends up needing to be mutable.
+//-----------------------------------------------------------------------------
+class CMutableLocalizationString
+{
+public:
+ CMutableLocalizationString()
+ : m_bMutable( false )
+ , m_pString( NULL )
+ {
+ }
+
+ CMutableLocalizationString( ILocalizationString *pString )
+ : m_bMutable( true )
+ , m_pString( pString )
+ {
+ }
+
+ CMutableLocalizationString( const ILocalizationString *pString )
+ : m_bMutable( false )
+ , m_pString( const_cast< ILocalizationString * >( pString ) )
+ {
+ }
+
+ CMutableLocalizationString( const CMutableLocalizationString &other )
+ {
+ m_bMutable = true;
+ if ( other.m_pString )
+ {
+ m_pString = UILocalize()->CloneString( other.m_pString->GetOwningPanel(), other.m_pString );
+ }
+ else
+ {
+ m_pString = NULL;
+ }
+ }
+
+ ~CMutableLocalizationString()
+ {
+ Clear();
+ }
+
+ const ILocalizationString *Get() const
+ {
+ return m_pString;
+ }
+
+ ILocalizationString *GetMutable()
+ {
+ if ( m_bMutable || !m_pString )
+ return m_pString;
+
+ ILocalizationString *pOldString = m_pString;
+
+ m_pString = UILocalize()->CloneString( pOldString->GetOwningPanel(), pOldString );
+ m_bMutable = true;
+
+ pOldString->Release();
+
+ return m_pString;
+ }
+
+ void Clear()
+ {
+ if ( m_pString )
+ {
+ m_pString->Release();
+ m_pString = NULL;
+ }
+ }
+
+ const ILocalizationString *Extract()
+ {
+ const ILocalizationString *pString = m_pString;
+ m_pString = NULL;
+ return pString;
+ }
+ ILocalizationString *ExtractMutable()
+ {
+ ILocalizationString *pString = GetMutable();
+ m_pString = NULL;
+ return pString;
+ }
+
+ // The -> operator is only overloaded to return a const string. If you need a mutable version, you must call GetMutable directly.
+ const ILocalizationString *operator ->() const
+ {
+ return Get();
+ }
+
+
+ explicit operator bool() const
+ {
+ return Get() != NULL;
+ }
+ bool operator ==( const CMutableLocalizationString &other ) const
+ {
+ return m_pString == other.m_pString;
+ }
+ bool operator !=( const CMutableLocalizationString &other ) const
+ {
+ return !( *this == other );
+ }
+
+ bool operator ==( const ILocalizationString *pString ) const
+ {
+ return m_pString == pString;
+ }
+ bool operator !=( const ILocalizationString *pString ) const
+ {
+ return !( *this == pString );
+ }
+
+ CMutableLocalizationString &operator =( const CMutableLocalizationString &other )
+ {
+ if ( other.m_pString == m_pString )
+ return *this;
+
+ Clear();
+
+ m_bMutable = true;
+ if ( other.m_pString )
+ {
+ m_pString = UILocalize()->CloneString( other.m_pString->GetOwningPanel(), other.m_pString );
+ }
+ else
+ {
+ m_pString = NULL;
+ }
+
+ return *this;
+ }
+
+ CMutableLocalizationString &operator =( const ILocalizationString *pString )
+ {
+ if ( m_pString == pString )
+ return *this;
+
+ Clear();
+
+ m_bMutable = false;
+ m_pString = const_cast< ILocalizationString * >( pString );
+
+ return *this;
+ }
+
+private:
+ bool m_bMutable;
+ ILocalizationString *m_pString;;
+};
+
+
+} // namespace panorama
+
+#endif // PANORAMA_ILOCALIZE_H
diff --git a/public/panorama/panorama.h b/public/panorama/panorama.h
new file mode 100644
index 0000000..3d6d8cb
--- /dev/null
+++ b/public/panorama/panorama.h
@@ -0,0 +1,76 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose: Public header for panorama UI framework
+//
+//
+//=============================================================================//
+#ifndef PANORAMA_H
+#define PANORAMA_H
+#pragma once
+
+namespace panorama
+{
+
+#ifndef PANORAMA_EXPORTS
+#define PANORAMA_INTERFACE
+#else
+#define PANORAMA_INTERFACE DLL_EXPORT
+#endif
+
+#ifdef PANORAMA_CLIENT_EXPORTS
+
+#if defined(PLATFORM_WINDOWS_PC32) || ( defined( _WIN32 ) && !defined( _WIN64 ) )
+#define REFERENCE_PANEL_CORE( className, layoutName ) \
+ __pragma( comment( linker, "/INCLUDE:?g_"#layoutName"LinkerHack@panorama@@3PAV"#className"@1@A" ) );
+#elif defined(PLATFORM_WINDOWS_PC64) || defined( _WIN64 )
+#define REFERENCE_PANEL_CORE( className, layoutName ) \
+ __pragma( comment( linker, "/INCLUDE:?g_"#layoutName"LinkerHack@panorama@@3PEAV"#className"@1@EA" ) );
+#else
+#define REFERENCE_PANEL_CORE( className, layoutName ) \
+ class className; \
+ extern className *g_##layoutName##LinkerHack; \
+ className *g_##layoutName##PullInModule SELECTANY = g_##layoutName##LinkerHack;
+#endif
+
+#define REFERENCE_PANEL( name ) \
+ REFERENCE_PANEL_CORE( C##name, name )
+
+// Referenced internal to the framework, so this becomes unneeded
+//REFERENCE_PANEL( Image )
+//REFERENCE_PANEL( Panel )
+REFERENCE_PANEL( Label )
+REFERENCE_PANEL( Button )
+REFERENCE_PANEL( ToggleButton )
+REFERENCE_PANEL( Carousel )
+REFERENCE_PANEL( HTML )
+REFERENCE_PANEL( TextEntry )
+REFERENCE_PANEL( Tooltip )
+REFERENCE_PANEL( VerticalScrollList )
+REFERENCE_PANEL( DebugLayout )
+REFERENCE_PANEL( DebugPanelParents )
+REFERENCE_PANEL( DebugAutoComplete )
+REFERENCE_PANEL( DebugPanel )
+REFERENCE_PANEL( DebugPanelComputed )
+REFERENCE_PANEL( DebugPanelStyle )
+REFERENCE_PANEL( DebugIndividualStyle )
+REFERENCE_PANEL( DebugStyleAnimation )
+REFERENCE_PANEL( DebugInheritedStylesHeader )
+REFERENCE_PANEL( DebugStyleBlock )
+REFERENCE_PANEL( DropDown )
+REFERENCE_PANEL( Grid )
+REFERENCE_PANEL( ProgressBar )
+REFERENCE_PANEL( ContextMenu )
+REFERENCE_PANEL( SimpleContextMenu )
+REFERENCE_PANEL( Slider )
+REFERENCE_PANEL( ListSegmentView )
+REFERENCE_PANEL( AnimatedImageStrip )
+REFERENCE_PANEL_CORE( CMoviePlayer, Movie )
+REFERENCE_PANEL( MoviePanel )
+REFERENCE_PANEL( VolumeSliderPopup )
+REFERENCE_PANEL_CORE( CMovieVideoQualityPopup, VideoQualityPopup )
+REFERENCE_PANEL( EdgeScroller )
+#endif
+
+} // namespace panorama
+
+#endif // PANORAMA_H
diff --git a/public/panorama/panoramacurves.h b/public/panorama/panoramacurves.h
new file mode 100644
index 0000000..f1c0cb5
--- /dev/null
+++ b/public/panorama/panoramacurves.h
@@ -0,0 +1,22 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose: Public header for panorama UI framework
+//
+//
+//=============================================================================//
+
+#ifndef PANORAMA_PANORAMACURVES_H
+#define PANORAMA_PANORAMACURVES_H
+#pragma once
+
+#include "panoramatypes.h"
+
+namespace panorama
+{
+
+void GetAnimationCurveControlPoints( EAnimationTimingFunction eAnimation, Vector2D points[4] );
+
+};
+
+#endif
+
diff --git a/public/panorama/panoramacxx.h b/public/panorama/panoramacxx.h
new file mode 100644
index 0000000..a4043b5
--- /dev/null
+++ b/public/panorama/panoramacxx.h
@@ -0,0 +1,131 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMACXX_H
+#define PANORAMACXX_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+// TEMPLATE CLASS integral_constant
+template<class _Ty,
+ _Ty _Val>
+struct panorama_integral_constant
+{ // convenient template for integral constant types
+ static const _Ty value = _Val;
+
+ typedef _Ty value_type;
+ typedef panorama_integral_constant<_Ty, _Val> type;
+
+ operator value_type() const
+ { // return stored value
+ return (value);
+ }
+};
+
+typedef panorama_integral_constant<bool, true> true_type;
+typedef panorama_integral_constant<bool, false> false_type;
+
+
+// TEMPLATE CLASS _Cat_base
+template<bool>
+struct panorama_Cat_base
+ : false_type
+{ // base class for type predicates
+};
+
+template<>
+struct panorama_Cat_base < true >
+ : true_type
+{ // base class for type predicates
+};
+
+// TEMPLATE CLASS enable_if
+template<bool _Test,
+class _Ty = void>
+struct panorama_enable_if
+{ // type is undefined for assumed !_Test
+};
+
+template<class _Ty>
+struct panorama_enable_if < true, _Ty >
+{ // type is _Ty for _Test
+ typedef _Ty type;
+};
+
+#define PANORAMA_IS_BASE_OF(_Base, _Der) \
+ : panorama_Cat_base<__is_base_of(_Base, _Der)>
+
+// TEMPLATE CLASS is_base_of
+template<class _Base, class _Der>
+struct panorama_is_base_of PANORAMA_IS_BASE_OF( _Base, _Der )
+{ // determine whether _Base is a base of or the same as _Der
+};
+
+#define PANORAMA_IS_ENUM(_Ty) \
+ : panorama_Cat_base<__is_enum(_Ty)>
+
+// TEMPLATE CLASS is_enum
+template<class _Ty>
+struct panorama_is_enum
+ PANORAMA_IS_ENUM( _Ty )
+{ // determine whether _Ty is an enumerated type
+};
+
+
+// TEMPLATE CLASS is_lvalue_reference
+template<class _Ty>
+struct panorama_is_lvalue_reference
+ : false_type
+{ // determine whether _Ty is an lvalue reference
+};
+
+template<class _Ty>
+struct panorama_is_lvalue_reference < _Ty& >
+ : true_type
+{ // determine whether _Ty is an lvalue reference
+};
+
+
+// TEMPLATE remove_reference
+template<class _Ty>
+struct panorama_remove_reference
+{ // remove reference
+ typedef _Ty type;
+};
+
+template<class _Ty>
+struct panorama_remove_reference < _Ty& >
+{ // remove reference
+ typedef _Ty type;
+};
+
+template<class _Ty>
+struct panorama_remove_reference < _Ty&& >
+{ // remove rvalue reference
+ typedef _Ty type;
+};
+
+// TEMPLATE FUNCTION forward
+template<class _Ty> inline
+_Ty&& panorama_forward( typename panorama_remove_reference<_Ty>::type& _Arg )
+{ // forward an lvalue
+ return (static_cast<_Ty&&>(_Arg));
+}
+
+template<class _Ty> inline
+_Ty&& panorama_forward( typename panorama_remove_reference<_Ty>::type&& _Arg )
+{ // forward anything
+ static_assert(!panorama_is_lvalue_reference<_Ty>::value, "bad forward call");
+ return (static_cast<_Ty&&>(_Arg));
+}
+
+}
+
+#endif // PANORAMACXX_H
diff --git a/public/panorama/panoramasymbol.h b/public/panorama/panoramasymbol.h
new file mode 100644
index 0000000..511a285
--- /dev/null
+++ b/public/panorama/panoramasymbol.h
@@ -0,0 +1,56 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMASYMBOL_H
+#define PANORAMASYMBOL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "utlsymbol.h"
+
+namespace panorama
+{
+
+
+// Panorama wrapper around CUtlSymbol which always creates symbol in panorama.dll module
+class CPanoramaSymbol
+{
+public:
+ // constructor, destructor
+ CPanoramaSymbol() : m_Id( UTL_INVAL_SYMBOL ) {}
+ CPanoramaSymbol( UtlSymId_t id ) : m_Id( id ) {}
+ CPanoramaSymbol( char const* pStr );
+ CPanoramaSymbol( CPanoramaSymbol const& sym ) : m_Id( sym.m_Id ) {}
+
+ // operator=
+ CPanoramaSymbol& operator=(CPanoramaSymbol const& src) { m_Id = src.m_Id; return *this; }
+
+ // operator==
+ bool operator==(CPanoramaSymbol const& src) const { return m_Id == src.m_Id; }
+ bool operator==(char const* pStr) const { return CPanoramaSymbol( pStr ).m_Id == m_Id; }
+
+ // sort by index offset and NOT lexigraphical
+ bool operator<(CPanoramaSymbol const& src) const { return m_Id < src.m_Id; }
+ bool operator>( CPanoramaSymbol const& src ) const { return m_Id > src.m_Id; }
+ bool operator!=(CPanoramaSymbol const& src) const { return !operator==(src); }
+
+ // Is valid?
+ bool IsValid() const { return m_Id != UTL_INVAL_SYMBOL; }
+
+ // Gets at the symbol
+ operator UtlSymId_t () const { return m_Id; }
+
+ // Gets the string associated with the symbol
+ char const* String() const;
+
+private:
+ UtlSymId_t m_Id;
+};
+
+} // namespace panorama
+
+#endif // PANORAMASYMBOL_H \ No newline at end of file
diff --git a/public/panorama/panoramatypes.h b/public/panorama/panoramatypes.h
new file mode 100644
index 0000000..e7cb836
--- /dev/null
+++ b/public/panorama/panoramatypes.h
@@ -0,0 +1,594 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose: Public header for panorama UI framework
+//
+//
+//=============================================================================//
+#ifndef PANORAMATYPES_H
+#define PANORAMATYPES_H
+#pragma once
+
+#ifdef POSIX
+#include <float.h>
+#endif
+#include "mathlib/vector.h"
+
+#ifdef SOURCE2_PANORAMA
+#include "tier1/mempool.h"
+#include "tier1/checksum_sha1.h"
+
+class ISceneView;
+class IRenderContext;
+class ISceneLayer;
+typedef void (RenderCallbackFunction_t)( ISceneView *, IRenderContext **, ISceneLayer *, float, float, float, float );
+
+#endif
+
+#if !defined( SOURCE2_PANORAMA )
+#define VPROF_BUDGET_THREAD VPROF_BUDGET
+#else
+#define VPROF_BUDGET_THREAD( name, group ) ((void)0)
+
+const uint32 k_cubSHA1Hash = k_cubHash;
+
+#ifndef SAFE_DELETE
+#define SAFE_DELETE( x ) if ( (x) != NULL ) { delete (x); x = NULL; }
+#endif
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE( x ) if ( NULL != ( x ) ) { ( x )->Release(); x = NULL; }
+#endif
+#define AssertFatalMsg2( b, msg, p1, p2 ) AssertFatalMsg( b, msg, p1, p2 )
+#define AssertFatalMsg1( b, msg, p1 ) AssertFatalMsg( b, msg, p1 )
+
+template <class T, class P>
+inline void ConstructOneArg( T* pMemory, P const& arg )
+{
+ HINT( pMemory != 0 );
+ ::new(pMemory)T( arg );
+}
+
+template <class T, class P, class P2 >
+inline void ConstructTwoArg( T* pMemory, P const& arg1, P2 const &arg2 )
+{
+ HINT( pMemory != 0 );
+ ::new(pMemory)T( arg1, arg2 );
+}
+
+template <class T, class P, class P2, class P3, class P4, class P5, class P6, class P7 >
+inline void ConstructSevenArg( T* pMemory, P const& arg1, P2 const &arg2, P3 const &arg3, P4 const &arg4, P5 const &arg5, P6 const &arg6, P7 const &arg7 )
+{
+ HINT( pMemory != 0 );
+ ::new(pMemory)T( arg1, arg2, arg3, arg4, arg5, arg6, arg7 );
+}
+#endif
+
+
+namespace panorama
+{
+
+class IUIPanelClient;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Text/font related types
+//-----------------------------------------------------------------------------
+enum EFontWeight
+{
+ k_EFontWeightUnset = -1,
+ k_EFontWeightNormal = 0,
+ k_EFontWeightMedium = 1,
+ k_EFontWeightBold = 2,
+ k_EFontWeightBlack = 3,
+ k_EFontWeightThin = 4,
+ k_EFontWeightLight = 5,
+ k_EFontWeightSemiBold = 6,
+};
+
+enum EFontStyle
+{
+ k_EFontStyleUnset = -1,
+ k_EFontStyleNormal = 0,
+ k_EFontStyleItalic = 2,
+};
+
+enum ETextAlign
+{
+ k_ETextAlignUnset = -1,
+ k_ETextAlignLeft = 0,
+ k_ETextAlignCenter = 1,
+ k_ETextAlignRight = 2
+};
+
+enum ETextDecoration
+{
+ k_ETextDecorationUnset = -1,
+ k_ETextDecorationNone = 0,
+ k_ETextDecorationUnderline = 1,
+ k_ETextDecorationLineThrough = 2,
+};
+
+enum ETextTransform
+{
+ k_ETextTransformUnset = -1,
+ k_ETextTransformNone = 0,
+ k_ETextTransformUppercase = 1,
+ k_ETextTransformLowercase = 2,
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Transform related types
+//-----------------------------------------------------------------------------
+enum ETransform3DType
+{
+ k_ETransform3DRotate,
+ k_ETransform3DTranslate,
+ k_ETransform3DScale
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Types for border images
+//-----------------------------------------------------------------------------
+enum EBorderImageRepeatType
+{
+ k_EBorderImageStretchStretch = 0,
+ k_EBorderImageStretchRepeat = 1,
+ k_EBorderImageStretchRound = 2,
+ k_EBorderImageStretchSpace = 3,
+};
+
+
+enum EBorderImageWidthType
+{
+ k_EBorderImageWidthAuto = 0,
+ k_EBorderImageWidthNumber = 1,
+ k_EBorderImageWidthPercentage = 2
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Transition timing functions
+//-----------------------------------------------------------------------------
+enum EAnimationTimingFunction
+{
+ k_EAnimationNone = 0, // Indicates that there is no transition set, do not animate. Don't change from zero!
+ k_EAnimationEase,
+ k_EAnimationEaseIn,
+ k_EAnimationEaseOut,
+ k_EAnimationEaseInOut,
+ k_EAnimationLinear,
+ k_EAnimationCustomBezier,
+
+ k_EAnimationUnset,
+ // if you add another, update BParseTimingFunction()
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Possible animation directions
+//-----------------------------------------------------------------------------
+enum EAnimationDirection
+{
+ k_EAnimationDirectionUnset = 0,
+ k_EAnimationDirectionNormal,
+ k_EAnimationDirectionAlternate,
+ k_EAnimationDirectionReverse,
+ k_EAnimationDirectionAlternateReverse,
+
+ // if you add another, update BParseAnimationDirectionFunction()
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Supported style psuedo classes
+//-----------------------------------------------------------------------------
+enum EStyleFlags : uint16
+{
+ k_EStyleFlagNone = 0,
+ k_EStyleFlagHover = 1 << 0, // mouse is over the panel
+ k_EStyleFlagFocus = 1 << 1, // panel has keyboard focus
+ k_EStyleFlagActive = 1 << 2, // panel is being actively used (mouse-down on the panel)
+ k_EStyleFlagDisabled = 1 << 3, // panel is disabled
+ k_EStyleFlagInspect = 1 << 4, // panel is being inspected by the debugger
+ k_EStyleFlagSelected = 1 << 5, // panel is selected (button checked)
+ k_EStyleFlagDescendantFocused = 1 << 6, // a descendant of the panel has keyboard focus
+ k_EStyleFlagParentDisabled = 1 << 7, // a parent of this panel is disabled, thus implicitly disabling it
+ k_EStyleFlagLayoutLoading = 1 << 8, // panel is in-progress loading it's layout file and thus may want to display specially
+ k_EStyleFlagLayoutLoadFailed = 1 << 9, // panel failed to load requested layout file, and thus may want to display specially
+ k_EStyleFlagActivationDisabled = 1 << 10, // panel is disabled for activation, may still be enabled for focus (normal disabled disallows all input/focus)
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Supported border styles
+//-----------------------------------------------------------------------------
+enum EBorderStyle
+{
+ k_EBorderStyleUnset = -1,
+ k_EBorderStyleNone = 0,
+ k_EBorderStyleSolid = 1,
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Horizontal alignments
+//-----------------------------------------------------------------------------
+enum EHorizontalAlignment
+{
+ k_EHorizontalAlignmentUnset,
+ k_EHorizontalAlignmentLeft,
+ k_EHorizontalAlignmentCenter,
+ k_EHorizontalAlignmentRight
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Vertical alignments
+//-----------------------------------------------------------------------------
+enum EVerticalAlignment
+{
+ k_EVerticalAlignmentUnset,
+ k_EVerticalAlignmentTop,
+ k_EVerticalAlignmentCenter,
+ k_EVerticalAlignmentBottom
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: ContextUI (tooltips + context menus) position
+//-----------------------------------------------------------------------------
+enum EContextUIPosition
+{
+ k_EContextUIPositionUnset,
+ k_EContextUIPositionLeft,
+ k_EContextUIPositionTop,
+ k_EContextUIPositionRight,
+ k_EContextUIPositionBottom,
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Possible flow directions
+//-----------------------------------------------------------------------------
+enum EBackgroundRepeat
+{
+ k_EBackgroundRepeatUnset,
+ k_EBackgroundRepeatRepeat,
+ k_EBackgroundRepeatSpace,
+ k_EBackgroundRepeatRound,
+ k_EBackgroundRepeatNo,
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Special words for background sizes when not length or percentage
+//-----------------------------------------------------------------------------
+enum EBackgroundSizeConstant
+{
+ k_EBackgroundSizeConstantNone,
+ k_EBackgroundSizeConstantContain,
+ k_EBackgroundSizeConstantCover
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: type of repaint to do for a render target/panel
+//-----------------------------------------------------------------------------
+enum EPanelRepaint : uint8
+{
+ k_EPanelRepaintFull,
+ k_EPanelRepaintComposition,
+ k_EPanelRepaintNone
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Specifies what category a sound is; each one of these maps to a volume control in the UI
+//-----------------------------------------------------------------------------
+enum ESoundType
+{
+ k_ESoundType_Ambient, // ambient sounds, intro movie
+ k_ESoundType_Movies, // movies in store
+ k_ESoundType_Effects, // daisywheel, navigation
+ k_ESoundType_Passthrough, // special sound type for volume-changing UI - bypasses volume controls
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Text Input handler types
+//-----------------------------------------------------------------------------
+enum ETextInputHandlerType_t
+{
+ k_ETextInputHandlerType_DaisyWheel,
+ k_ETextInputHandlerType_DualTouch,
+
+ k_ETextInputHandlerTypeDefault = k_ETextInputHandlerType_DualTouch, // if we fail at gathering the information to figure out which is the most appropriate input method, fall back to this one
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Possible flow directions
+//-----------------------------------------------------------------------------
+enum EFlowDirection : uint8
+{
+ k_EFlowNone,
+ k_EFlowDown,
+ k_EFlowRight,
+ k_EFlowDownWrap,
+ k_EFlowRightWrap
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Possible overflow settings
+//-----------------------------------------------------------------------------
+enum EOverflowValue : uint8
+{
+ k_EOverflowSquish,
+ k_EOverflowClip,
+ k_EOverflowScroll,
+ k_EOverflowNoClip,
+};
+
+
+enum EMouseCanActivate : uint8
+{
+ k_EMouseCanActivateUnfocused = 0,
+ k_EMouseCanActivateIfFocused,
+ k_EMouseCanActivateIfParentFocused,
+ k_EMouseCanActivateIfAnyParentFocused
+};
+
+// Focus navigation
+enum EFocusMoveDirection
+{
+ k_ENextInTabOrder = 1,
+ k_EPrevInTabOrder = 2,
+ k_ENextByXPosition = 4,
+ k_EPrevByXPosition = 8,
+ k_ENextByYPosition = 16,
+ k_EPrevByYPosition = 32
+};
+
+
+enum ELoadLayoutAsyncDetails
+{
+ k_ELoadLayoutAsyncDetailsNone,
+ k_ELoadLayoutAsyncDetailsNotLoggedIn
+};
+
+
+enum EMixBlendMode
+{
+ k_EMixBlendModeNormal,
+ k_EMixBlendModeMultiply,
+ k_EMixBlendModeScreen
+};
+
+
+enum ETextureSampleMode
+{
+ k_ETextureSampleModeNormal,
+ k_ETextureSampleModeAlphaOnly,
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Enum for the parts of layout a style invalidates when applied
+//-----------------------------------------------------------------------------
+enum EStyleInvalidateLayout
+{
+ k_EStyleInvalidateLayoutNone,
+ k_EStyleInvalidateLayoutSizeAndPosition,
+ k_EStyleInvalidateLayoutPosition
+};
+
+
+enum EStyleRepaint
+{
+ k_EStyleRepaintFull,
+ k_EStyleRepaintComposition,
+ k_EStyleRepaintNone,
+};
+
+
+enum EAntialiasing
+{
+ k_EAntialiasingNone,
+ k_EAntialisingEnabled
+};
+
+enum EOverlayWindowAlignment
+{
+ k_EOverlayWindowAlignment_FullscreenLetterboxed = 1,
+ k_EOverlayWindowAlignment_FullscreenNoLetterBox = 2,
+ k_EOverlayWindowAlignment_BottomRight = 3,
+};
+
+enum EStylePresentFlags : uint32
+{
+ k_EStylePresentTransformMatrix = 1 << 0,
+ k_EStylePresentPerspective = 1 << 1,
+ k_EStylePresentPerspectiveOrigin = 1 << 2,
+ k_EStylePresentOpacity = 1 << 3,
+ k_EStylePresentWashColor = 1 << 4,
+ k_EStylePresentDesaturation = 1 << 5,
+ k_EStylePresentBlur = 1 << 6,
+ k_EStylePresentBorderRadius = 1 << 7,
+ k_EStylePresentOpacityMaskImage = 1 << 8,
+ k_EStylePresentBackgroundImage = 1 << 9,
+ k_EStylePresentBackgroundFillColor = 1 << 10,
+ k_EStylePresentBorder = 1 << 11,
+ k_EStylePresentBoxShadow = 1 << 12,
+ k_EStylePresentBorderImage = 1 << 13,
+ k_EStylePresentScale2DCentered = 1 << 14,
+ k_EStylePresentRotate2DCentered = 1 << 15,
+ k_EStylePresentTextShadow = 1 << 16,
+ k_EStylePresentClip = 1 << 17,
+ k_EStylePresentMixBlendMode = 1 << 18,
+
+};
+
+// constants, these must remain matching
+const float k_flTabIndexInvalid = -1.0 * FLT_MAX;
+const float k_flSelectionPosInvalid = k_flTabIndexInvalid;
+const float k_flTabIndexAuto = FLT_MAX;
+const float k_flSelectionPosAuto = k_flTabIndexAuto;
+
+// These constants are duplicated in CSS files, so if you change them make sure to change the CSS values as well.
+const double k_flScrollTransitionTime = 0.2;
+const EAnimationTimingFunction k_flScrollTransitionFunc = k_EAnimationEaseInOut;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: bit flags used to control panel construction behavior
+//-----------------------------------------------------------------------------
+enum EPanelFlags
+{
+ ePanelFlags_DontAddAsChild = 0x1, // don't automatically add this panel as a child to its parent
+ ePanelFlags_DontFireOnLoad = 0x2, // don't fire the onload event when constructed, useful for image panel that waits until its contents load
+};
+
+
+enum EPanelEventSource_t
+{
+ k_ePanelEventSourceProgram,
+ k_ePanelEventSourceGamepad,
+ k_ePanelEventSourceKeyboard,
+ k_ePanelEventSourceMouse,
+
+ k_ePanelEventSourceInvalid
+};
+
+
+class IUIPanel;
+class IUIEvent;
+typedef IUIEvent* (*PFN_ParseUIEvent)(panorama::IUIPanel *pTarget, const char *pchEvent, const char **pchEventEnd);
+typedef IUIEvent* (*PFN_MakeUIEvent0)(const panorama::IUIPanelClient *pTarget);
+typedef IUIEvent* (*PFN_MakeUIEvent1Source)(const panorama::IUIPanelClient *pTarget, EPanelEventSource_t eSource);
+typedef IUIEvent* (*PFN_MakeUIEvent1Repeats)(const panorama::IUIPanelClient *pTarget, int nRepeats);
+struct UIEventFactory
+{
+ int m_cParams;
+ bool m_bPanelEvent;
+ PFN_ParseUIEvent m_pfnParseUIEvent;
+ PFN_MakeUIEvent0 m_pfnMakeUIEvent0;
+ PFN_MakeUIEvent1Repeats m_pfnMakeUIEvent1Repeats;
+ PFN_MakeUIEvent1Source m_pfnMakeUIEvent1Source;
+};
+
+
+//-----------------------------------------------------------------------------
+// Simple refcounted base class that doesn't auto-delete when refs hit zero.
+//-----------------------------------------------------------------------------
+class CLayoutRefCounted
+{
+public:
+ CLayoutRefCounted()
+ {
+ m_nRefCount = 0;
+ }
+ int AddRef()
+ {
+ return ++m_nRefCount;
+ }
+ int Release()
+ {
+ int nResult = --m_nRefCount;
+ Assert( nResult >= 0 );
+ return nResult;
+ }
+ int GetRefCount() const
+ {
+ return m_nRefCount;
+ }
+private:
+ int m_nRefCount;
+};
+
+
+//-----------------------------------------------------------------------------
+// Pointer to a CLayoutRefCounted that owns a ref of the pointee
+//-----------------------------------------------------------------------------
+template< class T >
+class CLayoutRefPtr
+{
+public:
+ CLayoutRefPtr() : m_pObject( NULL ) {}
+ CLayoutRefPtr( T *pFrom ) { Set( pFrom ); }
+ CLayoutRefPtr( const CLayoutRefPtr< T > &from ) { Set( from.m_pObject ); }
+ ~CLayoutRefPtr()
+ {
+ if ( m_pObject )
+ {
+ m_pObject->Release();
+ }
+ }
+
+ void operator=( const CLayoutRefPtr<T> &from ) { Set( from.m_pObject ); }
+
+ operator const T *() const { return m_pObject; }
+ operator T *() { return m_pObject; }
+
+ operator bool() const { return ( m_pObject != NULL ); }
+
+ T *operator=( T *p ) { Set( p ); return p; }
+
+ bool operator!() const { return ( !m_pObject ); }
+ bool operator==( T *p ) const { return ( m_pObject == p ); }
+ bool operator!=( T *p ) const { return ( m_pObject != p ); }
+ bool operator==( const CLayoutRefPtr<T> &p ) const { return ( m_pObject == p.m_pObject ); }
+ bool operator!=( const CLayoutRefPtr<T> &p ) const { return ( m_pObject != p.m_pObject ); }
+
+ T * operator->() { return m_pObject; }
+ T & operator *() { return *m_pObject; }
+ T ** operator &() { return &m_pObject; }
+
+ const T * operator->() const { return m_pObject; }
+ const T & operator *() const { return *m_pObject; }
+ T * const * operator &() const { return &m_pObject; }
+
+ void Set( T *pObject )
+ {
+ if ( m_pObject )
+ {
+ m_pObject->Release();
+ }
+
+ m_pObject = pObject;
+
+ if ( pObject )
+ {
+ pObject->AddRef();
+ }
+ }
+
+protected:
+ T *m_pObject;
+};
+
+
+enum EWindowFocusBehavior
+{
+ // By default, controls in this window will take focus whenever they're interacted with.
+ k_EWindowFocusBehavior_Default,
+
+ // By default, clicking on controls in this window will avoid taking focus unless it's necessary.
+ // Useful if you only plan on supporting keyboard focus in a few specific spots and otherwise
+ // don't display keyboard focus.
+ k_EWindowFocusBehavior_Shy,
+};
+
+
+struct SteamPadPointer_t
+{
+ bool bVisible;
+ Vector2D vecCenter;
+ float flRadius;
+ uint32 nTextureID;
+ int iControllerID;
+ float (* funcPreRenderCalculatePadOffset)( float, bool );
+};
+
+
+} // namespace panorama
+
+#endif // PANORAMATYPES_H \ No newline at end of file
diff --git a/public/panorama/renderer/styleproperties.h b/public/panorama/renderer/styleproperties.h
new file mode 100644
index 0000000..e3e0eb2
--- /dev/null
+++ b/public/panorama/renderer/styleproperties.h
@@ -0,0 +1,8025 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef STYLEPROPERTIES_H
+#define STYLEPROPERTIES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "layout/stylesymbol.h"
+#include "layout/csshelpers.h"
+#include "tier1/utlptrarray.h"
+#include "tier1/utlhashmap.h"
+#include "iuipanelstyle.h"
+#include "panoramatypes.h"
+
+namespace panorama
+{
+
+// Helper for getting actual size of parent, which will expand up to window size if top level
+void GetParentSizeAvailable( IUIPanel *pPanel, float &flParentWidth, float &flParentHeight, float &flParentPerspective );
+void GetAnimationCurveControlPoints( EAnimationTimingFunction eTransitionEffect, Vector2D vecPoints[4] );
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Information on a property in the middle of a transition
+//-----------------------------------------------------------------------------
+struct PropertyInTransition_t
+{
+ PropertyInTransition_t() { m_pStyleProperty = NULL; }
+ ~PropertyInTransition_t()
+ {
+ if( m_pStyleProperty )
+ UIEngine()->UIStyleFactory()->FreeStyleProperty( m_pStyleProperty );
+ }
+
+ TransitionProperty_t m_transitionData;
+ double m_flTransitionStartTime;
+ CStyleProperty *m_pStyleProperty;
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+private:
+ PropertyInTransition_t( const PropertyInTransition_t & );
+ PropertyInTransition_t &operator=(const PropertyInTransition_t &rhs);
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Individual animation property data
+//-----------------------------------------------------------------------------
+struct AnimationProperty_t
+{
+ CPanoramaSymbol m_symName; // keyframe name
+
+ double m_flDuration;
+ EAnimationTimingFunction m_eTimingFunction;
+ CCubicBezierCurve< Vector2D > m_CubicBezier;
+ float m_flIteration; // value or infinite
+ EAnimationDirection m_eAnimationDirection;
+ double m_flDelay;
+
+ bool operator==(const AnimationProperty_t &rhs) const
+ {
+ return (m_symName == rhs.m_symName && m_flDuration == rhs.m_flDuration && m_eTimingFunction == rhs.m_eTimingFunction &&
+ (m_eTimingFunction != k_EAnimationCustomBezier ||
+ (m_CubicBezier.ControlPoint( 0 ) == rhs.m_CubicBezier.ControlPoint( 0 ) &&
+ m_CubicBezier.ControlPoint( 1 ) == rhs.m_CubicBezier.ControlPoint( 1 ) &&
+ m_CubicBezier.ControlPoint( 2 ) == rhs.m_CubicBezier.ControlPoint( 2 ) &&
+ m_CubicBezier.ControlPoint( 3 ) == rhs.m_CubicBezier.ControlPoint( 3 )
+ )
+ ) &&
+ m_flIteration == rhs.m_flIteration && m_eAnimationDirection == rhs.m_eAnimationDirection && m_flDelay == rhs.m_flDelay);
+ }
+
+ bool operator!=(const AnimationProperty_t &rhs) const
+ {
+ return !(*this == rhs);
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Information on a property in the middle of a transition
+//-----------------------------------------------------------------------------
+class CActiveAnimation
+{
+public:
+ CActiveAnimation( float flAnimationStart, AnimationProperty_t &animationProperty );
+ ~CActiveAnimation();
+
+ CPanoramaSymbol GetName() const { return m_animationData.m_symName; }
+ const AnimationProperty_t &GetAnimationData() const { return m_animationData; }
+ void AddFrameData( float flPercent, EAnimationTimingFunction eTimingFunction, const CCubicBezierCurve<Vector2D> &cubicBezier, CStyleProperty *pProperty, float flUIScaleFactor );
+
+ bool BHasFrameDataForProperty( CStyleSymbol symStyleProperty );
+
+ double GetStartTime() const { return m_flAnimationStartTime; }
+ double GetStartTimeWithDelay() const { return m_flAnimationStartTime + m_animationData.m_flDelay; }
+ float CalculateAnimationEndTime() const;
+ void Reset();
+ void GetAffectedPanelLayoutFlags( CPanelStyle *pPanelStyle, bool *pbAffectsSize, bool *pbAffectsPosition );
+ bool BAffectsCompositionOnly();
+ bool BAffectsPanelLayoutFlags( CPanelStyle *pPanelStyle );
+
+ void UpdateUIScaleFactor( float flOldScaleFactor, float flNewScaleFactor );
+
+ // keyframe data
+ struct PropertyFrameData_t
+ {
+ float m_flPercent; // percent into animation when styles apply.
+ EAnimationTimingFunction m_eTimingFunction; // timing function can be overridden per keyframe
+ CCubicBezierCurve< Vector2D > m_CubicBezier;
+ CStyleProperty *m_pStyleProperty; // property to apply
+ };
+ typedef CUtlVector< PropertyFrameData_t > VecPropertyFrameData_t;
+ const VecPropertyFrameData_t *GetFrameData( CStyleSymbol symProperty );
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+private:
+ CActiveAnimation();
+ CActiveAnimation( const CActiveAnimation & );
+ CActiveAnimation &operator=(const CActiveAnimation &rhs);
+
+ AnimationProperty_t m_animationData;
+ double m_flAnimationStartTime;
+ CUtlMap< CStyleSymbol, VecPropertyFrameData_t *, short, CDefLess< CStyleSymbol > > m_mapFrameData;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents all components that can be included in an individual CSS selector
+//-----------------------------------------------------------------------------
+class CStyleSelector
+{
+public:
+ CStyleSelector()
+ {
+ m_pchID = NULL;
+ m_eStyleFlags = k_EStyleFlagNone;
+ m_unSelectorFlags = 0;
+ }
+
+ ~CStyleSelector()
+ {
+ ClearID();
+ }
+
+ void SetID( const char *pchID )
+ {
+ ClearID();
+ m_pchID = strdup( pchID );
+ }
+
+ void ClearID()
+ {
+ if( m_pchID )
+ {
+ free( (void*)m_pchID );
+ m_pchID = NULL;
+ }
+ }
+
+ const char *GetID() const { return m_pchID; }
+
+ void SetPanelType( CPanoramaSymbol symType ) { m_symPanelType = symType; }
+ CPanoramaSymbol GetPanelType() const { return m_symPanelType; }
+
+ void SetClasses( CPanoramaSymbol *pSymbols, int cSymbols ) { m_classes.Copy( pSymbols, cSymbols ); }
+ const CUtlPtrArray< CPanoramaSymbol > &GetClasses() const { return m_classes; }
+
+ void SetStyleFlags( EStyleFlags eFlags ) { m_eStyleFlags = eFlags; }
+ EStyleFlags GetStyleFlags() const { return m_eStyleFlags; }
+
+ // allows setting an ID w/o allocating for searching. Skips memory management
+ void SetIDForSearch( const char *pchID )
+ {
+ m_pchID = pchID;
+ }
+
+ // allows setting classes w/o allocationg for searching. Skips memory management
+ void SetClassesForSearch( CPanoramaSymbol *pSymbols, int cSymbols )
+ {
+ if( pSymbols )
+ m_classes.TakeOwnership( pSymbols, cSymbols );
+ else
+ m_classes.DetatchAndClear();
+ }
+
+ void SetChildMatchesNextStyle()
+ {
+ m_unSelectorFlags |= k_ESelectorFlagsChildCombinator;
+ }
+
+ bool BChildMatchesNextStyle() const
+ {
+ return ((m_unSelectorFlags & k_ESelectorFlagsChildCombinator) != 0);
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ validator.ClaimMemory( (void *)m_pchID );
+ ValidateObj( m_classes );
+ }
+#endif
+
+private:
+ enum ESelectorFlags
+ {
+ k_ESelectorFlagsNone = 0,
+ k_ESelectorFlagsChildCombinator = 1, // next selector must match child of panel that matched this style (.A > .B)
+ };
+
+ CStyleSelector( CStyleSelector const& ) { Assert( 0 ); }
+
+ // id is a char pointer instead of CUtlString so we can do searches w/o allocations
+ const char *m_pchID; // not empty if an ID is required
+ CPanoramaSymbol m_symPanelType; // if invalid, applies to all panels
+ CUtlPtrArray< CPanoramaSymbol > m_classes; // can be empty if id or panel type are set
+ EStyleFlags m_eStyleFlags; // required style flags
+ uint32 m_unSelectorFlags; // ESelectorFlags
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Base class for every style property, they all have a symbol for a name.
+//-----------------------------------------------------------------------------
+class CStyleProperty
+{
+public:
+ CStyleProperty( CStyleSymbol symPropertyName )
+ {
+ m_symPropertyName = symPropertyName;
+ m_bDisallowTransition = false;
+ }
+
+ virtual ~CStyleProperty() {}
+
+ bool operator < (const CStyleProperty &rhs) const
+ {
+ return m_symPropertyName < rhs.m_symPropertyName;
+ }
+
+ CStyleSymbol GetPropertySymbol() const { return m_symPropertyName; }
+
+ // Merges data to the target, this will only overwrite unset properties, and shouldn't clobber
+ // already set ones.
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( m_bDisallowTransition )
+ pTarget->m_bDisallowTransition = true;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() = 0;
+
+ // Interpolation func for animation of this property, must implement if you override BCanTransition to return true.
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) = 0;
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString ) = 0;
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const = 0;
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ // Example: For margin, if we have only seen margin-length, should return false until top, bottom, right are set
+ virtual bool BFullySet() { return true; }
+
+ // called when applied to a panel before comparing with set values. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues() {}
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor ) {}
+
+ // called when applied to a panel after comparing with set values
+ virtual void OnAppliedToPanel( IUIPanel *pPanel ) {}
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty ) { return "&lt;Needs a description&gt;"; }
+
+ // Does this property only affecting compositing when rendering, or does it affect drawing within the composition
+ // layer for the panel it is applied to?
+ virtual bool BAffectsCompositionOnly() { return false; }
+
+ // Get suggested values based on current text for style property value
+ virtual void GetSuggestedValues( CStyleSymbol symAlias, const char *pchTextSoFar, CUtlVector< CUtlString > &vecSuggestions ) { }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &rhs) const = 0;
+ bool operator!=(const CStyleProperty &rhs) const { return !(*this == rhs); }
+
+ // What layout attributes can be invalidated when the property is applied to a panel (compared to prior value)
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const = 0;
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ inline bool BInvalidatesSizeAndPosition( CStyleProperty *pCompareProperty ) const { return (GetInvalidateLayout( pCompareProperty ) == k_EStyleInvalidateLayoutSizeAndPosition); }
+ inline bool BInvalidatesPosition( CStyleProperty *pCompareProperty ) const { return (GetInvalidateLayout( pCompareProperty ) == k_EStyleInvalidateLayoutPosition); }
+
+ // If the style supports transition (BCanTransition), it may still be that this style instance disables transition and forces immediate apply, this controls that
+ void SetDisallowTransition( bool bDisallowTransition ) { m_bDisallowTransition = bDisallowTransition; }
+
+ // If the style supports transition (BCanTransition), it may still be that this style instance disables transition and forces immediate apply, this checks that
+ bool BDisallowTransition() { return m_bDisallowTransition; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+ // CLANG requires delete to be visible to derived classes even if new is not
+protected:
+#if !defined( SOURCE2_PANORAMA )
+#include "tier0/memdbgoff.h"
+#endif
+ void *operator new(size_t size) throw(){ return NULL; }
+ void *operator new(size_t size, int nBlockUse, const char *pFileName, int nLine) throw(){ return NULL; }
+ void operator delete(void* p) { Assert( false ); }
+ void operator delete(void* p, int nBlockUse, const char *pFileName, int nLine) { Assert( false ); }
+#if !defined( SOURCE2_PANORAMA )
+#include "tier0/memdbgon.h"
+#endif
+
+
+private:
+ CStyleSymbol m_symPropertyName;
+ bool m_bDisallowTransition;
+};
+
+
+typedef CUtlHashMap< panorama::CStyleSymbol, panorama::CStyleProperty *, CDefEquals< panorama::CStyleSymbol > > StylePropertyHash_t;
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a style's properties and position in a file
+//-----------------------------------------------------------------------------
+struct StyleFromFile_t
+{
+ StyleFromFile_t()
+ {
+ m_pProperties = NULL;
+ m_unFileLocation = 0;
+ m_pNext = NULL;
+ }
+
+ ~StyleFromFile_t()
+ {
+ if( m_pProperties )
+ {
+ FOR_EACH_RBTREE_FAST( *m_pProperties, i )
+ {
+ UIEngine()->UIStyleFactory()->FreeStyleProperty( m_pProperties->Element( i ) );
+ }
+
+ SAFE_DELETE( m_pProperties );
+ }
+
+ SAFE_DELETE( m_pNext );
+ }
+
+ const CStyleProperty *GetProperty( CStyleSymbol symProperty ) const
+ {
+ if( !m_pProperties )
+ return NULL;
+
+ short i = m_pProperties->Find( symProperty );
+ if( i == m_pProperties->InvalidIndex() )
+ return NULL;
+
+ return m_pProperties->Element( i );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_selector );
+
+ ValidateObj( m_parentSelectors );
+ FOR_EACH_PTR_ARRAY( m_parentSelectors, i )
+ {
+ ValidateObj( m_parentSelectors[i] );
+ }
+
+ ValidatePtr( m_pProperties );
+
+ // Don't validate individual properties, they are pooled and we validate the pools elsewhere. Do have
+ // them validate their own members.
+ FOR_EACH_MAP_FAST( *m_pProperties, i )
+ {
+ m_pProperties->Element( i )->Validate( validator, "CStyleProperty" );
+ }
+
+
+ if( m_pNext )
+ ValidatePtr( m_pNext );
+ }
+#endif
+
+ CStyleSelector m_selector; // selector for this element
+ CUtlPtrArray< CStyleSelector > m_parentSelectors; // selectors for parents, ordered farthest to our closest parent
+
+ StylePropertyHash_t *m_pProperties; // list of parsed properties
+ uint m_unFileLocation; // style offset into the file (Nth style, higher value means defined later and takes priority when determining
+ // cascading order (CSS2 TR 6.4.1)
+
+ StyleFromFile_t *m_pNext; // allows chaining of objects with the same same symbol in CStyleFile
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents a single keyframe
+//-----------------------------------------------------------------------------
+class CStyleKeyFrame
+{
+public:
+ CStyleKeyFrame( float flPercent, EAnimationTimingFunction eTimingFunc, const CCubicBezierCurve<Vector2D> &cubicBezier, StylePropertyHash_t *pProperties )
+ {
+ m_flPercent = flPercent;
+ m_eTimingFunction = eTimingFunc;
+ m_CubicBezier = cubicBezier;
+ m_pProperties = pProperties;
+ }
+
+ ~CStyleKeyFrame()
+ {
+ if( m_pProperties )
+ {
+ FOR_EACH_HASHMAP( *m_pProperties, i )
+ {
+ CStyleProperty *pProperty = m_pProperties->Element( i );
+ if( pProperty )
+ UIEngine()->UIStyleFactory()->FreeStyleProperty( pProperty );
+ }
+
+ SAFE_DELETE( m_pProperties );
+ }
+ }
+
+ float GetPercent() const { return m_flPercent; }
+ EAnimationTimingFunction GetTimingFunction() const { return m_eTimingFunction; }
+ const CCubicBezierCurve< Vector2D >& GetCubicBezier() const { return m_CubicBezier; }
+ StylePropertyHash_t *GetProperties() const { return m_pProperties; }
+
+ // ordered by percent
+ bool operator<(const CStyleKeyFrame &rhs) const { return m_flPercent < rhs.m_flPercent; }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+
+ ValidatePtr( m_pProperties );
+
+ // Don't validate each individual property, they are pooled and the pool is validated elsewhere
+ FOR_EACH_MAP_FAST( *m_pProperties, i )
+ {
+ (*m_pProperties)[i]->Validate( validator, "CStyleProperty" );
+ }
+ }
+#endif
+
+private:
+ CStyleKeyFrame();
+ CStyleKeyFrame( const CStyleKeyFrame &rhs );
+ CStyleKeyFrame& operator=(const CStyleKeyFrame &rhs) const;
+
+ float m_flPercent;
+ EAnimationTimingFunction m_eTimingFunction; // each keyframe can override the timing funciton
+ CCubicBezierCurve<Vector2D> m_CubicBezier;
+ StylePropertyHash_t *m_pProperties;
+};
+
+typedef CStyleKeyFrame* CStyleKeyFramePtr;
+bool StyleKeyFrameLessPtr( const CStyleKeyFramePtr &lhs, const CStyleKeyFramePtr &rhs, void *pCtx );
+#if defined( SOURCE2_PANORAMA )
+class CUtlSortVectorCStyleKeyFramePtrLess
+{
+public:
+ bool Less( const CStyleKeyFramePtr& lhs, const CStyleKeyFramePtr& rhs, void * )
+ {
+ return *lhs < *rhs;
+ }
+};
+
+typedef CUtlSortVector< CStyleKeyFrame*, CUtlSortVectorCStyleKeyFramePtrLess > VecKeyFrames_t;
+#else
+typedef CUtlSortVector< CStyleKeyFrame* > VecKeyFrames_t;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Represents an animation
+//-----------------------------------------------------------------------------
+class CStyleAnimation
+{
+public:
+ CStyleAnimation( CPanoramaSymbol symName, CPanoramaSymbol symStyleFile, uint unFileLocation )
+#if !defined( SOURCE2_PANORAMA )
+: m_vecKeyFrames( StyleKeyFrameLessPtr )
+#endif
+ {
+ m_symName = symName;
+ m_symStyleFile = symStyleFile;
+ m_unFileLocation = unFileLocation;
+ }
+
+ ~CStyleAnimation()
+ {
+ ClearFrames();
+ }
+
+ void ClearFrames()
+ {
+ m_vecKeyFrames.PurgeAndDeleteElements();
+ }
+
+ void InsertFrame( CStyleKeyFrame *pFrame )
+ {
+ int iVec = m_vecKeyFrames.Find( pFrame );
+ if( iVec != m_vecKeyFrames.InvalidIndex() )
+ {
+ delete m_vecKeyFrames.Element( iVec );
+ m_vecKeyFrames.Remove( iVec );
+ }
+
+ m_vecKeyFrames.Insert( pFrame );
+ }
+
+ CPanoramaSymbol GetName() const { return m_symName; }
+ CPanoramaSymbol GetStyleFile() const { return m_symStyleFile; }
+ uint GetFileLocation() const { return m_unFileLocation; }
+ const VecKeyFrames_t &GetFrames() const { return m_vecKeyFrames; }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+
+ ValidateObj( m_vecKeyFrames );
+ FOR_EACH_VEC( m_vecKeyFrames, i )
+ {
+ ValidatePtr( m_vecKeyFrames[i] );
+ }
+ }
+#endif
+
+private:
+ CStyleAnimation();
+ CStyleAnimation( const CStyleAnimation &rhs );
+ CStyleAnimation& operator=(const CStyleAnimation &rhs) const;
+
+ CPanoramaSymbol m_symName; // name of animation
+ CPanoramaSymbol m_symStyleFile; // path to style file this animation was created from
+ uint m_unFileLocation; // location within style file for this animation
+ VecKeyFrames_t m_vecKeyFrames; // frames for animation
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Position property
+//-----------------------------------------------------------------------------
+class CStylePropertyPosition : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol symbolX;
+ static const CStyleSymbol symbolY;
+ static const CStyleSymbol symbolZ;
+
+ CStylePropertyPosition() : CStyleProperty( CStylePropertyPosition::symbol )
+ {
+
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyPosition::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyPosition *p = (CStylePropertyPosition *)pTarget;
+
+ if( !p->x.IsSet() )
+ p->x = x;
+
+ if( !p->y.IsSet() )
+ p->y = y;
+
+ if( !p->z.IsSet() )
+ p->z = z;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = false;
+ if( symParsedName == symbol )
+ {
+ bSuccess = CSSHelpers::BParseIntoUILength( &x, pchString, &pchString ) &&
+ CSSHelpers::BParseIntoUILength( &y, pchString, &pchString ) &&
+ CSSHelpers::BParseIntoUILength( &z, pchString, &pchString );
+ }
+ else if( symParsedName == symbolX )
+ {
+ bSuccess = CSSHelpers::BParseIntoUILength( &x, pchString, &pchString );
+ }
+ else if( symParsedName == symbolY )
+ {
+ bSuccess = CSSHelpers::BParseIntoUILength( &y, pchString, &pchString );
+ }
+ else if( symParsedName == symbolZ )
+ {
+ bSuccess = CSSHelpers::BParseIntoUILength( &z, pchString, &pchString );
+ }
+
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ x.ScaleLengthValue( flScaleFactor );
+ y.ScaleLengthValue( flScaleFactor );
+ z.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, x );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, y );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, z );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return (x.IsSet() && y.IsSet() && z.IsSet());
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ if( !x.IsSet() )
+ x.SetLength( 0.0f );
+
+ if( !y.IsSet() )
+ y.SetLength( 0.0f );
+
+ if( !z.IsSet() )
+ z.SetLength( 0.0f );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the x, y, z position for a panel. Must not be in a flowing layout.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "position: 3% 20px 0px;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyPosition &rhs = (const CStylePropertyPosition&)other;
+ return (x == rhs.x && y == rhs.y && z == rhs.z);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUILength x, y, z;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: PerspectiveOrigin property
+//-----------------------------------------------------------------------------
+class CStylePropertyTransformOrigin : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline void GetDefault( CUILength *x, CUILength *y, bool *pbParent )
+ {
+ x->SetPercent( 50 );
+ y->SetPercent( 50 );
+ *pbParent = false;
+ }
+
+ CStylePropertyTransformOrigin() : CStyleProperty( CStylePropertyTransformOrigin::symbol )
+ {
+ GetDefault( &x, &y, &m_bParentRelative );
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTransformOrigin::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyTransformOrigin *p = (CStylePropertyTransformOrigin *)pTarget;
+ p->x = x;
+ p->y = y;
+ p->m_bParentRelative = m_bParentRelative;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = (CSSHelpers::BParseIntoUILength( &x, pchString, &pchString ) && CSSHelpers::BParseIntoUILength( &y, pchString, &pchString ));
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if( V_strnicmp( pchString, "parent-relative", V_strlen( "parent-relative" ) ) == 0 )
+ m_bParentRelative = true;
+ else if( V_strlen( pchString ) > 0 )
+ return false;
+
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ x.ScaleLengthValue( flScaleFactor );
+ y.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, x );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, y );
+ if( m_bParentRelative )
+ pfmtBuffer->Append( " parent-relative" );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the transform origin about which transforms will be applied. Default is 50% 50% on the panel so a rotation/scale is centered.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "transform-origin: 50% 50%"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTransformOrigin &rhs = (const CStylePropertyTransformOrigin&)other;
+ return (x == rhs.x && y == rhs.y && m_bParentRelative == rhs.m_bParentRelative);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ CUILength x;
+ CUILength y;
+ bool m_bParentRelative;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: PerspectiveOrigin property
+//-----------------------------------------------------------------------------
+class CStylePropertyPerspectiveOrigin : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline void GetDefault( CUILength *x, CUILength *y, bool *pbInvert )
+ {
+ x->SetPercent( 50 );
+ y->SetPercent( 50 );
+ *pbInvert = false;
+ }
+
+ CStylePropertyPerspectiveOrigin() : CStyleProperty( CStylePropertyPerspectiveOrigin::symbol )
+ {
+ GetDefault( &x, &y, &m_bInvert );
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyPerspectiveOrigin::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyPerspectiveOrigin *p = (CStylePropertyPerspectiveOrigin *)pTarget;
+ p->x = x;
+ p->y = y;
+ p->m_bInvert = m_bInvert;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = (CSSHelpers::BParseIntoUILength( &x, pchString, &pchString ) && CSSHelpers::BParseIntoUILength( &y, pchString, &pchString ));
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if( V_strnicmp( pchString, "invert", V_strlen( "invert" ) ) == 0 )
+ m_bInvert = true;
+ else if( V_strlen( pchString ) > 0 )
+ return false;
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ x.ScaleLengthValue( flScaleFactor );
+ y.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Handle getting applied to a panel
+ virtual void OnAppliedToPanel( IUIPanel *pPanel )
+ {
+
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, x );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, y );
+ if( m_bInvert )
+ pfmtBuffer->Append( " invert" );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the perspective origin which will be used when transforming children of this panel. This can be "
+ "thought of as the camera x/y position relative to the panel.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "perspective-origin: 50% 50%;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyPerspectiveOrigin &rhs = (const CStylePropertyPerspectiveOrigin&)other;
+ return (x == rhs.x && y == rhs.y && m_bInvert == rhs.m_bInvert);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ bool m_bInvert;
+ CUILength x;
+ CUILength y;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Perspective property
+//-----------------------------------------------------------------------------
+class CStylePropertyPerspective : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline float GetDefault() { return 1000.0f; }
+
+ CStylePropertyPerspective() : CStyleProperty( CStylePropertyPerspective::symbol )
+ {
+ perspective = GetDefault();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyPerspective::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyPerspective *p = (CStylePropertyPerspective *)pTarget;
+ p->perspective = perspective;
+ }
+
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ perspective *= flScaleFactor;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ if( target.GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyPerspective::Interpolate" );
+ return;
+ }
+
+ const CStylePropertyPerspective *p = (const CStylePropertyPerspective *)&target;
+ perspective = perspective + (p->perspective - perspective) * flProgress;
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( !CSSHelpers::BParseNumber( &perspective, pchString ) )
+ {
+ return CSSHelpers::BParseLength( &perspective, pchString );
+ }
+ return true;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendFloat( pfmtBuffer, perspective );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the perspective depth space available for children of the panel. Default of 1000 would mean that "
+ "children at 1000px zpos are right at the viewers eye, -1000px are just out of view distance faded to nothing.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "perspective: 1000;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyPerspective &rhs = (const CStylePropertyPerspective&)other;
+ return (perspective == rhs.perspective);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ float perspective;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: z-index, this determines z sorting within panels that are peers with indentical actual zpos
+//-----------------------------------------------------------------------------
+class CStylePropertyZIndex : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline float GetDefault() { return 0.0f; }
+
+ CStylePropertyZIndex() : CStyleProperty( CStylePropertyZIndex::symbol )
+ {
+ zindex = GetDefault();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyZIndex::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyZIndex *p = (CStylePropertyZIndex *)pTarget;
+ p->zindex = zindex;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ if( target.GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyZIndex::Interpolate" );
+ return;
+ }
+
+ const CStylePropertyZIndex *p = (const CStylePropertyZIndex *)&target;
+ zindex = zindex + (p->zindex - zindex) * flProgress;
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( !CSSHelpers::BParseNumber( &zindex, pchString ) )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendFloat( pfmtBuffer, zindex );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the z-index for a panel, panels will be sorted and painted in order within a parent panel. The sorting "
+ "first sorts by the z-pos computed from position and transforms, then if panels have matching zpos zindex is used. "
+ "z-index is different than z-pos in that it doesn't affect rendering perspective, just paint/hit-test ordering. "
+ "The default z-index value is 0, and any floating point value is accepted.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "z-index: 1;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyZIndex &rhs = (const CStylePropertyZIndex&)other;
+ return (zindex == rhs.zindex);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ float zindex;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Perspective property
+//-----------------------------------------------------------------------------
+class CStylePropertyOpacity : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline float GetDefault() { return 1.0f; }
+
+ CStylePropertyOpacity() : CStyleProperty( CStylePropertyOpacity::symbol )
+ {
+ opacity = GetDefault();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyOpacity::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyOpacity *p = (CStylePropertyOpacity *)pTarget;
+ p->opacity = opacity;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ if( target.GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyOpacity::Interpolate" );
+ return;
+ }
+
+ const CStylePropertyOpacity *p = (const CStylePropertyOpacity *)&target;
+ opacity = opacity + (p->opacity - opacity) * flProgress;
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ return (CSSHelpers::BParseNumber( &opacity, pchString, &pchString ));
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendFloat( pfmtBuffer, opacity );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the opacity or amount of transparency applied to the panel and all it's children during composition. "
+ "Default of 1.0 means fully opaque, 0.0 means fully transparent.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "opacity: 0.8;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyOpacity &rhs = (const CStylePropertyOpacity&)other;
+ return (opacity == rhs.opacity);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ float opacity;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: scale-2d-centered property
+//-----------------------------------------------------------------------------
+class CStylePropertyScale2DCentered : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline float GetDefaultX() { return 1.0f; }
+ static inline float GetDefaultY() { return 1.0f; }
+
+ CStylePropertyScale2DCentered() : CStyleProperty( CStylePropertyScale2DCentered::symbol )
+ {
+ m_flX = GetDefaultX();
+ m_flY = GetDefaultY();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyScale2DCentered::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyScale2DCentered *p = (CStylePropertyScale2DCentered *)pTarget;
+ p->m_flX = m_flX;
+ p->m_flY = m_flY;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ if( target.GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyScale2DCentered::Interpolate" );
+ return;
+ }
+
+ const CStylePropertyScale2DCentered *p = (const CStylePropertyScale2DCentered *)&target;
+ m_flX = m_flX + (p->m_flX - m_flX) * flProgress;
+ m_flY = m_flY + (p->m_flY - m_flY) * flProgress;
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ // should be "x, y"
+ CUtlVector< float > vecValues;
+ if( !CSSHelpers::BParseCommaSepList( &vecValues, CSSHelpers::BParseNumber, pchString ) )
+ return false;
+ if( vecValues.Count() < 1 || vecValues.Count() > 2 )
+ return false;
+
+ if( vecValues.Count() == 2 )
+ {
+ m_flX = vecValues[0];
+ m_flY = vecValues[1];
+ }
+ else if( vecValues.Count() == 1 )
+ {
+ m_flX = m_flY = vecValues[0];
+ }
+
+ return true;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendFloat( pfmtBuffer, m_flX );
+ pfmtBuffer->Append( ", " );
+ CSSHelpers::AppendFloat( pfmtBuffer, m_flY );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets 2 dimensional X/Y scale factors that apply to the quad for this panel prior to 3 dimensional transforms. "
+ "This scaling applies without perspective and leaves the panel centered at the same spot as it started. "
+ "Default of 1.0 means no scaling, 0.5 would be half size.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "pre-transform-scale2d: 0.8\n"
+ "pre-transform-scale2d: 0.4, 0.6"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyScale2DCentered &rhs = (const CStylePropertyScale2DCentered&)other;
+ return (m_flX == rhs.m_flX && m_flY == rhs.m_flY);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ float m_flX, m_flY;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: pre-transform-rotate2d property
+//-----------------------------------------------------------------------------
+class CStylePropertyRotate2DCentered : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline float GetDefault() { return 0.0f; }
+
+ CStylePropertyRotate2DCentered() : CStyleProperty( CStylePropertyRotate2DCentered::symbol )
+ {
+ m_flDegrees = GetDefault();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyRotate2DCentered::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyRotate2DCentered *p = (CStylePropertyRotate2DCentered *)pTarget;
+ p->m_flDegrees = m_flDegrees;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ if( target.GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyScale2DCentered::Interpolate" );
+ return;
+ }
+
+ const CStylePropertyRotate2DCentered *p = (const CStylePropertyRotate2DCentered *)&target;
+ m_flDegrees = m_flDegrees + (p->m_flDegrees - m_flDegrees) * flProgress;
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ // should be "degrees"
+ CUtlVector< float > vecValues;
+ if( !CSSHelpers::BParseCommaSepList( &vecValues, CSSHelpers::BParseAngle, pchString ) )
+ return false;
+ if( vecValues.Count() < 1 || vecValues.Count() > 1 )
+ return false;
+
+ m_flDegrees = vecValues[0];
+
+ return true;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendFloat( pfmtBuffer, m_flDegrees );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets 2 dimensional rotation degrees that apply to the quad for this panel prior to 3 dimensional transforms. "
+ "This rotation applies without perspective and leaves the panel centered at the same spot as it started.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "pre-transform-rotate2d: 45deg;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyRotate2DCentered &rhs = (const CStylePropertyRotate2DCentered&)other;
+ return (m_flDegrees == rhs.m_flDegrees);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ float m_flDegrees;
+};
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Perspective property
+//-----------------------------------------------------------------------------
+class CStylePropertyDesaturation : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline double GetDefault() { return 0.0f; }
+
+ CStylePropertyDesaturation() : CStyleProperty( CStylePropertyDesaturation::symbol )
+ {
+ desaturation = GetDefault();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyDesaturation::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyDesaturation *p = (CStylePropertyDesaturation *)pTarget;
+ p->desaturation = desaturation;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ if( target.GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyDesaturation::Interpolate" );
+ return;
+ }
+
+ const CStylePropertyDesaturation *p = (const CStylePropertyDesaturation *)&target;
+ desaturation = desaturation + (p->desaturation - desaturation) * flProgress;
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( V_strnicmp( pchString, "none", V_strlen( "none" ) ) == 0 )
+ {
+ desaturation = 0.0f;
+ return true;
+ }
+
+ return (CSSHelpers::BParseNumber( &desaturation, pchString, &pchString ));
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendFloat( pfmtBuffer, desaturation );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the amount of desaturation to apply to the panel and all it's children during composition. "
+ "Default of 0.0 means no adjustment, 1.0 means fully desaturated to gray scale.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "desaturation: 0.6;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyDesaturation &rhs = (const CStylePropertyDesaturation&)other;
+ return (desaturation == rhs.desaturation);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ float desaturation;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Perspective property
+//-----------------------------------------------------------------------------
+class CStylePropertyBlur : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline double GetDefaultStdDev() { return 0.0f; }
+ static inline double GetDefaultPasses() { return 1.0f; }
+
+ CStylePropertyBlur() : CStyleProperty( CStylePropertyBlur::symbol )
+ {
+ stddevhor = GetDefaultStdDev();
+ stddevver = GetDefaultStdDev();
+ passes = GetDefaultPasses();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyBlur::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyBlur *p = (CStylePropertyBlur *)pTarget;
+ p->stddevhor = stddevhor;
+ p->stddevver = stddevver;
+ p->passes = passes;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ if( target.GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyBlur::Interpolate" );
+ return;
+ }
+
+ const CStylePropertyBlur *p = (const CStylePropertyBlur *)&target;
+ stddevhor = stddevhor + (p->stddevhor - stddevhor) * flProgress;
+ stddevver = stddevver + (p->stddevver - stddevver) * flProgress;
+ passes = passes + (p->passes - passes) * flProgress;
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( !CSSHelpers::BParseGaussianBlur( passes, stddevhor, stddevver, pchString, &pchString ) )
+ return false;
+
+ return true;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( stddevhor == 0.0f && stddevver == 0.0f && passes == 0.0f )
+ {
+ pfmtBuffer->Append( "none" );
+ }
+ else
+ {
+ pfmtBuffer->Append( "gaussian( " );
+ CSSHelpers::AppendFloat( pfmtBuffer, stddevhor );
+ pfmtBuffer->Append( ", " );
+ CSSHelpers::AppendFloat( pfmtBuffer, stddevver );
+ pfmtBuffer->Append( ", " );
+ CSSHelpers::AppendFloat( pfmtBuffer, passes );
+ pfmtBuffer->Append( ")" );
+ }
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the amount of blur to apply to the panel and all it's children during composition. "
+ "Default is no blur, for now Gaussian is the only blur type and takes a horizontal standard deviation, "
+ "vertical standard deviation, and number of passes. Good std deviation values are around 0-10, if 10 is "
+ "still not intense enough consider more passes, but more than one pass is bad for perf. As shorthand you can "
+ "specify with just one value, which will be used for the standard deviation in both directions and 1 pass "
+ "will be set.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "blur: gaussian( 2.5 );\n"
+ "blur: gaussian( 6, 6, 1 );"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyBlur &rhs = (const CStylePropertyBlur&)other;
+ return (stddevhor == rhs.stddevhor && stddevver == rhs.stddevver && passes == rhs.passes);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ float stddevhor;
+ float stddevver;
+ float passes;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Box shadow property
+//-----------------------------------------------------------------------------
+class CStylePropertyBoxShadow : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static Color GetDefaultShadowColor() { return Color( 33, 33, 33, 80 ); }
+
+ CStylePropertyBoxShadow() : CStyleProperty( CStylePropertyBoxShadow::symbol )
+ {
+ m_bFill = false;
+ m_bInset = false;
+ m_ShadowColor = GetDefaultShadowColor();
+ m_HorizontalOffset.SetLength( 0 );
+ m_VerticalOffset.SetLength( 0 );
+ m_SpreadDistance.SetLength( 0 );
+ m_BlurRadius.SetLength( 0 );
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyBoxShadow::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyBoxShadow *p = (CStylePropertyBoxShadow *)pTarget;
+ p->m_bInset = m_bInset;
+ p->m_bFill = m_bFill;
+ p->m_HorizontalOffset = m_HorizontalOffset;
+ p->m_VerticalOffset = m_VerticalOffset;
+ p->m_SpreadDistance = m_SpreadDistance;
+ p->m_BlurRadius = m_BlurRadius;
+ p->m_ShadowColor = m_ShadowColor;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ // <shadow> = inset? && [ <length>{2,4} && <color>? ]
+ // Browsers let color/inset appear before or after lengths, we will too.
+
+ if( V_strnicmp( pchString, "none", V_strlen( "none" ) ) == 0 )
+ {
+ m_bInset = false;
+ m_BlurRadius.SetLength( 0.0f );
+ m_HorizontalOffset.SetLength( 0.0f );
+ m_VerticalOffset.SetLength( 0.0f );
+ m_ShadowColor.SetColor( 0, 0, 0, 0 );
+ m_SpreadDistance.SetLength( 0.0f );
+ return true;
+ }
+
+ bool bInsetParsed = false;
+ bool bColorParsed = false;
+ bool bLengthsParsed = false;
+ bool bFillParsed = false;
+ while( 1 )
+ {
+ pchString = CSSHelpers::SkipSpaces( pchString );
+
+ if( !bInsetParsed && V_strnicmp( pchString, "inset", V_strlen( "inset" ) ) == 0 )
+ {
+ pchString += V_strlen( "inset" );
+ bInsetParsed = true;
+ m_bInset = true;
+ continue;
+ }
+ if( !bFillParsed && V_strnicmp( pchString, "fill", V_strlen( "fill" ) ) == 0 )
+ {
+ pchString += V_strlen( "fill" );
+ bFillParsed = true;
+ m_bFill = true;
+ continue;
+ }
+ else if( !bColorParsed && CSSHelpers::BParseColor( &m_ShadowColor, pchString, &pchString ) )
+ {
+ bColorParsed = true;
+ continue;
+ }
+ else if( !bLengthsParsed )
+ {
+ bLengthsParsed = true;
+ if( !CSSHelpers::BParseIntoUILength( &m_HorizontalOffset, pchString, &pchString ) )
+ {
+ return false;
+ }
+
+ if( !CSSHelpers::BParseIntoUILength( &m_VerticalOffset, pchString, &pchString ) )
+ {
+ return false;
+ }
+
+ // These two are optional
+ CSSHelpers::BParseIntoUILength( &m_BlurRadius, pchString, &pchString );
+ CSSHelpers::BParseIntoUILength( &m_SpreadDistance, pchString, &pchString );
+ }
+ else
+ {
+ // Lengths are the only thing required, if we get here and have them, we are good.
+ if( bLengthsParsed )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ }
+ return true;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_HorizontalOffset.ScaleLengthValue( flScaleFactor );
+ m_VerticalOffset.ScaleLengthValue( flScaleFactor );
+
+ // Although this is a blur pixel radius in css terminology it's really a stddev for our gaussian blur internally,
+ // hence it should not scale.
+
+ //m_BlurRadius.ScaleLengthValue( flScaleFactor );
+ m_SpreadDistance.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( m_bInset )
+ pfmtBuffer->Append( "inset " );
+ if( m_bFill )
+ pfmtBuffer->Append( "fill " );
+
+ CSSHelpers::AppendUILength( pfmtBuffer, m_HorizontalOffset );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_VerticalOffset );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_BlurRadius );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_SpreadDistance );
+ pfmtBuffer->Append( " " );
+
+ CSSHelpers::AppendColor( pfmtBuffer, m_ShadowColor );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies outer shadows for boxes, or inset shadows/glows. The shadow shape will match the border box for the panel,"
+ "so use border-radius to affect rounding. Syntax takes optional 'inset', optional 'fill' then color, and then horizontal offset pixels, "
+ "vertical offset pixels, blur radius pixels, and spread distance in pixels. Inset means the shadow is an inner shadow/glow, fill is valid"
+ "only on outer shadows and means draw the shadow behind the entire box, not clipping it to outside the border area only.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "box-shadow: #ffffff80 4px 4px 8px 0px; // outer\n"
+ "box-shadow: fill #ffffff80 4px 4px 8px 0px; // outer, filled\n"
+ "box-shadow: inset #333333b0 0px 0px 8px 12px; // inner"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyBoxShadow &rhs = (const CStylePropertyBoxShadow&)other;
+ return (m_bFill == rhs.m_bFill && m_bInset == rhs.m_bInset && m_HorizontalOffset == rhs.m_HorizontalOffset &&
+ m_VerticalOffset == rhs.m_VerticalOffset && m_BlurRadius == rhs.m_BlurRadius && m_SpreadDistance == rhs.m_SpreadDistance &&
+ m_ShadowColor == rhs.m_ShadowColor);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ bool m_bFill;
+ bool m_bInset;
+ CUILength m_HorizontalOffset;
+ CUILength m_VerticalOffset;
+ CUILength m_BlurRadius;
+ CUILength m_SpreadDistance;
+ Color m_ShadowColor;
+
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Text shadow property
+//-----------------------------------------------------------------------------
+class CStylePropertyTextShadow : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static Color GetDefaultShadowColor() { return Color( 33, 33, 33, 80 ); }
+
+ CStylePropertyTextShadow() : CStyleProperty( CStylePropertyTextShadow::symbol )
+ {
+ m_ShadowColor = GetDefaultShadowColor();
+ m_HorizontalOffset.SetLength( 0 );
+ m_VerticalOffset.SetLength( 0 );
+ m_BlurRadius.SetLength( 0 );
+ m_flStrength = 1.0f;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if ( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTextShadow::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyTextShadow *p = (CStylePropertyTextShadow *)pTarget;
+ p->m_HorizontalOffset = m_HorizontalOffset;
+ p->m_VerticalOffset = m_VerticalOffset;
+ p->m_BlurRadius = m_BlurRadius;
+ p->m_ShadowColor = m_ShadowColor;
+ p->m_flStrength = m_flStrength;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if ( V_strnicmp( pchString, "none", V_strlen( "none" ) ) == 0 )
+ {
+ m_BlurRadius.SetLength( 0.0f );
+ m_flStrength = 1.0f;
+ m_HorizontalOffset.SetLength( 0.0f );
+ m_VerticalOffset.SetLength( 0.0f );
+ m_ShadowColor.SetColor( 0, 0, 0, 0 );
+ return true;
+ }
+
+ bool bColorParsed = false;
+ bool bLengthsParsed = false;
+ while ( 1 )
+ {
+ pchString = CSSHelpers::SkipSpaces( pchString );
+
+ if ( !bColorParsed && CSSHelpers::BParseColor( &m_ShadowColor, pchString, &pchString ) )
+ {
+ bColorParsed = true;
+ continue;
+ }
+ else if ( !bLengthsParsed )
+ {
+ bLengthsParsed = true;
+ if ( !CSSHelpers::BParseIntoUILength( &m_HorizontalOffset, pchString, &pchString ) )
+ {
+ return false;
+ }
+
+ if ( !CSSHelpers::BParseIntoUILength( &m_VerticalOffset, pchString, &pchString ) )
+ {
+ return false;
+ }
+
+ // These two are optional
+ CSSHelpers::BParseIntoUILength( &m_BlurRadius, pchString, &pchString );
+ CSSHelpers::BParseNumber( &m_flStrength, pchString, &pchString );
+ }
+ else
+ {
+ // Lengths are the only thing required, if we get here and have them, we are good.
+ if ( bLengthsParsed )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ }
+ return true;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_HorizontalOffset.ScaleLengthValue( flScaleFactor );
+ m_VerticalOffset.ScaleLengthValue( flScaleFactor );
+
+ // Although this is a blur pixel radius in css terminology it's really a stddev for our gaussian blur internally,
+ // hence it should not scale.
+
+ //m_BlurRadius.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_HorizontalOffset );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_VerticalOffset );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_BlurRadius );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendFloat( pfmtBuffer, m_flStrength );
+ pfmtBuffer->Append( " " );
+
+ CSSHelpers::AppendColor( pfmtBuffer, m_ShadowColor );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies text shadows. The shadow shape will match the text the panel can generate,"
+ "and this is only meaningful for labels. Syntax takes horizontal offset pixels, "
+ "vertical offset pixels, blur radius pixels, strength, and then shadow color.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "text-shadow: 2px 2px 8px 3.0 #333333b0;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if ( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTextShadow &rhs = (const CStylePropertyTextShadow&)other;
+ return ( m_HorizontalOffset == rhs.m_HorizontalOffset &&
+ m_VerticalOffset == rhs.m_VerticalOffset &&
+ m_BlurRadius == rhs.m_BlurRadius &&
+ m_ShadowColor == rhs.m_ShadowColor &&
+ m_flStrength == rhs.m_flStrength );
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ CUILength m_HorizontalOffset;
+ CUILength m_VerticalOffset;
+ CUILength m_BlurRadius;
+ float m_flStrength;
+ Color m_ShadowColor;
+};
+
+
+class CStylePropertyClip : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+
+ CStylePropertyClip() : CStyleProperty( CStylePropertyClip::symbol )
+ {
+
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyClip::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyClip *p = (CStylePropertyClip *)pTarget;
+
+ if ( !p->m_Left.IsSet() )
+ p->m_Left = m_Left;
+ if( !p->m_Top.IsSet() )
+ p->m_Top = m_Top;
+ if( !p->m_Right.IsSet() )
+ p->m_Right = m_Right;
+ if( !p->m_Bottom.IsSet() )
+ p->m_Bottom = m_Bottom;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( V_strnicmp( pchString, "none", V_strlen( "none" ) ) == 0 )
+ {
+ return true;
+ }
+
+ return CSSHelpers::BParseRect( &m_Top, &m_Right, &m_Bottom, &m_Left, pchString );
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_Left.ScaleLengthValue( flScaleFactor );
+ m_Top.ScaleLengthValue( flScaleFactor );
+ m_Right.ScaleLengthValue( flScaleFactor );
+ m_Bottom.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ pfmtBuffer->Append( "rect( " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_Top );
+ pfmtBuffer->Append( ", " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_Right );
+ pfmtBuffer->Append( ", " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_Bottom );
+ pfmtBuffer->Append( ", " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_Left );
+ pfmtBuffer->Append( ")" );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies a clip region within the panel, where contents will be clipped at render time. "
+ "This clipping has no impact on layout, and is fast and supported for transitions/animations.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "clip: rect( 10%, 90%, 90%, 10% );"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyClip &rhs = (const CStylePropertyClip&)other;
+ return (m_Left == rhs.m_Left &&
+ m_Right == rhs.m_Right &&
+ m_Top == rhs.m_Top &&
+ m_Bottom == rhs.m_Bottom );
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ if( !m_Left.IsSet() )
+ m_Left.SetPercent( 0 );
+
+ if( !m_Top.IsSet() )
+ m_Top.SetPercent( 0 );
+
+ if( !m_Right.IsSet() )
+ m_Right.SetPercent( 100 );
+
+ if( !m_Bottom.IsSet() )
+ m_Bottom.SetPercent( 100 );
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ CUILength m_Left;
+ CUILength m_Top;
+ CUILength m_Right;
+ CUILength m_Bottom;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: color wash property, applies basically like drawing the color over
+// the top of the panel after all child rendering is complete, alpha value affects
+// how much of the child drawing colors come through.
+//-----------------------------------------------------------------------------
+class CStylePropertyWashColor : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline Color GetDefault() { return Color( 255, 255, 255, 255 ); }
+
+ CStylePropertyWashColor() : CStyleProperty( CStylePropertyWashColor::symbol )
+ {
+ m_color = GetDefault();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyWashColor::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyWashColor *p = (CStylePropertyWashColor *)pTarget;
+ p->m_color = m_color;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ if( target.GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyWashColor::Interpolate" );
+ return;
+ }
+
+ const CStylePropertyWashColor *p = (const CStylePropertyWashColor *)&target;
+ int r = m_color.r() + (p->m_color.r() - m_color.r()) * flProgress;
+ int b = m_color.b() + (p->m_color.b() - m_color.b()) * flProgress;
+ int g = m_color.g() + (p->m_color.g() - m_color.g()) * flProgress;
+ int a = m_color.a() + (p->m_color.a() - m_color.a()) * flProgress;
+
+ m_color.SetColor( r, g, b, a );
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( CSSHelpers::BParseColor( &m_color, pchString ) )
+ {
+ return true;
+ }
+ else if( V_stricmp( "transparent", pchString ) == 0 )
+ {
+ m_color.SetColor( 0, 0, 0, 0 );
+ return true;
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendColor( pfmtBuffer, m_color );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies a 'wash' color, which means a color that will be blended over the panel and all it's children at "
+ "composition time, tinting them. The alpha value of the color determines the intensity of the tinting.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "wash-color: #39b0d325;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyWashColor &rhs = (const CStylePropertyWashColor&)other;
+ return (m_color == rhs.m_color);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ Color m_color;
+};
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Overflow property
+//-----------------------------------------------------------------------------
+class CStylePropertyOverflow : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyOverflow() : CStyleProperty( CStylePropertyOverflow::symbol )
+ {
+ m_eHorizontal = k_EOverflowSquish;
+ m_eVertical = k_EOverflowSquish;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyOverflow::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyOverflow *p = (CStylePropertyOverflow *)pTarget;
+ p->m_eHorizontal = m_eHorizontal;
+ p->m_eVertical = m_eVertical;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( !BParseOverflow( &m_eHorizontal, pchString, &pchString ) )
+ return false;
+
+ // only 1 value specified?
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if( pchString[0] == '\0' )
+ {
+ m_eVertical = m_eHorizontal;
+ return true;
+ }
+
+ // get vertical
+ if( !BParseOverflow( &m_eVertical, pchString, &pchString ) )
+ return false;
+
+ return true;
+ }
+
+ bool BParseOverflow( EOverflowValue *peOverflow, const char *pchString, const char **pchAfterParse = NULL )
+ {
+ char rgchProperty[128];
+ if( !CSSHelpers::BParseIdent( rgchProperty, V_ARRAYSIZE( rgchProperty ), pchString, &pchString ) )
+ return false;
+
+ // special case none
+ if( V_stricmp( rgchProperty, "squish" ) == 0 )
+ *peOverflow = k_EOverflowSquish;
+ else if( V_stricmp( rgchProperty, "clip" ) == 0 )
+ *peOverflow = k_EOverflowClip;
+ else if( V_stricmp( rgchProperty, "scroll" ) == 0 )
+ *peOverflow = k_EOverflowScroll;
+ else if( V_stricmp( rgchProperty, "noclip" ) == 0 )
+ *peOverflow = k_EOverflowNoClip;
+ else
+ return false;
+
+ if( pchAfterParse )
+ *pchAfterParse = pchString;
+
+ return true;
+ }
+
+ void BAppendOverflow( CFmtStr1024 *pfmtBuffer, const EOverflowValue &eOverflow ) const
+ {
+ if( eOverflow == k_EOverflowSquish )
+ pfmtBuffer->Append( "squish" );
+ else if( eOverflow == k_EOverflowClip )
+ pfmtBuffer->Append( "clip" );
+ else if( eOverflow == k_EOverflowScroll )
+ pfmtBuffer->Append( "scroll" );
+ else if( eOverflow == k_EOverflowNoClip )
+ pfmtBuffer->Append( "noclip" );
+ else
+ AssertMsg1( false, "Unknown overflow value: %d", eOverflow );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ BAppendOverflow( pfmtBuffer, m_eHorizontal );
+ pfmtBuffer->Append( " " );
+ BAppendOverflow( pfmtBuffer, m_eVertical );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies what to do with contents that overflow the available space for the panel. "
+ "Possible values:<br>"
+ "\"squish\" - Children are squished to fit within the panel's bounds if needed (default)<br>"
+ "\"clip\" - Children maintain their desired size but their contents are clipped<br>"
+ "\"scroll\" - Children maintain their desired size and a scrollbar is added to this panel<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "overflow: squish squish; // squishes contents in horizontal and vertical directions\n"
+ "overflow: squish scroll; // scrolls contents in the Y direction"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyOverflow &rhs = (const CStylePropertyOverflow&)other;
+ return (m_eHorizontal == rhs.m_eHorizontal && m_eVertical == rhs.m_eVertical);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ EOverflowValue m_eHorizontal;
+ EOverflowValue m_eVertical;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Font property
+//-----------------------------------------------------------------------------
+class CStylePropertyFont : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol fontFamily;
+ static const CStyleSymbol fontSize;
+ static const CStyleSymbol fontStyle;
+ static const CStyleSymbol fontWeight;
+
+ CStylePropertyFont() : CStyleProperty( CStylePropertyFont::symbol )
+ {
+ m_flFontSize = k_flFloatNotSet;
+ m_eFontStyle = k_EFontStyleUnset;
+ m_eFontWeight = k_EFontWeightUnset;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyFont::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyFont *p = (CStylePropertyFont *)pTarget;
+ if( p->m_strFontFamily.IsEmpty() )
+ p->m_strFontFamily = m_strFontFamily;
+
+ if( p->m_flFontSize == k_flFloatNotSet )
+ p->m_flFontSize = m_flFontSize;
+
+ if( p->m_eFontStyle == k_EFontStyleUnset )
+ p->m_eFontStyle = m_eFontStyle;
+
+ if( p->m_eFontWeight == k_EFontWeightUnset )
+ p->m_eFontWeight = m_eFontWeight;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { Assert( !"You can't interpolate a font" ); }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == fontSize )
+ {
+ bool bSuccess = false;
+ if( !CSSHelpers::BParseNumber( &m_flFontSize, pchString ) )
+ {
+ if( CSSHelpers::BParseLength( &m_flFontSize, pchString ) )
+ {
+ bSuccess = true;
+ }
+ }
+ else
+ {
+ bSuccess = true;
+ }
+
+ return bSuccess;
+ }
+ else if( symParsedName == fontFamily )
+ {
+ char rgchFontFamily[512] = "";
+
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ CSSHelpers::BSkipQuote( pchString, &pchString );
+ V_strncpy( rgchFontFamily, pchString, V_ARRAYSIZE( rgchFontFamily ) );
+ int len = V_strlen( rgchFontFamily );
+ if( len > 1 )
+ {
+ if( rgchFontFamily[len - 1] == '\'' || rgchFontFamily[len - 1] == '"' )
+ rgchFontFamily[len - 1] = 0;
+ }
+ V_StrTrim( rgchFontFamily );
+
+ m_strFontFamily = rgchFontFamily;
+ return !m_strFontFamily.IsEmpty();
+ }
+ else if( symParsedName == fontWeight )
+ {
+ if( V_stristr( pchString, "normal" ) )
+ m_eFontWeight = k_EFontWeightNormal;
+ else if( V_stristr( pchString, "medium" ) )
+ m_eFontWeight = k_EFontWeightMedium;
+ else if( V_stristr( pchString, "bold" ) )
+ m_eFontWeight = k_EFontWeightBold;
+ else if( V_stristr( pchString, "black" ) )
+ m_eFontWeight = k_EFontWeightBlack;
+ else if( V_stristr( pchString, "thin" ) )
+ m_eFontWeight = k_EFontWeightThin;
+ else if ( V_stristr( pchString, "light" ) )
+ m_eFontWeight = k_EFontWeightLight;
+ else if ( V_stristr( pchString, "semi-bold" ) )
+ m_eFontWeight = k_EFontWeightSemiBold;
+
+ if( m_eFontWeight != k_EFontWeightUnset )
+ return true;
+ }
+ else if( symParsedName == fontStyle )
+ {
+ if( V_stristr( pchString, "normal" ) )
+ m_eFontStyle = k_EFontStyleNormal;
+ else if( V_stristr( pchString, "italic" ) )
+ m_eFontStyle = k_EFontStyleItalic;
+
+ if( m_eFontStyle != k_EFontStyleUnset )
+ return true;
+ }
+
+ return false;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ if( m_flFontSize != k_flFloatNotSet )
+ m_flFontSize *= flScaleFactor;
+ }
+
+ // Get suggested values based on current text for style property value
+ virtual void GetSuggestedValues( CStyleSymbol symAlias, const char *pchTextSoFar, CUtlVector< CUtlString > &vecSuggestions )
+ {
+ if( symAlias == fontFamily )
+ {
+ if( pchTextSoFar[0] == '"' )
+ ++pchTextSoFar;
+
+ int cchText = V_strlen( pchTextSoFar );
+ if( cchText > 0 && pchTextSoFar[cchText - 1] == '"' )
+ --cchText;
+
+ const CUtlSortVector< CUtlString > &vecValues = UIEngine()->GetSortedValidFontNames();
+ int iVec = vecValues.FindLessOrEqual( pchTextSoFar );
+ if( iVec == vecValues.InvalidIndex() )
+ iVec = 0;
+
+ while( vecValues.IsValidIndex( iVec ) )
+ {
+ const char *pchValue = vecValues[iVec].String();
+
+ if( cchText > 0 )
+ {
+ int nCmp = V_strncmp( pchValue, pchTextSoFar, cchText );
+ if( nCmp > 0 )
+ break;
+
+ // if less than, keep going
+ if( nCmp < 0 )
+ {
+ iVec++;
+ continue;
+ }
+ }
+
+ CFmtStr1024 strValue( "\"%s\"", vecValues[iVec].String() );
+ vecSuggestions.AddToTail( strValue.String() );
+ iVec++;
+ }
+ }
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ pfmtBuffer->AppendFormat( "%s %s ", PchNameFromEFontStyle( m_eFontStyle ), PchNameFromEFontWeight( m_eFontWeight ) );
+ CSSHelpers::AppendFloat( pfmtBuffer, m_flFontSize );
+ pfmtBuffer->AppendFormat( " %s", m_strFontFamily.String() );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return (m_flFontSize != k_flFloatNotSet &&
+ !m_strFontFamily.IsEmpty() &&
+ m_eFontStyle != k_EFontStyleUnset &&
+ m_eFontWeight != k_EFontWeightUnset);
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ // leave unset rather than defaulting. We will fix things up when accessed
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == fontFamily )
+ {
+ return "Specifies the font face to use.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "font-family: Arial;\n"
+ "font-family: \"Comic Sans MS\";"
+ "</pre>";
+ }
+ else if( symProperty == fontSize )
+ {
+ return "Specifies the target font face height in pixels.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "font-size: 12;"
+ "</pre>";
+ }
+ else if( symProperty == fontWeight )
+ {
+ return "Specifies the font weight to use. Supported values are light, thin, normal, medium, bold, and black.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "font-weight: normal;\n"
+ "font-weight: bold;\n"
+ "font-weight: thin;"
+ "</pre>";
+ }
+ else if( symProperty == fontStyle )
+ {
+ return "Specifies the font style to use. Supported values are normal, and italic<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "font-style: normal;"
+ "</pre>";
+ }
+
+ return CStyleProperty::GetDescription( symProperty );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyFont &rhs = (const CStylePropertyFont&)other;
+ return (m_strFontFamily == rhs.m_strFontFamily && m_flFontSize == rhs.m_flFontSize && m_eFontStyle == rhs.m_eFontStyle && m_eFontWeight == rhs.m_eFontWeight);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_strFontFamily );
+ CStyleProperty::Validate( validator, pchName );
+ }
+#endif
+
+ CUtlString m_strFontFamily;
+ float m_flFontSize;
+ EFontStyle m_eFontStyle;
+ EFontWeight m_eFontWeight;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Text align property
+//-----------------------------------------------------------------------------
+class CStylePropertyTextAlign : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+
+ CStylePropertyTextAlign() : CStyleProperty( CStylePropertyTextAlign::symbol )
+ {
+ m_eAlign = k_ETextAlignUnset;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTextAlign::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyTextAlign *p = (CStylePropertyTextAlign *)pTarget;
+ p->m_eAlign = m_eAlign;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { Assert( !"You can't interpolate a text-align" ); }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == symbol )
+ {
+ if( V_stristr( pchString, "left" ) )
+ m_eAlign = k_ETextAlignLeft;
+ else if( V_stristr( pchString, "center" ) )
+ m_eAlign = k_ETextAlignCenter;
+ else if( V_stristr( pchString, "right" ) )
+ m_eAlign = k_ETextAlignRight;
+ else
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ pfmtBuffer->Append( PchNameFromETextAlign( m_eAlign ) );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return (m_eAlign != k_ETextAlignUnset);
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ // bugbug jmccaskey - someday maybe default to right aligned on rtl languages?
+ if( m_eAlign == k_ETextAlignUnset )
+ m_eAlign = k_ETextAlignLeft;
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies the text alignment for text within this panel, defaults to left.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "text-align: left;\n"
+ "text-align: right;\n"
+ "text-align: center;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTextAlign &rhs = (const CStylePropertyTextAlign&)other;
+ return (m_eAlign == rhs.m_eAlign);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ ETextAlign m_eAlign;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Letter spacing property
+//-----------------------------------------------------------------------------
+class CStylePropertyTextLetterSpacing : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyTextLetterSpacing() : CStyleProperty( CStylePropertyTextLetterSpacing::symbol )
+ {
+ m_nLetterSpacing = 0;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if ( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTextLetterSpacing::MergeTo" );
+ return;
+ }
+
+ CStylePropertyTextLetterSpacing *p = (CStylePropertyTextLetterSpacing *)pTarget;
+ p->m_nLetterSpacing = m_nLetterSpacing;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { Assert( !"You can't interpolate a letter-spacing" ); }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = false;
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if ( V_strnicmp( pchString, "normal", V_ARRAYSIZE( "normal" ) ) == 0 )
+ {
+ m_nLetterSpacing = 0;
+ bSuccess = true;
+ }
+ else
+ {
+ float flLength;
+ bSuccess = CSSHelpers::BParseLength( &flLength, pchString, NULL );
+ m_nLetterSpacing = roundf(flLength);
+ }
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_nLetterSpacing = (float)roundf(m_nLetterSpacing*flScaleFactor);
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendLength( pfmtBuffer, m_nLetterSpacing );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets letter-spacing for text in a string. "
+ "Possible values:<br>"
+ "normal - no manual spacing<br>"
+ "&lt;pixels&gt; - Any fixed pixel value (ex: \"1px\")";
+ }
+
+ // Comparison function
+ virtual bool operator==( const CStyleProperty &other ) const
+ {
+ if ( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTextLetterSpacing &rhs = (const CStylePropertyTextLetterSpacing &)other;
+ return ( m_nLetterSpacing == rhs.m_nLetterSpacing );
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if ( !pCompareProperty || !( *this == *pCompareProperty ) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ int m_nLetterSpacing;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Text decoration property
+//-----------------------------------------------------------------------------
+class CStylePropertyTextDecoration : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline ETextDecoration GetDefault() { return k_ETextDecorationNone; }
+
+ CStylePropertyTextDecoration() : CStyleProperty( CStylePropertyTextDecoration::symbol )
+ {
+ m_eDecoration = GetDefault();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTextDecoration::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyTextDecoration *p = (CStylePropertyTextDecoration *)pTarget;
+ p->m_eDecoration = m_eDecoration;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { Assert( !"You can't interpolate a text-decorations" ); }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == symbol )
+ {
+ m_eDecoration = ETextDecorationFromName( pchString );
+ return (m_eDecoration != k_ETextDecorationUnset);
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ pfmtBuffer->Append( PchNameFromETextDecoration( m_eDecoration ) );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return (m_eDecoration != k_ETextDecorationUnset);
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies the decoration for text within this panel, defaults to none. Possible values: none, underline, line-through.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "text-decoration: underline;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTextDecoration &rhs = (const CStylePropertyTextDecoration&)other;
+ return (m_eDecoration == rhs.m_eDecoration);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ ETextDecoration m_eDecoration;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Text decoration property
+//-----------------------------------------------------------------------------
+class CStylePropertyTextTransform : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline ETextTransform GetDefault() { return k_ETextTransformNone; }
+
+ CStylePropertyTextTransform() : CStyleProperty( CStylePropertyTextTransform::symbol )
+ {
+ m_eTransform = GetDefault();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTextDecoration::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyTextTransform *p = (CStylePropertyTextTransform *)pTarget;
+ p->m_eTransform = m_eTransform;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { Assert( !"You can't interpolate a text-decorations" ); }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == symbol )
+ {
+ m_eTransform = ETextTransformFromName( pchString );
+ return (m_eTransform != k_ETextTransformUnset);
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ pfmtBuffer->Append( PchNameFromETextTransform( m_eTransform ) );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return (m_eTransform != k_ETextTransformUnset);
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies the transform for text within this panel, defaults to none. Possible values: none, uppercase, lowercase.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "text-transform: uppercase;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTextTransform &rhs = (const CStylePropertyTextTransform&)other;
+ return (m_eTransform == rhs.m_eTransform);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ ETextTransform m_eTransform;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Line height property
+//-----------------------------------------------------------------------------
+class CStylePropertyLineHeight : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+
+ CStylePropertyLineHeight() : CStyleProperty( CStylePropertyLineHeight::symbol )
+ {
+ m_flLineHeight = k_flFloatNotSet;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyLineHeight::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyLineHeight *p = (CStylePropertyLineHeight *)pTarget;
+ p->m_flLineHeight = m_flLineHeight;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { Assert( !"You can't interpolate a line height" ); }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == symbol )
+ {
+ bool bSuccess = false;
+ if( !CSSHelpers::BParseNumber( &m_flLineHeight, pchString ) )
+ {
+ bSuccess = CSSHelpers::BParseLength( &m_flLineHeight, pchString );
+ }
+ else
+ {
+ bSuccess = true;
+ }
+
+ return bSuccess;
+ }
+
+ return false;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ if( m_flLineHeight != k_flFloatNotSet )
+ m_flLineHeight *= flScaleFactor;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendFloat( pfmtBuffer, m_flLineHeight );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return (m_flLineHeight != k_flFloatNotSet);
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ // Leave unset rather than defaulting, will mean don't apply and let font-size set
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies the line height (distance between top edge of line above and line below) to use for text. By default "
+ "this is unset and a value that matches the font-size reasonably will be used automatically.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "line-height: 20px;"
+ "</pre>";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyLineHeight &rhs = (const CStylePropertyLineHeight&)other;
+ return (m_flLineHeight == rhs.m_flLineHeight);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ float m_flLineHeight;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Fill color property, this is not a real style property, but instead
+// a base that others derive from if they include a fill color.
+//-----------------------------------------------------------------------------
+class CStylePropertyFillColor : public CStyleProperty
+{
+public:
+
+ CStylePropertyFillColor( CStyleSymbol symbol ) : CStyleProperty( symbol )
+ {
+ }
+
+ virtual ~CStylePropertyFillColor() {}
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyFillColor::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyFillColor *p = (CStylePropertyFillColor *)pTarget;
+ p->m_FillBrushCollection = m_FillBrushCollection;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property, must implement if you override BCanTransition to return true.
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ m_FillBrushCollection.Clear();
+ return CSSHelpers::BParseFillBrushCollection( &m_FillBrushCollection, pchString, NULL );
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_FillBrushCollection.ScaleLengthValues( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendFillBrushCollection( pfmtBuffer, m_FillBrushCollection );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyFillColor &rhs = (const CStylePropertyFillColor&)other;
+ return (m_FillBrushCollection == rhs.m_FillBrushCollection);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_FillBrushCollection );
+ CStyleProperty::Validate( validator, pchName );
+ }
+#endif
+
+ CFillBrushCollection m_FillBrushCollection;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: foreground color property
+//-----------------------------------------------------------------------------
+class CStylePropertyForegroundColor : public CStylePropertyFillColor
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyForegroundColor() : CStylePropertyFillColor( CStylePropertyForegroundColor::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the foreground fill color/gradient/combination for a panel. This color is the color used to render text within the panel.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "color: #FFFFFFFF;\n"
+ "color: gradient( linear, 0% 0%, 0% 100%, from( #cbcbcbff ), to( #a0a0a0a0 ) );"
+ "</pre>";
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bResult = CStylePropertyFillColor::BSetFromString( symParsedName, pchString );
+
+#ifdef _DEBUG
+ const CUtlVectorFixed< CFillBrushCollection::FillBrush_t, MAX_FILL_BRUSHES_PER_COLLECTION > &vecBrushes = m_FillBrushCollection.AccessBrushes();
+ FOR_EACH_VEC( vecBrushes, i )
+ {
+ AssertMsg( vecBrushes[i].m_Brush.GetType() != CFillBrush::k_EStrokeTypeParticleSystem, "Particle systems not supported as foreground color, only background. Won't render." );
+ }
+#endif
+
+ return bResult;
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: 3D transform properties
+//-----------------------------------------------------------------------------
+class CStylePropertyTransform3D : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static inline VMatrix GetDefault() { return VMatrix::GetIdentityMatrix(); }
+
+ CStylePropertyTransform3D() : CStyleProperty( CStylePropertyTransform3D::symbol )
+ {
+ m_bDirty = true;
+ m_bInterpolated = false;
+ m_Matrix = VMatrix::GetIdentityMatrix();
+ m_flCachedParentWidth = 0.0f;
+ m_flCachedParentHeight = 0.0f;
+ };
+
+ virtual ~CStylePropertyTransform3D()
+ {
+ m_vecTransforms.PurgeAndDeleteElements();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ Assert( !m_bInterpolated );
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTransform3D::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyTransform3D *p = (CStylePropertyTransform3D *)pTarget;
+ p->m_bDirty = true;
+ p->m_Matrix = m_Matrix;
+ p->m_vecTransforms.EnsureCapacity( p->m_vecTransforms.Count() + m_vecTransforms.Count() );
+ FOR_EACH_VEC( m_vecTransforms, i )
+ {
+ p->m_vecTransforms.AddToTail( m_vecTransforms[i]->Clone() );
+ }
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ bool BHasNon2DTransforms()
+ {
+ FOR_EACH_VEC( m_vecTransforms, i )
+ {
+ if( !m_vecTransforms[i]->BOnlyImpacts2DValues() )
+ return true;
+ }
+
+ return false;
+ }
+
+ VMatrix GetTransformMatrix( float flParentWidth, float flParentHeight ) const
+ {
+ // If dirty, or if called with new width/height (and not interpolated, because once interpolated we can't recompute values), then recompute the matrix
+ // with the specified width/height for the parent
+ if( m_bDirty || (!m_bInterpolated && (fabs( flParentWidth - m_flCachedParentWidth ) > 0.0001f || fabs( flParentHeight - m_flCachedParentHeight ) > 0.0001f ) ) )
+ {
+ // Should never be "dirty" when interpolated, this checks that
+ Assert( !m_bInterpolated );
+
+ m_flCachedParentWidth = flParentWidth;
+ m_flCachedParentHeight = flParentHeight;
+ m_bDirty = false;
+ m_Matrix = VMatrix::GetIdentityMatrix();
+ FOR_EACH_VEC( m_vecTransforms, i )
+ {
+ m_Matrix = m_vecTransforms[i]->GetTransformMatrix( flParentWidth, flParentHeight ) * m_Matrix;
+ }
+ }
+ return m_Matrix;
+ }
+
+ void AddTransform3D( CTransform3D *pTransform )
+ {
+ if( !pTransform )
+ {
+ Assert( pTransform );
+ return;
+ }
+
+ Assert( !m_bInterpolated );
+ m_bDirty = true;
+ m_vecTransforms.AddToTail( pTransform );
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ Assert( !m_bInterpolated );
+ m_bDirty = true;
+ m_vecTransforms.PurgeAndDeleteElements();
+
+ // special case none
+ if( V_stricmp( pchString, "none" ) == 0 )
+ return true;
+
+ // space separated string of transform-functions
+ while( pchString[0] != '\0' )
+ {
+ CTransform3D *pTransform = NULL;
+ if( !CSSHelpers::BParseTransformFunction( &pTransform, pchString, &pchString ) )
+ return false;
+
+ Assert( pTransform );
+ AddTransform3D( pTransform );
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ }
+
+ return true;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ if( flScaleFactor == 1.0f )
+ return;
+
+ if( !m_bInterpolated )
+ {
+ FOR_EACH_VEC( m_vecTransforms, i )
+ {
+ m_vecTransforms[i]->ScaleLengthValues( flScaleFactor );
+ m_bDirty = true;
+ }
+ }
+ else
+ {
+ if( m_Matrix.IsIdentity() )
+ return;
+
+ // Can't make an interpolated matrix dirty as we don't have data to recreate it fully, must
+ // decompose and scale the appropriate values that way
+ DecomposedMatrix_t current = DecomposeTransformMatrix( m_Matrix );
+ current.m_flTranslationXYZ[0] *= flScaleFactor;
+ current.m_flTranslationXYZ[1] *= flScaleFactor;
+ current.m_flTranslationXYZ[2] *= flScaleFactor;
+ m_Matrix = RecomposeTransformMatrix( current );
+ }
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( m_vecTransforms.Count() == 0 )
+ {
+ pfmtBuffer->Append( "none" );
+ return;
+ }
+
+ FOR_EACH_VEC( m_vecTransforms, i )
+ {
+ if( i > 0 )
+ pfmtBuffer->Append( "\n" );
+
+ CSSHelpers::AppendTransform( pfmtBuffer, m_vecTransforms[i] );
+ }
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the transforms to apply to the panel in 2d or 3d space. You can combine various transforms (comma separated) "
+ "and they will be applied in order to create a 4x4 3d transform matrix. The possible operations are: translate3d( x, y, z ), "
+ "translatex( x ), translatey( y ), translatez( z ), scale3d( x, y, z), rotate3d( x, y, z ), rotatex( x ), rotatey( y ), rotatez( z ).<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "transform: translate3d( -100px, -100px, 0px );\n"
+ "transform: rotateZ( -32deg ) rotateX( 30deg ) translate3d( 125px, 520px, 230px );"
+ "</pre>";
+ }
+
+ // Comparison function
+#ifdef WIN32
+#pragma optimize( "", off )
+#endif
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTransform3D &rhs = (const CStylePropertyTransform3D&)other;
+
+ if( m_bInterpolated || rhs.m_bInterpolated )
+ {
+ AssertMsg( false, "Can't compare two CStylePropertyTransform3D that have been interpolated" );
+ return false;
+ }
+
+ if( m_vecTransforms.Count() != rhs.m_vecTransforms.Count() )
+ return false;
+
+ FOR_EACH_VEC( m_vecTransforms, i )
+ {
+ CTransform3D *pLHS = m_vecTransforms[i];
+ CTransform3D *pRHS = rhs.m_vecTransforms[i];
+
+ ETransform3DType eType1 = pLHS->GetType();
+ Assert( eType1 == k_ETransform3DRotate || eType1 == k_ETransform3DTranslate || eType1 == k_ETransform3DScale );
+ ETransform3DType eType2 = pRHS->GetType();
+ Assert( eType2 == k_ETransform3DRotate || eType2 == k_ETransform3DTranslate || eType2 == k_ETransform3DScale );
+
+ if( *pLHS != *pRHS )
+ return false;
+ }
+
+ return true;
+ }
+#ifdef WIN32
+#pragma optimize( "", on )
+#endif
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecTransforms );
+ FOR_EACH_VEC( m_vecTransforms, i )
+ {
+ validator.ClaimMemory( m_vecTransforms[i] );
+ }
+ CStyleProperty::Validate( validator, pchName );
+ }
+#endif
+
+private:
+ CUtlVector<CTransform3D *> m_vecTransforms;
+
+ mutable float m_flCachedParentWidth;
+ mutable float m_flCachedParentHeight;
+ mutable bool m_bDirty;
+ mutable VMatrix m_Matrix;
+ bool m_bInterpolated; // once interpolated, only m_Matrix will be set. m_vecTransforms will be empty.
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Transition property
+//-----------------------------------------------------------------------------
+class CStylePropertyTransitionProperties : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol symbolProperty;
+ static const CStyleSymbol symbolDuration;
+ static const CStyleSymbol symbolTiming;
+ static const CStyleSymbol symbolDelay;
+
+ CStylePropertyTransitionProperties() : CStyleProperty( CStylePropertyTransitionProperties::symbol ) { m_bImmediate = false; }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTransitionProperties::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyTransitionProperties *p = (CStylePropertyTransitionProperties *)pTarget;
+
+ // bugbug cboyd - need to think about what to do when property counts dont match. currently, we do not change the number of properties in the
+ // target when a property name has been set as that count should override ours
+ bool bPropertiesSet = (p->m_vecTransitionProperties.Count() > 0) ? p->m_vecTransitionProperties[0].m_symProperty.IsValid() : false;
+
+ // add properties to target to match our count
+ if( !bPropertiesSet )
+ {
+ p->m_vecTransitionProperties.EnsureCapacity( m_vecTransitionProperties.Count() );
+ for( int i = p->m_vecTransitionProperties.Count(); i < m_vecTransitionProperties.Count(); i++ )
+ p->AddNewProperty();
+ }
+
+ // set all unset properties on target
+ FOR_EACH_VEC( m_vecTransitionProperties, i )
+ {
+ // we have more properties than the other guy. Stop processing.
+ if( bPropertiesSet && p->m_vecTransitionProperties.Count() - 1 < i )
+ break;
+
+ TransitionProperty_t &transOther = p->m_vecTransitionProperties[i];
+ const TransitionProperty_t &transUs = m_vecTransitionProperties[i];
+
+ if( !transOther.m_symProperty.IsValid() )
+ transOther.m_symProperty = transUs.m_symProperty;
+
+ if( transOther.m_flTransitionSeconds == k_flFloatNotSet )
+ transOther.m_flTransitionSeconds = transUs.m_flTransitionSeconds;
+
+ if( transOther.m_eTimingFunction == k_EAnimationUnset )
+ {
+ transOther.m_eTimingFunction = transUs.m_eTimingFunction;
+ transOther.m_CubicBezier = transUs.m_CubicBezier;
+ }
+
+ if( transOther.m_flTransitionDelaySeconds == k_flFloatNotSet )
+ transOther.m_flTransitionDelaySeconds = transUs.m_flTransitionDelaySeconds;
+ }
+
+ if( !p->m_bImmediate )
+ p->m_bImmediate = m_bImmediate;
+ }
+
+ virtual bool BCanTransition() { return false; }
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ void AddNewProperty()
+ {
+ int iVec = m_vecTransitionProperties.AddToTail();
+ TransitionProperty_t &transition = m_vecTransitionProperties[iVec];
+
+ // copy other set properties forward
+ if( iVec == 0 )
+ {
+ transition.m_eTimingFunction = k_EAnimationUnset;
+
+ Vector2D vec[4];
+
+ panorama::GetAnimationCurveControlPoints( k_EAnimationUnset, vec );
+ transition.m_CubicBezier.SetControlPoints( vec );
+
+ transition.m_flTransitionSeconds = k_flFloatNotSet;
+ transition.m_flTransitionDelaySeconds = k_flFloatNotSet;
+ }
+ else
+ {
+ transition.m_eTimingFunction = m_vecTransitionProperties[iVec - 1].m_eTimingFunction;
+ transition.m_CubicBezier = m_vecTransitionProperties[iVec - 1].m_CubicBezier;
+ transition.m_flTransitionSeconds = m_vecTransitionProperties[iVec - 1].m_flTransitionSeconds;
+ transition.m_flTransitionDelaySeconds = m_vecTransitionProperties[iVec - 1].m_flTransitionDelaySeconds;
+ }
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ // need a temp buffer that we can terminate if !immediate is on the end of the string
+ char rgchBuffer[1024];
+
+ V_strncpy( rgchBuffer, pchString, V_ARRAYSIZE( rgchBuffer ) );
+ if( !BParseAndRemoveImmediate( m_bImmediate ? NULL : &m_bImmediate, rgchBuffer ) )
+ return false;
+
+ pchString = rgchBuffer;
+
+ if( symParsedName == symbol )
+ {
+ m_vecTransitionProperties.RemoveAll();
+
+ // transition property format: property duration timing-function delay [,*]
+ // we also support 'none'
+ if( V_strcmp( "none", pchString ) == 0 )
+ return true;
+
+ while( *pchString != '\0' )
+ {
+ TransitionProperty_t transition;
+
+ // get property name
+ char rgchProperty[k_nCSSPropertyNameMax];
+ if( !CSSHelpers::BParseIdent( rgchProperty, V_ARRAYSIZE( rgchProperty ), pchString, &pchString ) )
+ return false;
+
+ transition.m_symProperty = panorama::CStyleSymbol( rgchProperty );
+
+ if( !BCanPropertyTransition( transition.m_symProperty ) )
+ return false;
+
+ // get rest
+ if( !CSSHelpers::BParseTime( &transition.m_flTransitionSeconds, pchString, &pchString ) ||
+ !CSSHelpers::BParseTimingFunction( &transition.m_eTimingFunction, &transition.m_CubicBezier, pchString, &pchString ) ||
+ !CSSHelpers::BParseTime( &transition.m_flTransitionDelaySeconds, pchString, &pchString ) )
+ {
+ return false;
+ }
+
+ m_vecTransitionProperties.AddToTail( transition );
+
+ // see if there is another transition property
+ if( !CSSHelpers::BSkipComma( pchString, &pchString ) )
+ {
+ // end of list.. should be an empty string
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ return (pchString[0] == '\0');
+ }
+ }
+
+ return true;
+ }
+ else if( symParsedName == symbolProperty )
+ {
+ // comma separated list of porperty names
+ CUtlVector< panorama::CStyleSymbol > vecProperties;
+ if( !CSSHelpers::BParseCommaSepList( &vecProperties, CSSHelpers::BParseIdentToStyleSymbol, pchString ) )
+ return false;
+
+ // if we have less properties specified than other params, error
+ if( m_vecTransitionProperties.Count() > vecProperties.Count() )
+ return false;
+
+ m_vecTransitionProperties.EnsureCapacity( vecProperties.Count() );
+ FOR_EACH_VEC( vecProperties, i )
+ {
+ if( vecProperties[i] == "none" )
+ continue;
+
+ if( !BCanPropertyTransition( vecProperties[i] ) )
+ return false;
+
+ // new property?
+ if( m_vecTransitionProperties.Count() <= i )
+ AddNewProperty();
+
+ m_vecTransitionProperties[i].m_symProperty = vecProperties[i];
+ }
+
+ return true;
+ }
+ else if( symParsedName == symbolDuration )
+ {
+ return BParseAndAddProperty( &TransitionProperty_t::m_flTransitionSeconds, CSSHelpers::BParseTime, pchString );
+ }
+ else if( symParsedName == symbolDelay )
+ {
+ return BParseAndAddProperty( &TransitionProperty_t::m_flTransitionDelaySeconds, CSSHelpers::BParseTime, pchString );
+ }
+ else if( symParsedName == symbolTiming )
+ {
+ return BParseAndAddTimingFunction( CSSHelpers::BParseTimingFunction, pchString );
+ }
+
+ return false;
+ }
+
+ bool BParseAndRemoveImmediate( bool *pbImmediate, char *pchString )
+ {
+ const char k_rgchImmediate[] = "!immediate";
+ char *pchImmediate = V_strstr( pchString, k_rgchImmediate );
+ if( !pchImmediate )
+ {
+ if( pbImmediate )
+ *pbImmediate = false;
+ return true;
+ }
+
+ pchString = pchImmediate + V_ARRAYSIZE( k_rgchImmediate ) - 1;
+ pchString = (char*)CSSHelpers::SkipSpaces( pchString );
+ if( pchString[0] != '\0' )
+ return false;
+
+ if( pbImmediate )
+ *pbImmediate = true;
+
+ pchImmediate[0] = '\0';
+ return true;
+ }
+
+ template < typename T >
+ bool BParseAndAddProperty( T TransitionProperty_t::*pProp, bool( *func )(T*, const char *, const char **), const char *pchString )
+ {
+ // parse comma separated list
+ CUtlVector< T > vec;
+ if( !CSSHelpers::BParseCommaSepList( &vec, func, pchString ) || vec.Count() == 0 )
+ return false;
+
+ FOR_EACH_VEC( vec, i )
+ {
+ // new property?
+ if( m_vecTransitionProperties.Count() <= i )
+ AddNewProperty();
+
+ m_vecTransitionProperties[i].*pProp = vec[i];
+ }
+
+ // if provided list is less than the total number of properties, fill in rest with last value
+ for( int i = vec.Count(); i < m_vecTransitionProperties.Count(); i++ )
+ m_vecTransitionProperties[i].*pProp = m_vecTransitionProperties[i - 1].*pProp;
+
+ return true;
+ }
+
+ bool BParseAndAddTimingFunction( bool( *func )(EAnimationTimingFunction *pTimeingFunc, CCubicBezierCurve< Vector2D > *pBezier, const char *, const char **), const char *pchString )
+ {
+ // parse comma separated list
+ CUtlVector< EAnimationTimingFunction > vec;
+ CUtlVector< CCubicBezierCurve< Vector2D > > vec2;
+ if( !CSSHelpers::BParseCommaSepList( &vec, &vec2, func, pchString ) || vec.Count() == 0 )
+ return false;
+
+ Assert( vec.Count() == vec2.Count() );
+
+ FOR_EACH_VEC( vec, i )
+ {
+ // new property?
+ if( m_vecTransitionProperties.Count() <= i )
+ AddNewProperty();
+
+ m_vecTransitionProperties[i].m_eTimingFunction = vec[i];
+ m_vecTransitionProperties[i].m_CubicBezier = vec2[i];
+ }
+
+ // if provided list is less than the total number of properties, fill in rest with last value
+ for( int i = vec.Count(); i < m_vecTransitionProperties.Count(); i++ )
+ {
+ m_vecTransitionProperties[i].m_eTimingFunction = m_vecTransitionProperties[i - 1].m_eTimingFunction;
+ m_vecTransitionProperties[i].m_CubicBezier = m_vecTransitionProperties[i - 1].m_CubicBezier;
+ }
+
+ return true;
+ }
+
+ bool BCanPropertyTransition( CStyleSymbol symProperty )
+ {
+ // make sure the property is valid, and is not an alias
+ if( !UIEngine()->UIStyleFactory()->BRegisteredProperty( symProperty ) )
+ return false;
+
+ // bugbug cboyd - need less expensive check for valid property symbol and if it supports transition
+ CStyleProperty *pStyleProperty = UIEngine()->UIStyleFactory()->CreateStyleProperty( symProperty );
+ if( !pStyleProperty )
+ return false;
+
+ bool bCanTransition = pStyleProperty->BCanTransition();
+ UIEngine()->UIStyleFactory()->FreeStyleProperty( pStyleProperty );
+ return bCanTransition;
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ if( m_vecTransitionProperties.Count() < 1 )
+ return false;
+
+ // if the first transition property is fully set, all other transition properties should be set
+ TransitionProperty_t &transitionProperty = m_vecTransitionProperties[0];
+ return (transitionProperty.m_symProperty.IsValid() &&
+ transitionProperty.m_flTransitionSeconds != k_flFloatNotSet &&
+ transitionProperty.m_eTimingFunction != k_EAnimationUnset &&
+ transitionProperty.m_flTransitionDelaySeconds != k_flFloatNotSet);
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ if( m_vecTransitionProperties.Count() < 1 )
+ return;
+
+ // if property names aren't set or transition time isn't set (would default to 0), remove all and exit
+ TransitionProperty_t &firstProperty = m_vecTransitionProperties[0];
+ if( !firstProperty.m_symProperty.IsValid() || firstProperty.m_flTransitionSeconds == k_flFloatNotSet )
+ {
+ m_vecTransitionProperties.RemoveAll();
+ return;
+ }
+
+ // default to 'ease' timing function and 0 delay
+ FOR_EACH_VEC( m_vecTransitionProperties, i )
+ {
+ TransitionProperty_t &transitionProperty = m_vecTransitionProperties[i];
+
+ if( transitionProperty.m_eTimingFunction == k_EAnimationUnset )
+ {
+ transitionProperty.m_eTimingFunction = k_EAnimationEase;
+
+ Vector2D vec[4];
+ panorama::GetAnimationCurveControlPoints( transitionProperty.m_eTimingFunction, vec );
+ transitionProperty.m_CubicBezier.SetControlPoints( vec );
+ }
+
+ if( transitionProperty.m_flTransitionDelaySeconds == k_flFloatNotSet )
+ transitionProperty.m_flTransitionDelaySeconds = 0;
+ }
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( m_vecTransitionProperties.Count() == 0 )
+ {
+ pfmtBuffer->Append( "none" );
+ return;
+ }
+
+ FOR_EACH_VEC( m_vecTransitionProperties, i )
+ {
+ if( i > 0 )
+ pfmtBuffer->Append( ",\n" );
+
+ const TransitionProperty_t &transition = m_vecTransitionProperties[i];
+
+ pfmtBuffer->Append( transition.m_symProperty.String() );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendTime( pfmtBuffer, transition.m_flTransitionSeconds );
+ if( transition.m_eTimingFunction != k_EAnimationCustomBezier )
+ pfmtBuffer->AppendFormat( " %s ", PchNameFromEAnimationTimingFunction( transition.m_eTimingFunction ) );
+ else
+ pfmtBuffer->AppendFormat( " cubic-bezier( %1.3f, %1.3f, %1.3f, %1.3f ) ",
+ transition.m_CubicBezier.ControlPoint( 1 ).x,
+ transition.m_CubicBezier.ControlPoint( 1 ).y,
+ transition.m_CubicBezier.ControlPoint( 2 ).x,
+ transition.m_CubicBezier.ControlPoint( 2 ).y );
+
+ CSSHelpers::AppendTime( pfmtBuffer, transition.m_flTransitionDelaySeconds );
+ }
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == symbol )
+ {
+ return "Specifies which properties should transition smoothly to new values if a class/pseudo class changes the styles. "
+ "Also specifies duration, timing function, and delay. Valid timing functions are: ease, ease-in, ease-out, ease-in-out, linear.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "transition: position 2.0s ease-in-out 0.0s, perspective-origin 1.2s ease-in-out 0.8s;"
+ "</pre>";
+ }
+ else if( symProperty == symbolProperty )
+ {
+ return "Specifies which properties should transition smoothly to new values if a class/pseudo class changes the styles.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "transition: position, transform, background-color;"
+ "</pre>";
+ }
+ else if( symProperty == symbolTiming )
+ {
+ return "Specifies the timing function to use for transition properties on this panel, if more than one comma delimited value is specified "
+ "then the values are applied to each property specified in 'transition-property' in order. If only one value is specified then "
+ "it applies to all the properties specified in transition-property. Valid timing functions are: ease, ease-in, ease-out, ease-in-out, linear.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "transition-timing-function: ease-in-out;\n"
+ "transition-timing-function: ease-in-out, linear;\n"
+ "transition-timing-function: cubic-bezier( 0.785, 0.385, 0.555, 1.505 );"
+ "</pre>";
+
+ }
+ else if( symProperty == symbolDuration )
+ {
+ return "Specifies the durating in seconds to use for transition properties on this panel, if more than one comma delimited value is specified "
+ "then the values are applied to each property specified in 'transition-property' in order. If only one value is specified then "
+ "it applies to all the properties specified in transition-property.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "transition-duration: 2.0s;\n"
+ "transition-duration: 2.0s, 1.2s, 1.2s, 4.0s, 2.0s;"
+ "</pre>";
+
+ }
+ else if( symProperty == symbolDelay )
+ {
+ return "Specifies the delay in seconds to use for transition properties on this panel, if more than one comma delimited value is specified "
+ "then the values are applied to each property specified in 'transition-property' in order. If only one value is specified then "
+ "it applies to all the properties specified in transition-property.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "transition-delay: 0.0s;\n"
+ "transition-delay: 0.0s, 1.2s;"
+ "</pre>";
+ }
+
+ return CStyleProperty::GetDescription( symProperty );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTransitionProperties &rhs = (const CStylePropertyTransitionProperties &)other;
+ if( m_vecTransitionProperties.Count() != rhs.m_vecTransitionProperties.Count() )
+ return false;
+
+ FOR_EACH_VEC( m_vecTransitionProperties, i )
+ {
+ if( m_vecTransitionProperties[i] != rhs.m_vecTransitionProperties[i] )
+ return false;
+ }
+
+ // should not compare immediate
+
+ return true;
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ // looks up transition data for a property
+ TransitionProperty_t *GetTransitionData( CStyleSymbol hSymbol )
+ {
+ FOR_EACH_VEC( m_vecTransitionProperties, i )
+ {
+ if( m_vecTransitionProperties[i].m_symProperty == hSymbol )
+ return &m_vecTransitionProperties[i];
+ }
+
+ return NULL;
+ }
+
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecTransitionProperties );
+ CStyleProperty::Validate( validator, pchName );
+ }
+#endif
+
+ CUtlVector< TransitionProperty_t > m_vecTransitionProperties;
+ bool m_bImmediate;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: background-color property
+//-----------------------------------------------------------------------------
+class CStylePropertyBackgroundColor : public CStylePropertyFillColor
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyBackgroundColor() : CStylePropertyFillColor( CStylePropertyBackgroundColor::symbol )
+ {
+ }
+
+ bool BHasAnyParticleSystems()
+ {
+ return m_FillBrushCollection.GetNumParticleSystems() > 0 ? true : false;
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the background fill color/gradient/combination for a panel.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "background-color: #FFFFFFFF;\n"
+ "background-color: gradient( linear, 0% 0%, 0% 100%, from( #fbfbfbff ), to( #c0c0c0c0 ) );\n"
+ "background-color: gradient( linear, 0% 0%, 0% 100%, from( #fbfbfbff ), color-stop( 0.3, #ebebebff ), to( #c0c0c0c0 ) );\n"
+ "background-color: gradient( radial, 50% 50%, 0% 0%, 80% 80%, from( #00ff00ff ), to( #0000ffff ) );\n"
+ "background-color: #0d1c22ff, gradient( radial, 100% -0%, 100px -40px, 320% 270%, from( #3a464bff ), color-stop( 0.23, #0d1c22ff ), to( #0d1c22ff ) );"
+ "</pre>";
+ }
+
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: border property
+//-----------------------------------------------------------------------------
+class CStylePropertyBorder : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+
+ static const CStyleSymbol symTop;
+ static const CStyleSymbol symRight;
+ static const CStyleSymbol symBottom;
+ static const CStyleSymbol symLeft;
+
+ static const CStyleSymbol symStyle;
+ static const CStyleSymbol symTopStyle;
+ static const CStyleSymbol symRightStyle;
+ static const CStyleSymbol symBottomStyle;
+ static const CStyleSymbol symLeftStyle;
+
+ static const CStyleSymbol symWidth;
+ static const CStyleSymbol symTopWidth;
+ static const CStyleSymbol symRightWidth;
+ static const CStyleSymbol symBottomWidth;
+ static const CStyleSymbol symLeftWidth;
+
+ static const CStyleSymbol symColor;
+ static const CStyleSymbol symTopColor;
+ static const CStyleSymbol symRightColor;
+ static const CStyleSymbol symBottomColor;
+ static const CStyleSymbol symLeftColor;
+
+ CStylePropertyBorder() : CStyleProperty( CStylePropertyBorder::symbol )
+ {
+ for( int i = 0; i < 4; i++ )
+ {
+ m_rgBorderStyle[i] = k_EBorderStyleUnset;
+ m_rgColorsSet[i] = false;
+ m_rgBorderColor[i] = Color( 0, 0, 0, 0 );
+ }
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyBorder::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyBorder *pBorderTarget = (CStylePropertyBorder*)pTarget;
+ for( int i = 0; i < 4; i++ )
+ {
+ if( pBorderTarget->m_rgBorderStyle[i] == k_EBorderStyleUnset )
+ pBorderTarget->m_rgBorderStyle[i] = m_rgBorderStyle[i];
+
+ if( !pBorderTarget->m_rgBorderWidth[i].IsSet() )
+ pBorderTarget->m_rgBorderWidth[i] = m_rgBorderWidth[i];
+
+ if( pBorderTarget->m_rgColorsSet[i] == false )
+ {
+ pBorderTarget->m_rgColorsSet[i] = m_rgColorsSet[i];
+ pBorderTarget->m_rgBorderColor[i] = m_rgBorderColor[i];
+ }
+ }
+
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == symbol )
+ {
+ // shorthand for width, style, color
+ if( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[0], pchString, &pchString ) )
+ {
+ m_rgBorderWidth[1] = m_rgBorderWidth[2] = m_rgBorderWidth[3] = m_rgBorderWidth[0];
+
+ if( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[0], pchString, &pchString ) )
+ {
+ m_rgBorderStyle[1] = m_rgBorderStyle[2] = m_rgBorderStyle[3] = m_rgBorderStyle[0];
+
+ if( CSSHelpers::BParseColor( &m_rgBorderColor[0], pchString, &pchString ) )
+ {
+ m_rgColorsSet[0] = m_rgColorsSet[1] = m_rgColorsSet[2] = m_rgColorsSet[3] = true;
+ m_rgBorderColor[1] = m_rgBorderColor[2] = m_rgBorderColor[3] = m_rgBorderColor[0];
+ }
+ }
+
+ // bugbug - should reset all values, as well as border-image and border-radius as well, see
+ // http://www.w3.org/TR/css3-background/#ltborder-widthgt
+
+ return true;
+ }
+
+ return false;
+ }
+ else if ( symParsedName == symTop )
+ {
+ return BParseSingleEdgeShortcutProperty( 0, pchString );
+ }
+ else if ( symParsedName == symRight )
+ {
+ return BParseSingleEdgeShortcutProperty( 1, pchString );
+ }
+ else if ( symParsedName == symBottom )
+ {
+ return BParseSingleEdgeShortcutProperty( 2, pchString );
+ }
+ else if ( symParsedName == symLeft )
+ {
+ return BParseSingleEdgeShortcutProperty( 3, pchString );
+ }
+ else if( symParsedName == symWidth )
+ {
+ // "top right bottom left" in order
+ if( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[0], pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[1], pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[2], pchString, &pchString ) )
+ {
+ if( !CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[3], pchString, &pchString ) )
+ m_rgBorderWidth[3] = m_rgBorderWidth[1];
+ }
+ else
+ {
+ m_rgBorderWidth[2] = m_rgBorderWidth[0];
+ m_rgBorderWidth[3] = m_rgBorderWidth[1];
+ }
+ }
+ else
+ {
+ m_rgBorderWidth[1] = m_rgBorderWidth[2] = m_rgBorderWidth[3] = m_rgBorderWidth[0];
+ }
+
+ return true;
+ }
+ return false;
+ }
+ else if( symParsedName == symTopWidth )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[0], pchString, &pchString ) )
+ {
+ return true;
+ }
+
+ return false;
+ }
+ else if( symParsedName == symRightWidth )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[1], pchString, &pchString ) )
+ {
+ return true;
+ }
+
+ return false;
+ }
+ else if( symParsedName == symBottomWidth )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[2], pchString, &pchString ) )
+ {
+ return true;
+ }
+
+ return false;
+ }
+ else if( symParsedName == symLeftWidth )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[3], pchString, &pchString ) )
+ {
+ return true;
+ }
+
+ return false;
+ }
+ else if( symParsedName == symStyle )
+ {
+ // "top right bottom left" in order
+ if( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[0], pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[1], pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[2], pchString, &pchString ) )
+ {
+ if( !CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[3], pchString, &pchString ) )
+ m_rgBorderStyle[3] = m_rgBorderStyle[1];
+ }
+ else
+ {
+ m_rgBorderStyle[2] = m_rgBorderStyle[0];
+ m_rgBorderStyle[3] = m_rgBorderStyle[1];
+ }
+ }
+ else
+ {
+ m_rgBorderStyle[1] = m_rgBorderStyle[2] = m_rgBorderStyle[3] = m_rgBorderStyle[0];
+ }
+ return true;
+ }
+ return false;
+ }
+ else if( symParsedName == symTopStyle )
+ {
+ if( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[0], pchString, &pchString ) )
+ return true;
+
+ return false;
+ }
+ else if( symParsedName == symRightStyle )
+ {
+ if( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[1], pchString, &pchString ) )
+ return true;
+
+ return false;
+ }
+ else if( symParsedName == symBottomStyle )
+ {
+ if( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[2], pchString, &pchString ) )
+ return true;
+
+ return false;
+ }
+ else if( symParsedName == symLeftStyle )
+ {
+ if( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[3], pchString, &pchString ) )
+ return true;
+
+ return false;
+ }
+ else if( symParsedName == symColor )
+ {
+ // "top right bottom left" in order
+ if( CSSHelpers::BParseColor( &m_rgBorderColor[0], pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseColor( &m_rgBorderColor[1], pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseColor( &m_rgBorderColor[2], pchString, &pchString ) )
+ {
+ if( !CSSHelpers::BParseColor( &m_rgBorderColor[3], pchString, &pchString ) )
+ m_rgBorderColor[3] = m_rgBorderColor[1];
+ }
+ else
+ {
+ m_rgBorderColor[2] = m_rgBorderColor[0];
+ m_rgBorderColor[3] = m_rgBorderColor[1];
+ }
+ }
+ else
+ {
+ m_rgBorderColor[1] = m_rgBorderColor[2] = m_rgBorderColor[3] = m_rgBorderColor[0];
+ }
+ m_rgColorsSet[0] = m_rgColorsSet[1] = m_rgColorsSet[2] = m_rgColorsSet[3] = true;
+ return true;
+ }
+ return false;
+ }
+ else if( symParsedName == symTopColor )
+ {
+ if( CSSHelpers::BParseColor( &m_rgBorderColor[0], pchString, &pchString ) )
+ {
+ m_rgColorsSet[0] = true;
+ return true;
+ }
+
+ return false;
+ }
+ else if( symParsedName == symRightColor )
+ {
+ if( CSSHelpers::BParseColor( &m_rgBorderColor[1], pchString, &pchString ) )
+ {
+ m_rgColorsSet[1] = true;
+ return true;
+ }
+
+ return false;
+ }
+ else if( symParsedName == symBottomColor )
+ {
+ if( CSSHelpers::BParseColor( &m_rgBorderColor[2], pchString, &pchString ) )
+ {
+ m_rgColorsSet[2] = true;
+ return true;
+ }
+
+ return false;
+ }
+ else if( symParsedName == symLeftColor )
+ {
+ if( CSSHelpers::BParseColor( &m_rgBorderColor[3], pchString, &pchString ) )
+ {
+ m_rgColorsSet[3] = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ return false;
+ }
+
+ // helper function to parse the shortcut property for a single edge (border-top, border-right, border-bottom, border-left)
+ bool BParseSingleEdgeShortcutProperty( int nEdgeIndex, const char *pchString )
+ {
+ // shorthand for width, style, color
+ if ( CSSHelpers::BParseIntoUILength( &m_rgBorderWidth[ nEdgeIndex ], pchString, &pchString ) )
+ {
+ if ( CSSHelpers::BParseBorderStyle( &m_rgBorderStyle[ nEdgeIndex ], pchString, &pchString ) )
+ {
+ if ( CSSHelpers::BParseColor( &m_rgBorderColor[ nEdgeIndex ], pchString, &pchString ) )
+ {
+ m_rgColorsSet[ nEdgeIndex ] = true;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_rgBorderWidth[0].ScaleLengthValue( flScaleFactor );
+ m_rgBorderWidth[1].ScaleLengthValue( flScaleFactor );
+ m_rgBorderWidth[2].ScaleLengthValue( flScaleFactor );
+ m_rgBorderWidth[3].ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ // bugbug jmccaskey - this emits an invalid value for now... can't really put it all into just "border:"...
+
+ pfmtBuffer->Append( m_rgBorderStyle[0] == k_EBorderStyleSolid ? "solid " : "none " );
+ pfmtBuffer->Append( m_rgBorderStyle[1] == k_EBorderStyleSolid ? "solid " : "none " );
+ pfmtBuffer->Append( m_rgBorderStyle[2] == k_EBorderStyleSolid ? "solid " : "none " );
+ pfmtBuffer->Append( m_rgBorderStyle[3] == k_EBorderStyleSolid ? "solid " : "none " );
+
+ pfmtBuffer->Append( "/ " );
+
+
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgBorderWidth[0] );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgBorderWidth[1] );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgBorderWidth[2] );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgBorderWidth[3] );
+ pfmtBuffer->Append( " " );
+
+ pfmtBuffer->AppendFormat( "/ " );
+
+ if( m_rgColorsSet[0] )
+ {
+ CSSHelpers::AppendColor( pfmtBuffer, m_rgBorderColor[0] );
+ pfmtBuffer->Append( " " );
+ }
+ else
+ pfmtBuffer->Append( "none " );
+
+ if( m_rgColorsSet[1] )
+ {
+ CSSHelpers::AppendColor( pfmtBuffer, m_rgBorderColor[1] );
+ pfmtBuffer->Append( " " );
+ }
+ else
+ pfmtBuffer->Append( "none " );
+
+ if( m_rgColorsSet[2] )
+ {
+ CSSHelpers::AppendColor( pfmtBuffer, m_rgBorderColor[2] );
+ pfmtBuffer->Append( " " );
+ }
+ else
+ pfmtBuffer->Append( "none " );
+
+ if( m_rgColorsSet[3] )
+ {
+ CSSHelpers::AppendColor( pfmtBuffer, m_rgBorderColor[3] );
+ pfmtBuffer->Append( " " );
+ }
+ else
+ pfmtBuffer->Append( "none " );
+
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ for( int i = 0; i < 4; ++i )
+ {
+ if( m_rgBorderStyle[i] == k_EBorderStyleUnset )
+ return false;
+ if( !m_rgBorderWidth[i].IsSet() )
+ return false;
+ if( m_rgColorsSet[i] == false )
+ return false;
+ }
+ return true;
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ for( int i = 0; i < 4; ++i )
+ {
+ if( !m_rgBorderWidth[i].IsSet() )
+ m_rgBorderWidth[i].SetLength( 0 );
+
+ if( m_rgBorderStyle[i] == k_EBorderStyleUnset )
+ m_rgBorderStyle[i] = k_EBorderStyleNone;
+
+ if( m_rgColorsSet[i] == false )
+ {
+ m_rgColorsSet[i] = true;
+ m_rgBorderColor[i] = Color( 0, 0, 0, 0 );
+ }
+ }
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == symbol )
+ {
+ return "Shorthand for setting panel border. Specify width, style, and color. Supported styles are: solid, none.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border: 2px solid #111111FF;"
+ "</pre>";
+ }
+ else if ( symProperty == symTop )
+ {
+ return "Shorthand for setting the top panel border. Specify width, style, and color. Supported styles are: solid, none.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-top: 2px solid #111111FF;"
+ "</pre>";
+ }
+ else if ( symProperty == symRight )
+ {
+ return "Shorthand for setting the right panel border. Specify width, style, and color. Supported styles are: solid, none.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-right: 2px solid #111111FF;"
+ "</pre>";
+ }
+ else if ( symProperty == symBottom )
+ {
+ return "Shorthand for setting the bottom panel border. Specify width, style, and color. Supported styles are: solid, none.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-bottom: 2px solid #111111FF;"
+ "</pre>";
+ }
+ else if ( symProperty == symLeft )
+ {
+ return "Shorthand for setting the left panel border. Specify width, style, and color. Supported styles are: solid, none.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-left: 2px solid #111111FF;"
+ "</pre>";
+ }
+ else if ( symProperty == symColor )
+ {
+ return "Specifies border color for panel. If a single color value is set it applies to all sides, if 2 are set the first is top/bottom and "
+ "the second is left/right, if all four are set then they are top, right, bottom, left in order.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-color: #111111FF;\n"
+ "border-color: #FF0000FF #00FF00FF #0000FFFF #00FFFFFF;"
+ "</pre>";
+ }
+ else if( symProperty == symTopColor )
+ {
+ return "Specifies border color for the top edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-top-color: #111111FF;"
+ "</pre>";
+ }
+ else if( symProperty == symRightColor )
+ {
+ return "Specifies border color for the right edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-right-color: #111111FF;"
+ "</pre>";
+ }
+ else if( symProperty == symBottomColor )
+ {
+ return "Specifies border color for the bottom edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-bottom-color: #111111FF;"
+ "</pre>";
+ }
+ else if( symProperty == symLeftColor )
+ {
+ return "Specifies border color for the left edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-left-color: #111111FF;"
+ "</pre>";
+ }
+ else if( symProperty == symWidth )
+ {
+ return "Specifies border width for panel. If a single width value is set it applies to all sides, if 2 are set the first is top/bottom and "
+ "the second is left/right, if all four are set then they are top, right, bottom, left in order.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-width: 1px;'\n"
+ "border-width: 20px 1px 20px 1px;"
+ "</pre>";
+ }
+ else if( symProperty == symTopWidth )
+ {
+ return "Specifies border width for the top edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-top-width: 2px;"
+ "</pre>";
+ }
+ else if( symProperty == symRightWidth )
+ {
+ return "Specifies border width for the right edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-right-width: 2px;"
+ "</pre>";
+ }
+ else if( symProperty == symBottomWidth )
+ {
+ return "Specifies border width for the bottom edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-bottom-width: 2px;"
+ "</pre>";
+ }
+ else if( symProperty == symLeftWidth )
+ {
+ return "Specifies border width for the left edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-left-width: 2px;"
+ "</pre>";
+ }
+ else if( symProperty == symStyle )
+ {
+ return "Specifies border style for panel. If a single style value is set it applies to all sides, if 2 are set the first is top/bottom and "
+ "the second is left/right, if all four are set then they are top, right, bottom, left in order.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-style: solid;\n"
+ "border-style: solid none solid none;"
+ "</pre>";
+ }
+ else if( symProperty == symTopStyle )
+ {
+ return "Specifies border style for the top edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-top-style: solid;"
+ "</pre>";
+ }
+ else if( symProperty == symRightStyle )
+ {
+ return "Specifies border style for the right edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-right-style: solid;"
+ "</pre>";
+ }
+ else if( symProperty == symBottomStyle )
+ {
+ return "Specifies border style for the bottom edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-bottom-style: solid;"
+ "</pre>";
+ }
+ else if( symProperty == symLeftStyle )
+ {
+ return "Specifies border style for the left edge of the panel. <br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-left-style: solid;"
+ "</pre>";
+ }
+
+ return CStyleProperty::GetDescription( symProperty );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyBorder &rhs = (const CStylePropertyBorder &)other;
+
+ if( V_memcmp( m_rgBorderStyle, rhs.m_rgBorderStyle, sizeof( m_rgBorderStyle ) ) != 0 )
+ return false;
+
+ for( int i = 0; i < V_ARRAYSIZE( m_rgBorderWidth ); i++ )
+ {
+ if( m_rgBorderWidth[i] != rhs.m_rgBorderWidth[i] )
+ return false;
+ }
+
+ if( V_memcmp( m_rgColorsSet, rhs.m_rgColorsSet, sizeof( m_rgColorsSet ) ) != 0 )
+ return false;
+
+
+ for( int i = 0; i < V_ARRAYSIZE( m_rgBorderColor ); i++ )
+ {
+ if( m_rgBorderColor[i] != rhs.m_rgBorderColor[i] )
+ return false;
+ }
+
+ return true;
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ const CStylePropertyBorder &rhs = (const CStylePropertyBorder &)*pCompareProperty;
+ if( m_rgBorderWidth[0] != rhs.m_rgBorderWidth[0] || m_rgBorderWidth[1] != rhs.m_rgBorderWidth[1]
+ || m_rgBorderWidth[2] != rhs.m_rgBorderWidth[2] || m_rgBorderWidth[3] != rhs.m_rgBorderWidth[3] )
+ {
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+ }
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ EBorderStyle m_rgBorderStyle[4];
+ CUILength m_rgBorderWidth[4];
+ bool m_rgColorsSet[4];
+ Color m_rgBorderColor[4];
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: border radius property
+//-----------------------------------------------------------------------------
+class CStylePropertyBorderRadius : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol topRightRadius;
+ static const CStyleSymbol bottomRightRadius;
+ static const CStyleSymbol bottomLeftRadius;
+ static const CStyleSymbol topLeftRadius;
+
+ CStylePropertyBorderRadius() : CStyleProperty( CStylePropertyBorderRadius::symbol )
+ {
+
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyBorderRadius::MergeTo" );
+ return;
+ }
+
+ CStyleProperty::MergeTo( pTarget );
+
+ CStylePropertyBorderRadius *p = (CStylePropertyBorderRadius *)pTarget;
+ for( int i = 0; i < k_ECornerMax; ++i )
+ {
+ if( !p->m_rgCornerRaddi[i].m_HorizontalRadii.IsSet() )
+ p->m_rgCornerRaddi[i].m_HorizontalRadii = m_rgCornerRaddi[i].m_HorizontalRadii;
+ if( !p->m_rgCornerRaddi[i].m_VerticalRadii.IsSet() )
+ p->m_rgCornerRaddi[i].m_VerticalRadii = m_rgCornerRaddi[i].m_VerticalRadii;
+ }
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ );
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == symbol )
+ {
+ // horizontal before /, vertical after, vertical matches horizontal if unset
+ //[ <length> | <percentage> ]{1,4} [ / [ <length> | <percentage> ]{1,4} ]
+
+ CUILength topLeft;
+ CUILength topRight;
+ CUILength bottomRight;
+ CUILength bottomLeft;
+
+ if( !CSSHelpers::BParseIntoUILength( &topLeft, pchString, &pchString ) )
+ return false;
+
+ m_rgCornerRaddi[k_ECornerTopLeft].m_HorizontalRadii = topLeft;
+
+ if( !CSSHelpers::BParseIntoUILength( &topRight, pchString, &pchString ) )
+ {
+ // All horizontal values then equal topLeft
+ m_rgCornerRaddi[k_ECornerTopRight].m_HorizontalRadii = topLeft;
+ m_rgCornerRaddi[k_ECornerBottomRight].m_HorizontalRadii = topLeft;
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_HorizontalRadii = topLeft;
+ }
+ else
+ {
+ m_rgCornerRaddi[k_ECornerTopRight].m_HorizontalRadii = topRight;
+
+ if( !CSSHelpers::BParseIntoUILength( &bottomRight, pchString, &pchString ) )
+ {
+ // Bottom right matches top left then, and bottom left matches top right
+ m_rgCornerRaddi[k_ECornerBottomRight].m_HorizontalRadii = topLeft;
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_HorizontalRadii = topRight;
+ }
+ else
+ {
+ m_rgCornerRaddi[k_ECornerBottomRight].m_HorizontalRadii = bottomRight;
+
+ if( !CSSHelpers::BParseIntoUILength( &bottomLeft, pchString, &pchString ) )
+ {
+ // Bottom left matches top right then
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_HorizontalRadii = topRight;
+ }
+ else
+ {
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_HorizontalRadii = bottomLeft;
+ }
+ }
+ }
+
+ // Look for the / then, which will have vertical values after. If not found set them all
+ // to match horizontal.
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if( pchString[0] != '/' )
+ {
+ for( int i = 0; i < k_ECornerMax; ++i )
+ m_rgCornerRaddi[i].m_VerticalRadii = m_rgCornerRaddi[i].m_HorizontalRadii;
+ }
+ else
+ {
+ // Skip /
+ pchString++;
+ CSSHelpers::SkipSpaces( pchString );
+
+ // Insist we get one value after the /, having a trailing / with no vertical values is bogus
+ if( !CSSHelpers::BParseIntoUILength( &topLeft, pchString, &pchString ) )
+ {
+ // Set to match horizontal anyway so our values are kind of valid
+ for( int i = 0; i < k_ECornerMax; ++i )
+ m_rgCornerRaddi[i].m_VerticalRadii = m_rgCornerRaddi[i].m_HorizontalRadii;
+
+ return false;
+ }
+
+ m_rgCornerRaddi[k_ECornerTopLeft].m_VerticalRadii = topLeft;
+
+ if( !CSSHelpers::BParseIntoUILength( &topRight, pchString, &pchString ) )
+ {
+ // All vertical values then equal topLeft
+ m_rgCornerRaddi[k_ECornerTopRight].m_VerticalRadii = topLeft;
+ m_rgCornerRaddi[k_ECornerBottomRight].m_VerticalRadii = topLeft;
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_VerticalRadii = topLeft;
+ }
+ else
+ {
+ m_rgCornerRaddi[k_ECornerTopRight].m_VerticalRadii = topRight;
+
+ if( !CSSHelpers::BParseIntoUILength( &bottomRight, pchString, &pchString ) )
+ {
+ // Bottom right matches top left then, and bottom left matches top right
+ m_rgCornerRaddi[k_ECornerBottomRight].m_VerticalRadii = topLeft;
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_VerticalRadii = topRight;
+ }
+ else
+ {
+ m_rgCornerRaddi[k_ECornerBottomRight].m_VerticalRadii = bottomRight;
+
+ if( !CSSHelpers::BParseIntoUILength( &bottomLeft, pchString, &pchString ) )
+ {
+ // Bottom left matches top right then
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_VerticalRadii = topRight;
+ }
+ else
+ {
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_VerticalRadii = bottomLeft;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+ else
+ {
+ int iCorner = k_ECornerInvalid;
+ if( symParsedName == topLeftRadius )
+ iCorner = k_ECornerTopLeft;
+ else if( symParsedName == topRightRadius )
+ iCorner = k_ECornerTopRight;
+ else if( symParsedName == bottomRightRadius )
+ iCorner = k_ECornerBottomRight;
+ else if( symParsedName == bottomLeftRadius )
+ iCorner = k_ECornerBottomLeft;
+
+ if( iCorner == k_ECornerInvalid )
+ return false;
+
+ CUILength length;
+ if( !CSSHelpers::BParseIntoUILength( &length, pchString, &pchString ) )
+ return false;
+
+ m_rgCornerRaddi[iCorner].m_HorizontalRadii = length;
+
+ // Second value is optional, otherwise vertical matches horizontal
+ if( !CSSHelpers::BParseIntoUILength( &length, pchString, &pchString ) )
+ m_rgCornerRaddi[iCorner].m_VerticalRadii = m_rgCornerRaddi[iCorner].m_HorizontalRadii;
+ else
+ m_rgCornerRaddi[iCorner].m_VerticalRadii = length;
+
+ return true;
+ }
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_rgCornerRaddi[k_ECornerTopLeft].m_HorizontalRadii.ScaleLengthValue( flScaleFactor );
+ m_rgCornerRaddi[k_ECornerTopLeft].m_VerticalRadii.ScaleLengthValue( flScaleFactor );
+ m_rgCornerRaddi[k_ECornerTopRight].m_HorizontalRadii.ScaleLengthValue( flScaleFactor );
+ m_rgCornerRaddi[k_ECornerTopRight].m_VerticalRadii.ScaleLengthValue( flScaleFactor );
+ m_rgCornerRaddi[k_ECornerBottomRight].m_HorizontalRadii.ScaleLengthValue( flScaleFactor );
+ m_rgCornerRaddi[k_ECornerBottomRight].m_VerticalRadii.ScaleLengthValue( flScaleFactor );
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_HorizontalRadii.ScaleLengthValue( flScaleFactor );
+ m_rgCornerRaddi[k_ECornerBottomLeft].m_VerticalRadii.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgCornerRaddi[k_ECornerTopLeft].m_HorizontalRadii );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgCornerRaddi[k_ECornerTopRight].m_HorizontalRadii );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgCornerRaddi[k_ECornerBottomRight].m_HorizontalRadii );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgCornerRaddi[k_ECornerBottomLeft].m_HorizontalRadii );
+
+ pfmtBuffer->AppendFormat( " / " );
+
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgCornerRaddi[k_ECornerTopLeft].m_VerticalRadii );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgCornerRaddi[k_ECornerTopRight].m_VerticalRadii );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgCornerRaddi[k_ECornerBottomRight].m_VerticalRadii );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_rgCornerRaddi[k_ECornerBottomLeft].m_VerticalRadii );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ for( int i = 0; i < (int)k_ECornerMax; ++i )
+ {
+ if( !m_rgCornerRaddi[i].m_HorizontalRadii.IsSet() )
+ return false;
+ if( !m_rgCornerRaddi[i].m_VerticalRadii.IsSet() )
+ return false;
+ }
+ return true;
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ for( int i = 0; i < (int)k_ECornerMax; ++i )
+ {
+ if( !m_rgCornerRaddi[i].m_HorizontalRadii.IsSet() )
+ m_rgCornerRaddi[i].m_HorizontalRadii.SetLength( 0 );
+ if( !m_rgCornerRaddi[i].m_VerticalRadii.IsSet() )
+ m_rgCornerRaddi[i].m_VerticalRadii.SetLength( 0 );
+ }
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == symbol )
+ {
+ return "Shorthand to set border radius for all corners at once. Border radius rounds off corners of the panel, adjusting the border to "
+ "smoothly round and also clipping background image/color and contents to the specified elliptical or circular values. In this shorthand "
+ "version you may specify a single value for all raddi, or horizontal / vertical separated by the '/' character. For both horizontal and "
+ "vertical you may specify 1 to 4 values in pixels or %, they will be taken in order as top-left, top-right, bottom-right, bottom-left radii "
+ "values.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "// 2 px circular corners on all sides\n"
+ "border-radius: 2px;\n"
+ "// Perfect circular or elliptical panel (circular if box was square)\n"
+ "border-radius: 50% / 50%;\n"
+ "// 2 px horizontal radii 4px vertical elliptical corners on all sides\n"
+ "border-radius: 2px / 4px;\n"
+ "// All corners fully specified \n"
+ "border-radius: 2px 3px 4px 2px / 2px 3px 3px 2px;"
+ "</pre>";
+ }
+ else if( symProperty == topLeftRadius )
+ {
+ return "Specifies border-radius for top-left corner which rounds off border and clips background/foreground content to rounded edge. "
+ "Takes 1 or 2 values in px or %, first value is horizontal radii for elliptical corner, second is vertical radii, if only one is specified "
+ "then horizontal/vertical will both be set and corner will be circular.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-top-left-radius: 2px 2px;\n"
+ "border-top-left-radius: 5%;"
+ "</pre>";
+ }
+ else if( symProperty == topRightRadius )
+ {
+ return "Specifies border-radius for top-right corner which rounds off border and clips background/foreground content to rounded edge. "
+ "Takes 1 or 2 values in px or %, first value is horizontal radii for elliptical corner, second is vertical radii, if only one is specified "
+ "then horizontal/vertical will both be set and corner will be circular.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-top-right-radius: 2px 2px;\n"
+ "border-top-right-radius: 5%;"
+ "</pre>";
+ }
+ else if( symProperty == bottomRightRadius )
+ {
+ return "Specifies border-radius for bottom-right corner which rounds off border and clips background/foreground content to rounded edge. "
+ "Takes 1 or 2 values in px or %, first value is horizontal radii for elliptical corner, second is vertical radii, if only one is specified "
+ "then horizontal/vertical will both be set and corner will be circular.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-bottom-right-radius: 2px 2px;\n"
+ "border-bottom-right-radius: 5%;"
+ "</pre>";
+ }
+ else if( symProperty == bottomLeftRadius )
+ {
+ return "Specifies border-radius for bottom-left corner which rounds off border and clips background/foreground content to rounded edge. "
+ "Takes 1 or 2 values in px or %, first value is horizontal radii for elliptical corner, second is vertical radii, if only one is specified "
+ "then horizontal/vertical will both be set and corner will be circular.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-bottom-left-radius: 2px 2px;\n"
+ "border-bottom-left-radius: 5%;"
+ "</pre>";
+ }
+
+ return CStyleProperty::GetDescription( symProperty );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyBorderRadius &rhs = (const CStylePropertyBorderRadius &)other;
+
+ for( int i = 0; i < V_ARRAYSIZE( m_rgCornerRaddi ); i++ )
+ {
+ if( m_rgCornerRaddi[i] != rhs.m_rgCornerRaddi[i] )
+ return false;
+ }
+
+ return true;
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ enum ECorner
+ {
+ k_ECornerInvalid = -1,
+ k_ECornerTopLeft = 0,
+ k_ECornerTopRight,
+ k_ECornerBottomRight,
+ k_ECornerBottomLeft,
+
+ // Sentinel, for array iteration
+ k_ECornerMax
+ };
+
+ struct CornerRadii_t
+ {
+ CUILength m_HorizontalRadii;
+ CUILength m_VerticalRadii;
+
+ bool operator==(const CornerRadii_t &rhs) const { return (m_HorizontalRadii == rhs.m_HorizontalRadii && m_VerticalRadii == rhs.m_VerticalRadii); }
+ bool operator!=(const CornerRadii_t &rhs) const { return !(*this == rhs); }
+ };
+
+ CornerRadii_t m_rgCornerRaddi[k_ECornerMax];
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: border image property
+//-----------------------------------------------------------------------------
+class CStylePropertyBorderImage : public CStyleProperty
+{
+public:
+
+ // forward decl
+ struct BorderImageWidth_t;
+
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol symImageSource;
+ static const CStyleSymbol symImageSlice;
+ static const CStyleSymbol symImageWidth;
+ static const CStyleSymbol symImageOutset;
+ static const CStyleSymbol symImageRepeat;
+
+ CStylePropertyBorderImage() : CStyleProperty( CStylePropertyBorderImage::symbol )
+ {
+ m_bFillCenter = false;
+ m_pImage = NULL;
+ m_bSlicesSet = false;
+ m_bWidthsSet = false;
+ m_bOutsetsSet = false;
+ m_bStretchSet = false;
+ for( int i = 0; i < 4; ++i )
+ {
+ m_Width[i].m_eType = k_EBorderImageWidthNumber;
+ m_Width[i].m_flValue = 1.0f;
+ m_Outsets[i].SetLength( 0.0f );
+ m_Slices[i].SetPercent( 100.0f );
+ }
+ m_Stretch[0] = k_EBorderImageStretchStretch;
+ m_Stretch[1] = k_EBorderImageStretchStretch;
+ }
+
+ virtual ~CStylePropertyBorderImage()
+ {
+ SAFE_RELEASE( m_pImage );
+ }
+
+ // Merge properties
+ virtual void MergeTo( CStyleProperty *pTarget ) const;
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString );
+
+ // Parse image source
+ bool BParseImageSource( const char *pchString, const char **pchAfterParse );
+
+ // Parse image slices
+ bool BParseImageSlices( const char *pchString, const char **pchAfterParse );
+
+ // Parse image widths
+ bool BParseImageWidths( const char *pchString, const char **pchAfterParse );
+
+ // Parse image outsets
+ bool BParseImageOutsets( const char *pchString, const char **pchAfterParse );
+
+ // Parse image repeats
+ bool BParseImageRepeats( const char *pchString, const char **pchAfterParse );
+
+ // Parse individual border image width
+ bool BParseImageWidth( BorderImageWidth_t *pWidth, const char *pchString, const char **pchAfterParse );
+
+ // Parse individual repeat
+ bool BParseRepeat( EBorderImageRepeatType *pRepeat, const char *pchString, const char **pchAfterParse );
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const;
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ if( m_bSlicesSet && m_bStretchSet && m_bWidthsSet && m_bOutsetsSet && !m_sURLPath.IsEmpty() )
+ return true;
+
+ return false;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor );
+
+ // called when applied to a panel after comparing with set values
+ virtual void OnAppliedToPanel( IUIPanel *pPanel, float flScaleFactor );
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == symbol )
+ {
+ return "Shorthand for specifying all the border-image related properties at once.\n"
+ "Technical syntax is: &lt;border-image-source&gt; || &lt;border-image-slice&gt; [ / &lt;border-image-width&gt;? [ / &lt;border-image-outset&gt; ]? ]? || &lt;border-image-repeat&gt;, "
+ "see the explanations for individual properties for details on each.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-image: url( \"file://message_border.tga\" ) 25% repeat;\n"
+ "border-image: url( \"file://message_border.tga\" ) 25% / 1 / 20px repeat;"
+ "</pre>";
+ }
+ else if( symProperty == symImageSource )
+ {
+ return "Specifies the source image to use as the 9-slice border-image.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-image-source: url( \"file://message_border.tga\" );\n"
+ "border-image-source: url( \"http://store.steampowered.com/public/images/steam/message_border.tga\" );"
+ "</pre>";
+ }
+ else if( symProperty == symImageSlice )
+ {
+ return "Specifies the insets for top, right, bottom, and left (in order) slice offsets to use for slicing the source image into 9 regions. "
+ "The 'fill' keyword may optionally appear before or after the length values and specifies to draw the middle region as a fill for the body "
+ "background of the panel, without it the middle region will not be drawn.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-image-slice: 10px 10px 10px 10px;\n"
+ "border-image-slice: 20% 10% 20% 10% fill;"
+ "</pre>";
+ }
+ else if( symProperty == symImageWidth )
+ {
+ return "By default after slicing the image as specified in border-image-slice the 9 regions will be used to fill the space specified "
+ "by the standard border-width property. This border-image-width property may be used to override that and specify different widths. "
+ "The values appear in top, right, bottom, left order, the 2nd through 4th may be ommited and corresponding earlier values will be used. "
+ "Values may be straight floats which specify a multiple of the corresponding border-width value, a percentage (which is relative "
+ "to the size of the border image in the corresponding dimension), or 'auto' which means to use the intrinsic size of the corresponding "
+ "border-image-slice.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-image-width: 1 1 1 1;\n"
+ "border-image-slice: 50% 50% 50% 50%;\n"
+ "border-image-slice: auto;"
+ "</pre>";
+ }
+ else if( symProperty == symImageOutset )
+ {
+ return "Specifies the amount by which the border image should draw outside of the normal content/border box, this allows the border image "
+ "to extend into the margin area and draw outside the panels bounds. This may still result in clipping of the image by a parent panel if "
+ "the parents bounds are too close to the edges of the panel with the border-image. Values are specified as px or % in top, right, bottom, left "
+ "order with the 2nd through 4th values optional.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-image-outset: 0px;\n"
+ "border-image-outset: 20px 20px 20px 20px;"
+ "</pre>";
+ }
+ else if( symProperty == symImageRepeat )
+ {
+ return "Specifies how the top/right/bottom/left/middle images of the 9 slice regions are stretched to fit the available space. "
+ "Options are stretch, repeat, round or space. Stretch/repeat are self explanatory, round means tile (repeat) but scale first"
+ "to ensure that a whole number of tiles is used with no partial tile at the edge of the space, space means tile (repeat) but add "
+ "padding between tiles to ensure a whole number of tiles with no partial tile at the edge is needed.\n"
+ "Two values are specified, the first applies to how we stretch the top/middle/bottom horizontally to fill space, the second "
+ "applies to how we stretch the left/middle/right vertically to fill space.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "border-image-repeat: stretch stretch;\n"
+ "border-image-outset: repeat;\n"
+ "border-image-outset: round;\n"
+ "border-image-outset: stetch space;"
+ "</pre>";
+ }
+
+ return CStyleProperty::GetDescription( symProperty );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyBorderImage &rhs = (const CStylePropertyBorderImage &)other;
+
+ if( m_sURLPath != rhs.m_sURLPath || m_bSlicesSet != rhs.m_bSlicesSet )
+ return false;
+
+ for( int i = 0; i < V_ARRAYSIZE( m_Slices ); i++ )
+ {
+ if( m_Slices[i] != rhs.m_Slices[i] )
+ return false;
+ }
+
+ if( m_bFillCenter != rhs.m_bFillCenter )
+ return false;
+
+ if( m_bWidthsSet != rhs.m_bWidthsSet )
+ return false;
+
+ if( m_bWidthsSet && V_memcmp( m_Width, rhs.m_Width, sizeof( m_Width ) ) != 0 )
+ return false;
+
+ if( m_bOutsetsSet != rhs.m_bOutsetsSet )
+ return false;
+
+ if( m_bOutsetsSet )
+ {
+ for( int i = 0; i < V_ARRAYSIZE( m_Outsets ); i++ )
+ {
+ if( m_Outsets[i] != rhs.m_Outsets[i] )
+ return false;
+ }
+ }
+
+ if( m_bStretchSet != rhs.m_bStretchSet )
+ return false;
+
+ if( m_bStretchSet && V_memcmp( m_Stretch, rhs.m_Stretch, sizeof( m_Stretch ) ) != 0 )
+ return false;
+
+ return true;
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ // border image source
+ IImageSource *m_pImage;
+ CUtlString m_sURLPath;
+
+ // border image slice
+ bool m_bSlicesSet;
+ CUILength m_Slices[4];
+ bool m_bFillCenter;
+
+ // border image width
+ struct BorderImageWidth_t
+ {
+ EBorderImageWidthType m_eType;
+ float m_flValue;
+ };
+ bool m_bWidthsSet;
+ BorderImageWidth_t m_Width[4];
+
+ // border image outsets
+ bool m_bOutsetsSet;
+ CUILength m_Outsets[4];
+
+ // border image stretch values
+ bool m_bStretchSet;
+ EBorderImageRepeatType m_Stretch[2];
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Background-image property
+//-----------------------------------------------------------------------------
+class CStylePropertyBackgroundImage : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol backgroundSize;
+ static const CStyleSymbol backgroundPosition;
+ static const CStyleSymbol backgroundRepeat;
+
+ CStylePropertyBackgroundImage();
+ virtual ~CStylePropertyBackgroundImage();
+
+ // from CStyleProperty
+ virtual void MergeTo( CStyleProperty *pTarget ) const;
+ virtual bool BCanTransition() { return false; }
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) { Assert( !"You can't interpolate an image" ); }
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString );
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const;
+ virtual bool BFullySet();
+ virtual void ResolveDefaultValues();
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+ virtual bool operator==(const CStyleProperty &rhs) const;
+ virtual void ApplyUIScaleFactor( float flScaleFactor );
+ virtual void OnAppliedToPanel( IUIPanel *pPanel );
+ virtual const char *GetDescription( CStyleSymbol symProperty );
+
+ CUtlVector< CBackgroundImageLayer * > &AccessLayers() { return m_vecLayers; }
+ void Set( const CUtlVector< CBackgroundImageLayer * > &vecLayers );
+
+ bool BHasActiveMovie();
+ void EnableBackgroundMovies( bool bEnable );
+
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+private:
+ CBackgroundImageLayer *GetOrAddLayer( int i );
+ void AddLayer();
+ void Clear();
+ void RemoveUnsetLayers();
+
+ CUtlVector< CBackgroundImageLayer * > m_vecLayers;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: opacity-mask property
+//-----------------------------------------------------------------------------
+class CStylePropertyOpacityMask : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol symbolScrollUp;
+ static const CStyleSymbol symbolScrollDown;
+ static const CStyleSymbol symbolScrollUpDown;
+
+ CStylePropertyOpacityMask() : CStyleProperty( CStylePropertyOpacityMask::symbol )
+ {
+ m_pImage = NULL;
+ m_flOpacityMaskOpacity = 1.0f;
+ m_pImageUp = NULL;
+ m_flOpacityMaskOpacityUp = 1.0f;
+ m_pImageDown = NULL;
+ m_flOpacityMaskOpacityDown = 1.0f;
+ m_pImageUpDown = NULL;
+ m_flOpacityMaskOpacityUpDown = 1.0f;
+
+ m_bWasSet = false;
+ }
+
+ virtual ~CStylePropertyOpacityMask()
+ {
+ SAFE_RELEASE( m_pImage );
+ SAFE_RELEASE( m_pImageUp );
+ SAFE_RELEASE( m_pImageDown );
+ SAFE_RELEASE( m_pImageUpDown );
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyOpacityMask::MergeTo" );
+ return;
+ }
+
+
+ CStylePropertyOpacityMask *p = (CStylePropertyOpacityMask *)pTarget;
+ if( !p->m_bWasSet )
+ {
+ p->m_pImage = m_pImage;
+ p->m_sURL = m_sURL;
+ p->m_flOpacityMaskOpacity = m_flOpacityMaskOpacity;
+
+ p->m_sURLUp = m_sURLUp;
+ p->m_pImageUp = m_pImageUp;
+ p->m_sURLUp = m_sURLUp;
+
+ p->m_sURLDown = m_sURLDown;
+ p->m_pImageDown = m_pImageDown;
+ p->m_sURLDown = m_sURLDown;
+
+ p->m_sURLUpDown = m_sURLUpDown;
+ p->m_pImageUpDown = m_pImageUpDown;
+ p->m_sURLUpDown = m_sURLUpDown;
+ }
+ }
+
+ // Does the style only affect compositing of it's panels and not drawing within a composition layer?
+ virtual bool BAffectsCompositionOnly() { return true; }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ CStylePropertyOpacityMask *p = (CStylePropertyOpacityMask *)&target;
+ if( !p->m_sURL.IsValid() )
+ {
+ // Fade out
+ m_flOpacityMaskOpacity = Lerp( flProgress, m_flOpacityMaskOpacity, 0.0f );
+ }
+ else if( !m_sURL.IsValid() && p->m_sURL.IsValid() )
+ {
+ // Fade in
+ m_sURL = p->m_sURL;
+ m_flOpacityMaskOpacity = Lerp( flProgress, 0.0f, p->m_flOpacityMaskOpacity );
+ }
+ else
+ {
+ m_sURL = p->m_sURL;
+ m_flOpacityMaskOpacity = Lerp( flProgress, m_flOpacityMaskOpacity, p->m_flOpacityMaskOpacity );
+ }
+
+ m_sURLUp = p->m_sURLUp;
+ m_pImageUp = p->m_pImageUp;
+ m_sURLUp = p->m_sURLUp;
+
+ m_sURLDown = p->m_sURLDown;
+ m_pImageDown = p->m_pImageDown;
+ m_sURLDown = p->m_sURLDown;
+
+ m_sURLUpDown = p->m_sURLUpDown;
+ m_pImageUpDown = p->m_pImageUpDown;
+ m_sURLUpDown = p->m_sURLUpDown;
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == symbol )
+ {
+ if( BParseProperty( pchString, m_flOpacityMaskOpacity, &m_pImage, m_sURL ) )
+ {
+ m_bWasSet = true;
+ return true;
+ }
+ return false;
+ }
+ else if( symParsedName == symbolScrollUp )
+ {
+ return BParseProperty( pchString, m_flOpacityMaskOpacityUp, &m_pImageUp, m_sURLUp );
+ }
+ else if( symParsedName == symbolScrollDown )
+ {
+ return BParseProperty( pchString, m_flOpacityMaskOpacityDown, &m_pImageDown, m_sURLDown );
+ }
+ else if( symParsedName == symbolScrollUpDown )
+ {
+ return BParseProperty( pchString, m_flOpacityMaskOpacityUpDown, &m_pImageUpDown, m_sURLUpDown );
+ }
+
+ return false;
+ }
+
+
+ bool BParseProperty( const char *pchString, float &flOpacityMaskOpacity, IImageSource **ppImage, CUtlString &sURL )
+ {
+ if( V_stricmp( "none", pchString ) == 0 )
+ {
+ *ppImage = NULL;
+ flOpacityMaskOpacity = 0.0f;
+ return true;
+ }
+ else
+ {
+ CUtlString sURLPath;
+ if( !CSSHelpers::BParseURL( sURLPath, pchString, &pchString ) )
+ return false;
+
+ sURL = sURLPath;
+ if( !sURL.IsValid() )
+ return false;
+
+ // Optional opacity value following
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if( !CSSHelpers::BParseNumber( &flOpacityMaskOpacity, pchString, &pchString ) )
+ flOpacityMaskOpacity = 1.0f;
+
+ return true;
+ }
+ }
+
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( !m_sURL.IsValid() )
+ {
+ pfmtBuffer->Append( "none" );
+ }
+ else
+ {
+ CSSHelpers::AppendURL( pfmtBuffer, m_sURL.String() );
+ pfmtBuffer->Append( " " );
+ pfmtBuffer->AppendFormat( "%f", m_flOpacityMaskOpacity );
+ }
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == symbol )
+ {
+ return "Applies an image as an opacity mask that stretches to the panel bounds and fades out it's content based on the alpha channel. "
+ "The second float value is an optional opacity value for the mask itself, the image won't interpolate/cross-fade, but you can animate the opacity to fade the mask in/out. "
+ "The -scroll-up, -scroll-down, and -scroll-up-down varients override the mask and apply only when the various vertical scroll scenarios affect the panel based on the overflow property.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "opacity-mask: url( \"file://{images}/upper_row_mask.tga\" );\n"
+ "opacity-mask: url( \"file://{images}/upper_row_mask.tga\" ) 0.5;\n"
+ "opacity-mask-scroll-up: url( \"file://{images}/upper_row_mask_up.tga\" ) 0.5;\n"
+ "opacity-mask-scroll-down: url( \"file://{images}/upper_row_mask_down.tga\" ) 0.5;\n"
+ "opacity-mask-scroll-up-down: url( \"file://{images}/upper_row_mask_up_down.tga\" ) 0.5;"
+ "</pre>";
+ }
+ return "";
+ }
+
+ virtual void OnAppliedToPanel( IUIPanel *pPanel );
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyOpacityMask &rhs = (const CStylePropertyOpacityMask &)other;
+ return (
+ m_sURL == rhs.m_sURL && m_flOpacityMaskOpacity == rhs.m_flOpacityMaskOpacity &&
+ m_sURLUp == rhs.m_sURLUp && m_flOpacityMaskOpacityUp == rhs.m_flOpacityMaskOpacityUp &&
+ m_sURLDown == rhs.m_sURLDown && m_flOpacityMaskOpacityDown == rhs.m_flOpacityMaskOpacityDown &&
+ m_sURLUpDown == rhs.m_sURLUpDown && m_flOpacityMaskOpacityUpDown == rhs.m_flOpacityMaskOpacityUpDown
+ );
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+ IImageSource *m_pImage;
+ IImageSource *m_pImageUp;
+ IImageSource *m_pImageDown;
+ IImageSource *m_pImageUpDown;
+
+ float m_flOpacityMaskOpacity;
+ float m_flOpacityMaskOpacityUp;
+ float m_flOpacityMaskOpacityDown;
+ float m_flOpacityMaskOpacityUpDown;
+
+private:
+ bool m_bWasSet;
+ CUtlString m_sURL;
+ CUtlString m_sURLUp;
+ CUtlString m_sURLDown;
+ CUtlString m_sURLUpDown;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: White-space property
+//-----------------------------------------------------------------------------
+class CStylePropertyWhiteSpace : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyWhiteSpace() : CStyleProperty( CStylePropertyWhiteSpace::symbol )
+ {
+ m_bSet = false;
+ m_bWrap = true;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyWhiteSpace::MergeTo" );
+ return;
+ }
+
+ CStylePropertyWhiteSpace *p = (CStylePropertyWhiteSpace *)pTarget;
+ if( !p->m_bSet )
+ {
+ p->m_bWrap = m_bWrap;
+ p->m_bSet = m_bSet;
+ }
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if( V_strnicmp( pchString, "nowrap", V_ARRAYSIZE( "nowrap" ) ) == 0 )
+ {
+ m_bWrap = false;
+ m_bSet = true;
+ return true;
+ }
+ else if( V_strnicmp( pchString, "normal", V_ARRAYSIZE( "normal" ) ) == 0 )
+ {
+ m_bWrap = true;
+ m_bSet = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( m_bWrap )
+ pfmtBuffer->Append( "normal" );
+ else
+ pfmtBuffer->Append( "nowrap" );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == symbol )
+ {
+ return "Controls white-space wrapping on rendered text. \"normal\" means wrap on whitespace, \"nowrap\" means do no wrapping at all.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "white-space: normal;\n"
+ "white-space: nowrap;"
+ "</pre>";
+ }
+ return "";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyWhiteSpace &rhs = (const CStylePropertyWhiteSpace &)other;
+ return (m_bWrap == rhs.m_bWrap && m_bSet == rhs.m_bSet);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ bool m_bWrap;
+ bool m_bSet;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: text-overflow property
+//-----------------------------------------------------------------------------
+class CStylePropertyTextOverflow : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyTextOverflow() : CStyleProperty( CStylePropertyTextOverflow::symbol )
+ {
+ m_bSet = false;
+ m_bEllipsis = true;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTextOverflow::MergeTo" );
+ return;
+ }
+
+ CStylePropertyTextOverflow *p = (CStylePropertyTextOverflow *)pTarget;
+ if( !p->m_bSet )
+ {
+ p->m_bEllipsis = m_bEllipsis;
+ p->m_bSet = m_bSet;
+ }
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if( V_strnicmp( pchString, "clip", V_ARRAYSIZE( "clip" ) ) == 0 )
+ {
+ m_bEllipsis = false;
+ m_bSet = true;
+ return true;
+ }
+ else if( V_strnicmp( pchString, "ellipsis", V_ARRAYSIZE( "ellipsis" ) ) == 0 )
+ {
+ m_bEllipsis = true;
+ m_bSet = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( m_bEllipsis )
+ pfmtBuffer->Append( "ellipsis" );
+ else
+ pfmtBuffer->Append( "clip" );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == symbol )
+ {
+ return "Controls truncation of text that doesn't fit in a panel. \"clip\" means to simply truncate (on char boundaries), \"ellipsis\" means to end with '...'.\n"
+ "We default to ellipsis, which is contrary to the normal CSS spec.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "text-overflow: ellipsis;\n"
+ "text-overflow: clip;"
+ "</pre>";
+ }
+ return "";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTextOverflow &rhs = (const CStylePropertyTextOverflow &)other;
+ return (m_bEllipsis == rhs.m_bEllipsis && m_bSet == rhs.m_bSet);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ bool m_bEllipsis;
+ bool m_bSet;
+};
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Width property
+//-----------------------------------------------------------------------------
+class CStylePropertyWidth : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyWidth() : CStyleProperty( CStylePropertyWidth::symbol )
+ {
+ m_Length.SetFitChildren();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyWidth::MergeTo" );
+ return;
+ }
+
+ CStylePropertyWidth *p = (CStylePropertyWidth *)pTarget;
+ p->m_Length = m_Length;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ CStylePropertyWidth *p = (CStylePropertyWidth *)&target;
+
+ float flParentWidth, flParentHeight, flParentPerspective;
+ GetParentSizeAvailable( pPanel, flParentWidth, flParentHeight, flParentPerspective );
+
+ m_Length = LerpUILength( flProgress, m_Length, p->m_Length, flParentWidth );
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = CSSHelpers::BParseIntoUILengthForSizing( &m_Length, pchString, NULL );
+
+ if ( m_Length.IsWidthPercentage() )
+ return false;
+
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_Length.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_Length );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the width for this panel. "
+ "Possible values:<br>"
+ "\"fit-children\" - Panel size is set to the required size of all children (default)<br>"
+ "&lt;pixels&gt; - Any fixed pixel value (ex: \"100px\")<br>"
+ "&lt;percentage&gt; - Percentage of parent width (ex: \"100%\")<br>"
+ "\"fill-parent-flow( &lt;weight&gt; )\" - Fills to remaining parent width. If multiple children are set to this value, weight is used to determine final width. For example, if three children are set to fill-parent-flow of 1.0 and the parent is 300px wide, each child will be 100px wide. (ex: \"fill-parent-flow( 1.0 )\" )<br>"
+ "\"height-percentage( &lt;percentage&gt; )\" - Percentage of the panel's height, which allows you to enforce a particular aspect ratio. The height cannot also be width-percentage.";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyWidth &rhs = (const CStylePropertyWidth &)other;
+ return (m_Length == rhs.m_Length);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUILength m_Length;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Height property
+//-----------------------------------------------------------------------------
+class CStylePropertyHeight : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyHeight() : CStyleProperty( CStylePropertyHeight::symbol )
+ {
+ m_Height.SetFitChildren();
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyHeight::MergeTo" );
+ return;
+ }
+
+ CStylePropertyHeight *p = (CStylePropertyHeight *)pTarget;
+ p->m_Height = m_Height;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ CStylePropertyHeight *p = (CStylePropertyHeight *)&target;
+
+ float flParentWidth, flParentHeight, flParentPerspective;
+ GetParentSizeAvailable( pPanel, flParentWidth, flParentHeight, flParentPerspective );
+
+ m_Height = LerpUILength( flProgress, m_Height, p->m_Height, flParentHeight );
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = CSSHelpers::BParseIntoUILengthForSizing( &m_Height, pchString, NULL );
+
+ if ( m_Height.IsHeightPercentage() )
+ return false;
+
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_Height.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_Height );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Sets the height for this panel. "
+ "Possible values:<br>"
+ "\"fit-children\" - Panel size is set to the required size of all children (default)<br>"
+ "&lt;pixels&gt; - Any fixed pixel value (ex: \"100px\")<br>"
+ "&lt;percentage&gt; - Percentage of parent height (ex: \"100%\")<br>"
+ "\"fill-parent-flow( &lt;weight&gt; )\" - Fills to remaining parent width. If multiple children are set to this value, weight is used to determine final height. For example, if three children are set to fill-parent-flow of 1.0 and the parent is 300px tall, each child will be 100px tall. (ex: \"fill-parent-flow( 1.0 )\" )<br>"
+ "\"width-percentage( &lt;percentage&gt; )\" - Percentage of the panel's width, which allows you to enforce a particular aspect ratio. The width cannot also be height-percentage.";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyHeight &rhs = (const CStylePropertyHeight &)other;
+ return (m_Height == rhs.m_Height);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUILength m_Height;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: min-width property
+//-----------------------------------------------------------------------------
+class CStylePropertyMinWidth : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyMinWidth() : CStyleProperty( CStylePropertyMinWidth::symbol )
+ {
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyMinWidth::MergeTo" );
+ return;
+ }
+
+ CStylePropertyMinWidth *p = (CStylePropertyMinWidth *)pTarget;
+ p->m_minWidth = m_minWidth;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = CSSHelpers::BParseIntoUILengthForSizing( &m_minWidth, pchString, NULL );
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_minWidth.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_minWidth );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyMinWidth &rhs = (const CStylePropertyMinWidth &)other;
+ return (m_minWidth == rhs.m_minWidth);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUILength m_minWidth;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: min-height property
+//-----------------------------------------------------------------------------
+class CStylePropertyMinHeight : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyMinHeight() : CStyleProperty( CStylePropertyMinHeight::symbol )
+ {
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyMinHeight::MergeTo" );
+ return;
+ }
+
+ CStylePropertyMinHeight *p = (CStylePropertyMinHeight *)pTarget;
+ p->m_minHeight = m_minHeight;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = CSSHelpers::BParseIntoUILengthForSizing( &m_minHeight, pchString, NULL );
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_minHeight.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_minHeight );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyMinHeight &rhs = (const CStylePropertyMinHeight &)other;
+ return (m_minHeight == rhs.m_minHeight);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUILength m_minHeight;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: max-width property
+//-----------------------------------------------------------------------------
+class CStylePropertyMaxWidth : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyMaxWidth() : CStyleProperty( CStylePropertyMaxWidth::symbol )
+ {
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyMaxWidth::MergeTo" );
+ return;
+ }
+
+ CStylePropertyMaxWidth *p = (CStylePropertyMaxWidth *)pTarget;
+ p->m_maxWidth = m_maxWidth;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ float flParentWidth, flParentHeight, flParentPerspective;
+ GetParentSizeAvailable( pPanel, flParentWidth, flParentHeight, flParentPerspective );
+
+ const CStylePropertyMaxWidth *p = (const CStylePropertyMaxWidth*)&target;
+ m_maxWidth = LerpUILength( flProgress, m_maxWidth, p->m_maxWidth, flParentWidth );
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = CSSHelpers::BParseIntoUILengthForSizing( &m_maxWidth, pchString, NULL );
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_maxWidth.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_maxWidth );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyMaxWidth &rhs = (const CStylePropertyMaxWidth &)other;
+ return (m_maxWidth == rhs.m_maxWidth);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUILength m_maxWidth;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: max-height property
+//-----------------------------------------------------------------------------
+class CStylePropertyMaxHeight : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyMaxHeight() : CStyleProperty( CStylePropertyMaxHeight::symbol )
+ {
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyMaxHeight::MergeTo" );
+ return;
+ }
+
+ CStylePropertyMaxHeight *p = (CStylePropertyMaxHeight*)pTarget;
+ p->m_maxHeight = m_maxHeight;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return true; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ float flParentWidth, flParentHeight, flParentPerspective;
+ GetParentSizeAvailable( pPanel, flParentWidth, flParentHeight, flParentPerspective );
+
+ const CStylePropertyMaxHeight *p = (const CStylePropertyMaxHeight *)&target;
+ m_maxHeight = LerpUILength( flProgress, m_maxHeight, p->m_maxHeight, flParentHeight );
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ bool bSuccess = CSSHelpers::BParseIntoUILengthForSizing( &m_maxHeight, pchString, NULL );
+ return bSuccess;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_maxHeight.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_maxHeight );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyMaxHeight &rhs = (const CStylePropertyMaxHeight &)other;
+ return (m_maxHeight == rhs.m_maxHeight);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUILength m_maxHeight;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Width property
+//-----------------------------------------------------------------------------
+class CStylePropertyVisible : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyVisible() : CStyleProperty( CStylePropertyVisible::symbol )
+ {
+ m_bVisible = true;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyHeight::MergeTo" );
+ return;
+ }
+
+ CStylePropertyVisible *p = (CStylePropertyVisible *)pTarget;
+ p->m_bVisible = m_bVisible;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( V_stricmp( "visible", pchString ) == 0 )
+ {
+ m_bVisible = true;
+ return true;
+ }
+ else if( V_stricmp( "collapse", pchString ) == 0 )
+ {
+ m_bVisible = false;
+ return true;
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ pfmtBuffer->Append( m_bVisible ? "visible" : "collapse" );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Controls if the panel is visible and is included in panel layout. "
+ "Possible values:<br>"
+ "\"visible\" - panel is visible and included in layout (default)<br>"
+ "\"collapse\" - panel is invisible and not included in layout";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyVisible &rhs = (const CStylePropertyVisible&)other;
+ return (m_bVisible == rhs.m_bVisible);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty )
+ {
+ if( !m_bVisible )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+ else
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ if( !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ bool m_bVisible;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Flow property
+//-----------------------------------------------------------------------------
+class CStylePropertyFlowChildren : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ CStylePropertyFlowChildren() : CStyleProperty( CStylePropertyFlowChildren::symbol )
+ {
+ m_eFlowDirection = k_EFlowNone;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyFlow::MergeTo" );
+ return;
+ }
+
+ CStylePropertyFlowChildren *p = (CStylePropertyFlowChildren *)pTarget;
+ p->m_eFlowDirection = m_eFlowDirection;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( V_stricmp( "none", pchString ) == 0 )
+ m_eFlowDirection = k_EFlowNone;
+ else if( V_stricmp( "down", pchString ) == 0 )
+ m_eFlowDirection = k_EFlowDown;
+ else if( V_stricmp( "right", pchString ) == 0 )
+ m_eFlowDirection = k_EFlowRight;
+ else if ( V_stricmp( "down-wrap", pchString ) == 0 )
+ m_eFlowDirection = k_EFlowDownWrap;
+ else if ( V_stricmp( "right-wrap", pchString ) == 0 )
+ m_eFlowDirection = k_EFlowRightWrap;
+ else
+ return false;
+
+ return true;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( m_eFlowDirection == k_EFlowNone )
+ pfmtBuffer->Append( "none" );
+ else if( m_eFlowDirection == k_EFlowDown )
+ pfmtBuffer->Append( "down" );
+ else if( m_eFlowDirection == k_EFlowRight )
+ pfmtBuffer->Append( "right" );
+ else if ( m_eFlowDirection == k_EFlowDownWrap )
+ pfmtBuffer->Append( "down-wrap" );
+ else if ( m_eFlowDirection == k_EFlowRightWrap )
+ pfmtBuffer->Append( "right-wrap" );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyFlowChildren &rhs = (const CStylePropertyFlowChildren&)other;
+ return (m_eFlowDirection == rhs.m_eFlowDirection);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ EFlowDirection m_eFlowDirection;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: base class for margin/padding
+//-----------------------------------------------------------------------------
+template < class T >
+class CStylePropertyDimensionsBase : public CStyleProperty
+{
+public:
+ CStylePropertyDimensionsBase() : CStyleProperty( T::symbol )
+ {
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyDimensionsBase::MergeTo" );
+ return;
+ }
+
+ T *p = (T *)pTarget;
+ if( !p->m_left.IsSet() )
+ p->m_left = m_left;
+
+ if( !p->m_top.IsSet() )
+ p->m_top = m_top;
+
+ if( !p->m_right.IsSet() )
+ p->m_right = m_right;
+
+ if( !p->m_bottom.IsSet() )
+ p->m_bottom = m_bottom;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == T::symbol )
+ {
+ // we support 1 to 4 values specified.
+ if( CSSHelpers::BParseIntoUILength( &m_top, pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_right, pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_bottom, pchString, &pchString ) )
+ {
+ if( CSSHelpers::BParseIntoUILength( &m_left, pchString, &pchString ) )
+ {
+ // got all 4
+ }
+ else
+ {
+ m_left = m_right;
+ }
+ }
+ else
+ {
+ m_left = m_right;
+ m_bottom = m_top;
+ }
+ }
+ else
+ {
+ m_right = m_top;
+ m_left = m_right;
+ m_bottom = m_top;
+ }
+
+ return true;
+ }
+ return false;
+ }
+ else if( symParsedName == T::symbolLeft )
+ {
+ return CSSHelpers::BParseIntoUILength( &m_left, pchString, NULL );
+ }
+ else if( symParsedName == T::symbolTop )
+ {
+ return CSSHelpers::BParseIntoUILength( &m_top, pchString, NULL );
+ }
+ else if( symParsedName == T::symbolBottom )
+ {
+ return CSSHelpers::BParseIntoUILength( &m_bottom, pchString, NULL );
+ }
+ else if( symParsedName == T::symbolRight )
+ {
+ return CSSHelpers::BParseIntoUILength( &m_right, pchString, NULL );
+ }
+
+ return false;
+ }
+
+ // called when we are ready to apply any scaling factor to the values
+ virtual void ApplyUIScaleFactor( float flScaleFactor )
+ {
+ m_left.ScaleLengthValue( flScaleFactor );
+ m_top.ScaleLengthValue( flScaleFactor );
+ m_bottom.ScaleLengthValue( flScaleFactor );
+ m_right.ScaleLengthValue( flScaleFactor );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_top );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_right );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_bottom );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_left );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return (m_left.IsSet() && m_top.IsSet() && m_bottom.IsSet() && m_right.IsSet());
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ if( !m_left.IsSet() )
+ m_left.SetLength( 0 );
+
+ if( !m_top.IsSet() )
+ m_top.SetLength( 0 );
+
+ if( !m_right.IsSet() )
+ m_right.SetLength( 0 );
+
+ if( !m_bottom.IsSet() )
+ m_bottom.SetLength( 0 );
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyDimensionsBase<T> &rhs = (const CStylePropertyDimensionsBase<T> &)other;
+ return (m_left == rhs.m_left && m_top == rhs.m_top && m_right == rhs.m_right && m_bottom == rhs.m_bottom);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutSizeAndPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUILength m_left;
+ CUILength m_top;
+ CUILength m_right;
+ CUILength m_bottom;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Animation properties
+//-----------------------------------------------------------------------------
+const float k_flFloatInfiniteIteration = FLT_MAX;
+class CStylePropertyAnimationProperties : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol symbolName;
+ static const CStyleSymbol symbolDuration;
+ static const CStyleSymbol symbolTiming;
+ static const CStyleSymbol symbolIteration;
+ static const CStyleSymbol symbolDirection;
+ static const CStyleSymbol symbolDelay;
+
+ CStylePropertyAnimationProperties() : CStyleProperty( CStylePropertyAnimationProperties::symbol )
+ {
+ m_bNone = false;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyAnimationProperties::MergeTo" );
+ return;
+ }
+
+ CStylePropertyAnimationProperties *p = (CStylePropertyAnimationProperties *)pTarget;
+
+ // if the other property is already set to none, don't merge
+ if( p->m_bNone )
+ return;
+
+ // if other does not yet have names set, and we are none, set other to none
+ if( m_bNone && (p->m_vecAnimationProperties.Count() == 0 || !p->m_vecAnimationProperties[0].m_symName.IsValid()) )
+ {
+ p->m_bNone = true;
+ p->m_vecAnimationProperties.RemoveAll();
+ return;
+ }
+
+ // bugbug cboyd - need to think about what to do when property counts dont match. currently, we do not change the number of properties in the
+ // target when a property name has been set as that count should override ours
+ bool bPropertiesSet = (p->m_vecAnimationProperties.Count() > 0) ? p->m_vecAnimationProperties[0].m_symName.IsValid() : false;
+
+ // add properties to target to match our count
+ if( !bPropertiesSet )
+ {
+ p->m_vecAnimationProperties.EnsureCapacity( m_vecAnimationProperties.Count() );
+ for( int i = p->m_vecAnimationProperties.Count(); i < m_vecAnimationProperties.Count(); i++ )
+ p->AddNewProperty();
+ }
+
+ // set all unset properties on target
+ FOR_EACH_VEC( m_vecAnimationProperties, i )
+ {
+ // we have more properties than the other guy. Stop processing.
+ if( bPropertiesSet && p->m_vecAnimationProperties.Count() <= i )
+ break;
+
+ AnimationProperty_t &animOther = p->m_vecAnimationProperties[i];
+ const AnimationProperty_t &animUs = m_vecAnimationProperties[i];
+
+ if( !animOther.m_symName.IsValid() )
+ animOther.m_symName = animUs.m_symName;
+
+ if( animOther.m_flDuration == k_flFloatNotSet )
+ animOther.m_flDuration = animUs.m_flDuration;
+
+ if( animOther.m_eTimingFunction == k_EAnimationUnset )
+ {
+ animOther.m_eTimingFunction = animUs.m_eTimingFunction;
+ animOther.m_CubicBezier = animUs.m_CubicBezier;
+ }
+
+ if( animOther.m_flDelay == k_flFloatNotSet )
+ animOther.m_flDelay = animUs.m_flDelay;
+
+ if( animOther.m_eAnimationDirection == k_EAnimationDirectionUnset )
+ animOther.m_eAnimationDirection = animUs.m_eAnimationDirection;
+
+ if( animOther.m_flIteration == k_flFloatNotSet )
+ animOther.m_flIteration = animUs.m_flIteration;
+ }
+ }
+
+ virtual bool BCanTransition() { return false; }
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ void AddNewProperty()
+ {
+ int iVec = m_vecAnimationProperties.AddToTail();
+ AnimationProperty_t &transition = m_vecAnimationProperties[iVec];
+
+ // copy other set properties forward
+ if( iVec == 0 )
+ {
+ transition.m_flDuration = k_flFloatNotSet;
+ transition.m_eTimingFunction = k_EAnimationUnset;
+
+ Vector2D vec[4];
+ panorama::GetAnimationCurveControlPoints( transition.m_eTimingFunction, vec );
+ transition.m_CubicBezier.SetControlPoints( vec );
+
+ transition.m_flIteration = k_flFloatNotSet;
+ transition.m_eAnimationDirection = k_EAnimationDirectionUnset;
+ transition.m_flDelay = k_flFloatNotSet;
+ }
+ else
+ {
+ transition = m_vecAnimationProperties[iVec - 1];
+ transition.m_symName = UTL_INVAL_SYMBOL;
+ }
+ }
+
+ void SetAnimation( const char *pchAnimationName, float flDuration, float flDelay, EAnimationTimingFunction eTimingFunc, CCubicBezierCurve< Vector2D > cubicBezier, EAnimationDirection eDirection, float flIterations )
+ {
+ m_bNone = false;
+ m_vecAnimationProperties.RemoveAll();
+
+ AnimationProperty_t animation;
+ animation.m_symName = pchAnimationName;
+ animation.m_eTimingFunction = eTimingFunc;
+ animation.m_CubicBezier = cubicBezier;
+ animation.m_eAnimationDirection = eDirection;
+ animation.m_flDuration = flDuration;
+ animation.m_flDelay = flDelay;
+ animation.m_flIteration = flIterations;
+
+ m_vecAnimationProperties.AddToTail( animation );
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ static CPanoramaSymbol k_symNone = "none";
+
+ if( symParsedName == symbol )
+ {
+ m_vecAnimationProperties.RemoveAll();
+
+ // transition property format: name duration timing-function delay iteration-count animation-direction [,*]
+ m_bNone = false;
+ while( *pchString != '\0' )
+ {
+ AnimationProperty_t animation;
+
+ // get the animation name
+ char rgchName[k_nCSSPropertyNameMax];
+ if( !CSSHelpers::BParseIdent( rgchName, V_ARRAYSIZE( rgchName ), pchString, &pchString ) )
+ return false;
+
+ animation.m_symName = CPanoramaSymbol( rgchName );
+ if( animation.m_symName == k_symNone )
+ return false;
+
+ // get rest
+ if( !CSSHelpers::BParseTime( &animation.m_flDuration, pchString, &pchString ) ||
+ !CSSHelpers::BParseTimingFunction( &animation.m_eTimingFunction, &animation.m_CubicBezier, pchString, &pchString ) ||
+ !CSSHelpers::BParseTime( &animation.m_flDelay, pchString, &pchString ) ||
+ !BParseIterationCount( &animation.m_flIteration, pchString, &pchString ) ||
+ !CSSHelpers::BParseAnimationDirectionFunction( &animation.m_eAnimationDirection, pchString, &pchString ) )
+ {
+ return false;
+ }
+
+ m_vecAnimationProperties.AddToTail( animation );
+
+ // see if there is another transition property
+ if( !CSSHelpers::BSkipComma( pchString, &pchString ) )
+ {
+ // end of list.. should be an empty string
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ return (pchString[0] == '\0');
+ }
+ }
+
+ return true;
+ }
+ else if( symParsedName == symbolName )
+ {
+ // comma separated list of keyframe names
+ CUtlVector< CPanoramaSymbol > vecNames;
+ if( !CSSHelpers::BParseCommaSepList( &vecNames, CSSHelpers::BParseIdentToSymbol, pchString ) )
+ return false;
+
+ // we also support 'none'
+ if( vecNames.Count() == 1 && vecNames[0] == k_symNone )
+ {
+ m_bNone = true;
+ return true;
+ }
+
+ // if we have less properties specified than other params, error
+ if( m_vecAnimationProperties.Count() > vecNames.Count() )
+ return false;
+
+ m_vecAnimationProperties.EnsureCapacity( vecNames.Count() );
+ FOR_EACH_VEC( vecNames, i )
+ {
+ if( vecNames[i] == k_symNone )
+ return false;
+
+ // new property?
+ if( m_vecAnimationProperties.Count() <= i )
+ AddNewProperty();
+
+ m_vecAnimationProperties[i].m_symName = vecNames[i];
+ }
+
+ return true;
+ }
+ else if( symParsedName == symbolDuration )
+ {
+ return BParseAndAddProperty( &AnimationProperty_t::m_flDuration, CSSHelpers::BParseTime, pchString );
+ }
+ else if( symParsedName == symbolDelay )
+ {
+ return BParseAndAddProperty( &AnimationProperty_t::m_flDelay, CSSHelpers::BParseTime, pchString );
+ }
+ else if( symParsedName == symbolTiming )
+ {
+ return BParseAndAddTimingFunction( CSSHelpers::BParseTimingFunction, pchString );
+ }
+ else if( symParsedName == symbolIteration )
+ {
+ return BParseAndAddProperty( &AnimationProperty_t::m_flIteration, BParseIterationCount, pchString );
+ }
+ else if( symParsedName == symbolDirection )
+ {
+ return BParseAndAddProperty( &AnimationProperty_t::m_eAnimationDirection, CSSHelpers::BParseAnimationDirectionFunction, pchString );
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( m_vecAnimationProperties.Count() == 0 || m_bNone )
+ {
+ pfmtBuffer->Append( "none" );
+ return;
+ }
+
+ FOR_EACH_VEC( m_vecAnimationProperties, i )
+ {
+ if( i > 0 )
+ pfmtBuffer->Append( ",\n" );
+
+ const AnimationProperty_t &prop = m_vecAnimationProperties[i];
+ pfmtBuffer->Append( prop.m_symName.String() );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendTime( pfmtBuffer, prop.m_flDuration );
+ if( prop.m_eTimingFunction != k_EAnimationCustomBezier )
+ pfmtBuffer->AppendFormat( " %s ", PchNameFromEAnimationTimingFunction( prop.m_eTimingFunction ) );
+ else
+ pfmtBuffer->AppendFormat( " cubic-bezier( %1.3f, %1.3f, %1.3f, %1.3f ) ",
+ prop.m_CubicBezier.ControlPoint( 1 ).x,
+ prop.m_CubicBezier.ControlPoint( 1 ).y,
+ prop.m_CubicBezier.ControlPoint( 2 ).x,
+ prop.m_CubicBezier.ControlPoint( 2 ).y );
+
+ CSSHelpers::AppendTime( pfmtBuffer, prop.m_flDelay );
+ pfmtBuffer->Append( " " );
+
+ // iteration count
+ if( prop.m_flIteration == k_flFloatInfiniteIteration )
+ pfmtBuffer->Append( "infinite" );
+ else
+ CSSHelpers::AppendFloat( pfmtBuffer, prop.m_flIteration );
+
+ // direction func
+ pfmtBuffer->Append( " " );
+ if( prop.m_eAnimationDirection == k_EAnimationDirectionNormal )
+ pfmtBuffer->Append( "normal" );
+ else if( prop.m_eAnimationDirection == k_EAnimationDirectionAlternate )
+ pfmtBuffer->Append( "alternate" );
+ else if ( prop.m_eAnimationDirection == k_EAnimationDirectionAlternateReverse )
+ pfmtBuffer->Append( "alternate-reverse" );
+ else if( prop.m_eAnimationDirection == k_EAnimationDirectionReverse )
+ pfmtBuffer->Append( "reverse" );
+ else if( prop.m_eAnimationDirection == k_EAnimationDirectionUnset )
+ pfmtBuffer->Append( "unset" );
+ else
+ AssertMsg( false, "Unknown animation direction" );
+ }
+ }
+
+ template < typename T >
+ bool BParseAndAddProperty( T AnimationProperty_t::*pProp, bool( *func )(T*, const char *, const char **), const char *pchString )
+ {
+ // parse comma separated list
+ CUtlVector< T > vec;
+ if( !CSSHelpers::BParseCommaSepList( &vec, func, pchString ) || vec.Count() == 0 )
+ return false;
+
+ FOR_EACH_VEC( vec, i )
+ {
+ // new property?
+ if( m_vecAnimationProperties.Count() <= i )
+ AddNewProperty();
+
+ m_vecAnimationProperties[i].*pProp = vec[i];
+ }
+
+ // if provided list is less than the total number of properties, fill in rest with last value
+ for( int i = vec.Count(); i < m_vecAnimationProperties.Count(); i++ )
+ m_vecAnimationProperties[i].*pProp = m_vecAnimationProperties[i - 1].*pProp;
+
+ return true;
+ }
+
+ bool BParseAndAddTimingFunction( bool( *func )(EAnimationTimingFunction *, CCubicBezierCurve<Vector2D> *, const char *, const char **), const char *pchString )
+ {
+ // parse comma separated list
+ CUtlVector< EAnimationTimingFunction > vec;
+ CUtlVector< CCubicBezierCurve< Vector2D > > vec2;
+ if( !CSSHelpers::BParseCommaSepList( &vec, &vec2, func, pchString ) || vec.Count() == 0 )
+ return false;
+
+ FOR_EACH_VEC( vec, i )
+ {
+ // new property?
+ if( m_vecAnimationProperties.Count() <= i )
+ AddNewProperty();
+
+ m_vecAnimationProperties[i].m_eTimingFunction = vec[i];
+ m_vecAnimationProperties[i].m_CubicBezier = vec2[i];
+ }
+
+ // if provided list is less than the total number of properties, fill in rest with last value
+ for( int i = vec.Count(); i < m_vecAnimationProperties.Count(); i++ )
+ {
+ m_vecAnimationProperties[i].m_eTimingFunction = m_vecAnimationProperties[i - 1].m_eTimingFunction;
+ m_vecAnimationProperties[i].m_CubicBezier = m_vecAnimationProperties[i - 1].m_CubicBezier;
+ }
+
+ return true;
+ }
+
+ static bool BParseIterationCount( float *pflValue, const char *pchString, const char **pchAfterParse )
+ {
+ pchString = CSSHelpers::SkipSpaces( pchString );
+
+ // special case handling for infinite
+ if( V_strnicmp( pchString, "infinite", V_strlen( "infinite" ) ) == 0 )
+ {
+ *pflValue = k_flFloatInfiniteIteration;
+ if( pchAfterParse )
+ *pchAfterParse = pchString + V_strlen( "infinite" );
+
+ return true;
+ }
+
+ // should be a number
+ return CSSHelpers::BParseNumber( pflValue, pchString, pchAfterParse );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ if( m_bNone )
+ return true;
+
+ if( m_vecAnimationProperties.Count() < 1 )
+ return false;
+
+ // if the first transition property is fully set, all other transition properties should be set
+ AnimationProperty_t &animationProperty = m_vecAnimationProperties[0];
+ return (animationProperty.m_symName.IsValid() &&
+ animationProperty.m_flDuration != k_flFloatNotSet &&
+ animationProperty.m_eTimingFunction != k_EAnimationUnset &&
+ animationProperty.m_flIteration != k_flFloatNotSet &&
+ animationProperty.m_eAnimationDirection != k_EAnimationDirectionUnset &&
+ animationProperty.m_flDelay != k_flFloatNotSet);
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ if( m_vecAnimationProperties.Count() < 1 )
+ return;
+
+ // if property names aren't set or transition time isn't set (would default to 0), remove all and exit
+ AnimationProperty_t &firstProperty = m_vecAnimationProperties[0];
+ if( !firstProperty.m_symName.IsValid() || firstProperty.m_flDuration == k_flFloatNotSet )
+ {
+ m_vecAnimationProperties.RemoveAll();
+ return;
+ }
+
+ // set defaults
+ FOR_EACH_VEC( m_vecAnimationProperties, i )
+ {
+ AnimationProperty_t &animationProperty = m_vecAnimationProperties[i];
+
+ if( animationProperty.m_eTimingFunction == k_EAnimationUnset )
+ {
+ animationProperty.m_eTimingFunction = k_EAnimationEase;
+
+ Vector2D vec[4];
+ panorama::GetAnimationCurveControlPoints( animationProperty.m_eTimingFunction, vec );
+ animationProperty.m_CubicBezier.SetControlPoints( vec );
+ }
+
+ if( animationProperty.m_flIteration == k_flFloatNotSet )
+ animationProperty.m_flIteration = 1;
+
+ if( animationProperty.m_eAnimationDirection == k_EAnimationDirectionUnset )
+ animationProperty.m_eAnimationDirection = k_EAnimationDirectionNormal;
+
+ if( animationProperty.m_flDelay == k_flFloatNotSet )
+ animationProperty.m_flDelay = 0;
+ }
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyAnimationProperties &rhs = (const CStylePropertyAnimationProperties &)other;
+ if( m_bNone != rhs.m_bNone )
+ return false;
+
+ if( m_vecAnimationProperties.Count() != rhs.m_vecAnimationProperties.Count() )
+ return false;
+
+ FOR_EACH_VEC( m_vecAnimationProperties, i )
+ {
+ if( m_vecAnimationProperties[i] != rhs.m_vecAnimationProperties[i] )
+ return false;
+ }
+
+ return true;
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_vecAnimationProperties );
+ CStyleProperty::Validate( validator, pchName );
+ }
+#endif
+
+ CUtlVector< AnimationProperty_t > m_vecAnimationProperties;
+ bool m_bNone;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Padding property
+//-----------------------------------------------------------------------------
+class CStylePropertyPadding : public CStylePropertyDimensionsBase < CStylePropertyPadding >
+{
+public:
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol symbolLeft;
+ static const CStyleSymbol symbolTop;
+ static const CStyleSymbol symbolBottom;
+ static const CStyleSymbol symbolRight;
+
+ CStylePropertyPadding() : CStylePropertyDimensionsBase<CStylePropertyPadding>() {}
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Margin property
+//-----------------------------------------------------------------------------
+class CStylePropertyMargin : public CStylePropertyDimensionsBase < CStylePropertyMargin >
+{
+public:
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol symbolLeft;
+ static const CStyleSymbol symbolTop;
+ static const CStyleSymbol symbolBottom;
+ static const CStyleSymbol symbolRight;
+
+ CStylePropertyMargin() : CStylePropertyDimensionsBase<CStylePropertyMargin>() {}
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: -s2-mix-blend-mode property
+//-----------------------------------------------------------------------------
+class CStylePropertyMixBlendMode : public CStyleProperty
+{
+public:
+
+
+ static const CStyleSymbol symbol;
+ CStylePropertyMixBlendMode() : CStyleProperty( CStylePropertyMixBlendMode::symbol )
+ {
+ m_bSet = false;
+ m_eMixBlendMode = k_EMixBlendModeNormal;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyMixBlendMode::MergeTo" );
+ return;
+ }
+
+ CStylePropertyMixBlendMode *p = (CStylePropertyMixBlendMode *)pTarget;
+ if( !p->m_bSet )
+ {
+ p->m_eMixBlendMode = m_eMixBlendMode;
+ p->m_bSet = m_bSet;
+ }
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if( V_strnicmp( pchString, "normal", V_ARRAYSIZE( "normal" ) ) == 0 )
+ {
+ m_eMixBlendMode = k_EMixBlendModeNormal;
+ m_bSet = true;
+ return true;
+ }
+ else if( V_strnicmp( pchString, "multiply", V_ARRAYSIZE( "multiply" ) ) == 0 )
+ {
+ m_eMixBlendMode = k_EMixBlendModeMultiply;
+ m_bSet = true;
+ return true;
+ }
+ else if( V_strnicmp( pchString, "screen", V_ARRAYSIZE( "screen" ) ) == 0 )
+ {
+ m_eMixBlendMode = k_EMixBlendModeScreen;
+ m_bSet = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if( m_eMixBlendMode == k_EMixBlendModeNormal )
+ pfmtBuffer->Append( "normal" );
+ else if( m_eMixBlendMode == k_EMixBlendModeMultiply )
+ pfmtBuffer->Append( "multiply" );
+ else if( m_eMixBlendMode == k_EMixBlendModeScreen )
+ pfmtBuffer->Append( "screen" );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if( symProperty == symbol )
+ {
+ return "Controls blending mode for the panel. See CSS mix-blend-mode docs on web, except normal for us is with alpha blending.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "-s2-mix-blend-mode: normal;\n"
+ "-s2-mix-blend-mode: multiply;\n"
+ "-s2-mix-blend-mode: screen;"
+ "</pre>";
+ }
+ return "";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyMixBlendMode &rhs = (const CStylePropertyMixBlendMode &)other;
+ return (m_eMixBlendMode == rhs.m_eMixBlendMode && m_bSet == rhs.m_bSet);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ EMixBlendMode m_eMixBlendMode;
+ bool m_bSet;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: texture-sampling
+//-----------------------------------------------------------------------------
+class CStylePropertyTextureSampleMode : public CStyleProperty
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyTextureSampleMode() : CStyleProperty( CStylePropertyTextureSampleMode::symbol )
+ {
+ m_bSet = false;
+ m_eTextureSampleMode = k_ETextureSampleModeNormal;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if ( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTextureSampleMode::MergeTo" );
+ return;
+ }
+
+ CStylePropertyTextureSampleMode *p = (CStylePropertyTextureSampleMode *)pTarget;
+ if ( !p->m_bSet )
+ {
+ p->m_eTextureSampleMode = m_eTextureSampleMode;
+ p->m_bSet = m_bSet;
+ }
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ )
+ {
+ }
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ pchString = CSSHelpers::SkipSpaces( pchString );
+ if ( V_strnicmp( pchString, "normal", V_ARRAYSIZE( "normal" ) ) == 0 )
+ {
+ m_eTextureSampleMode = k_ETextureSampleModeNormal;
+ m_bSet = true;
+ return true;
+ }
+ else if ( V_strnicmp( pchString, "alpha-only", V_ARRAYSIZE( "alpha-only" ) ) == 0 )
+ {
+ m_eTextureSampleMode = k_ETextureSampleModeAlphaOnly;
+ m_bSet = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ if ( m_eTextureSampleMode == k_ETextureSampleModeNormal )
+ pfmtBuffer->Append( "normal" );
+ else if ( m_eTextureSampleMode == k_ETextureSampleModeAlphaOnly )
+ pfmtBuffer->Append( "alpha-only" );
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ if ( symProperty == symbol )
+ {
+ return "Controls texture sampling mode for the panel. Set to alpha-only to use the textures alpha data across all 3 color channels.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "texture-sampling: normal;\n"
+ "texture-sampling: alpha-only;"
+ "</pre>";
+ }
+ return "";
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if ( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyTextureSampleMode &rhs = (const CStylePropertyTextureSampleMode &)other;
+ return (m_eTextureSampleMode == rhs.m_eTextureSampleMode && m_bSet == rhs.m_bSet);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ ETextureSampleMode m_eTextureSampleMode;
+ bool m_bSet;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Align property
+//-----------------------------------------------------------------------------
+class CStylePropertyAlign : public CStyleProperty
+{
+public:
+
+ static const CStyleSymbol symbol;
+ static const CStyleSymbol symbolHorizontal;
+ static const CStyleSymbol symbolVertical;
+ CStylePropertyAlign() : CStyleProperty( CStylePropertyAlign::symbol )
+ {
+ m_eHorizontalAlignment = k_EHorizontalAlignmentUnset;
+ m_eVerticalAlignment = k_EVerticalAlignmentUnset;
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyAlign::MergeTo" );
+ return;
+ }
+
+ CStylePropertyAlign *p = (CStylePropertyAlign *)pTarget;
+ if( p->m_eHorizontalAlignment == k_EHorizontalAlignmentUnset )
+ p->m_eHorizontalAlignment = m_eHorizontalAlignment;
+
+ if( p->m_eVerticalAlignment == k_EVerticalAlignmentUnset )
+ p->m_eVerticalAlignment = m_eVerticalAlignment;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ if( symParsedName == symbol )
+ {
+ return CSSHelpers::BParseHorizontalAlignment( &m_eHorizontalAlignment, pchString, &pchString ) && CSSHelpers::BParseVerticalAlignment( &m_eVerticalAlignment, pchString, &pchString );
+ }
+ else if( symParsedName == symbolHorizontal )
+ {
+ return CSSHelpers::BParseHorizontalAlignment( &m_eHorizontalAlignment, pchString, &pchString );
+ }
+ else if( symParsedName == symbolVertical )
+ {
+ return CSSHelpers::BParseVerticalAlignment( &m_eVerticalAlignment, pchString, &pchString );
+ }
+
+ return false;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ pfmtBuffer->AppendFormat( "%s %s", PchNameFromEHorizontalAlignment( m_eHorizontalAlignment ), PchNameFromEVerticalAlignment( m_eVerticalAlignment ) );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return (m_eHorizontalAlignment != k_EHorizontalAlignmentUnset && m_eVerticalAlignment != k_EVerticalAlignmentUnset);
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ if( m_eHorizontalAlignment == k_EHorizontalAlignmentUnset )
+ m_eHorizontalAlignment = k_EHorizontalAlignmentLeft;
+
+ if( m_eVerticalAlignment == k_EVerticalAlignmentUnset )
+ m_eVerticalAlignment = k_EVerticalAlignmentTop;
+ }
+
+ // Comparison function
+ virtual bool operator==(const CStyleProperty &other) const
+ {
+ if( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyAlign &rhs = (const CStylePropertyAlign &)other;
+ return (m_eHorizontalAlignment == rhs.m_eHorizontalAlignment && m_eVerticalAlignment == rhs.m_eVerticalAlignment);
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ if( !pCompareProperty || !(*this == *pCompareProperty) )
+ return k_EStyleInvalidateLayoutPosition;
+
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ EHorizontalAlignment m_eHorizontalAlignment;
+ EVerticalAlignment m_eVerticalAlignment;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Context UI Position property base class
+//-----------------------------------------------------------------------------
+class CStylePropertyContextUIPosition : public CStyleProperty
+{
+public:
+ CStylePropertyContextUIPosition( CStyleSymbol symPropertyName ) : CStyleProperty( symPropertyName )
+ {
+ for ( EContextUIPosition &ePosition : m_ePositions )
+ {
+ ePosition = k_EContextUIPositionUnset;
+ }
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if ( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTooltipPosition::MergeTo" );
+ return;
+ }
+
+ CStylePropertyContextUIPosition *p = ( CStylePropertyContextUIPosition * )pTarget;
+ for ( int i = 0; i < V_ARRAYSIZE( m_ePositions ); ++i )
+ {
+ if ( p->m_ePositions[ i ] == k_EContextUIPositionUnset )
+ p->m_ePositions[ i ] = m_ePositions[ i ];
+ }
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ char rgchPosition[ 128 ];
+
+ int i = 0;
+ while ( *pchString != '\0' )
+ {
+ if ( !CSSHelpers::BParseIdent( rgchPosition, V_ARRAYSIZE( rgchPosition ), pchString, &pchString ) )
+ return i != 0;
+
+ if ( i >= V_ARRAYSIZE( m_ePositions ) )
+ return false;
+
+ if ( V_stricmp( rgchPosition, "left" ) == 0 )
+ m_ePositions[ i ] = k_EContextUIPositionLeft;
+ else if ( V_stricmp( rgchPosition, "top" ) == 0 )
+ m_ePositions[ i ] = k_EContextUIPositionTop;
+ else if ( V_stricmp( rgchPosition, "right" ) == 0 )
+ m_ePositions[ i ] = k_EContextUIPositionRight;
+ else if ( V_stricmp( rgchPosition, "bottom" ) == 0 )
+ m_ePositions[ i ] = k_EContextUIPositionBottom;
+ else
+ return false;
+
+ ++i;
+ }
+
+ return true;
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ bool bFirst = true;
+ for ( EContextUIPosition ePosition : m_ePositions )
+ {
+ if ( bFirst )
+ {
+ bFirst = false;
+ }
+ else
+ {
+ pfmtBuffer->Append( " " );
+ }
+
+ pfmtBuffer->AppendFormat( "%s", PchNameFromEContextUIPosition( ePosition ) );
+ }
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ for ( EContextUIPosition ePosition : m_ePositions )
+ {
+ if ( ePosition == k_EContextUIPositionUnset )
+ return false;
+ }
+
+ return true;
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ ResolveDefaultPositions( m_ePositions );
+ }
+
+ static void ResolveDefaultPositions( EContextUIPosition( &ePositions )[ 4 ] )
+ {
+ // By default, pick "right" if it's not set
+ if ( ePositions[ 0 ] == k_EContextUIPositionUnset )
+ {
+ ePositions[ 0 ] = k_EContextUIPositionRight;
+ }
+
+ // By default, just swap which side the tooltip is on for the second option
+ if ( ePositions[ 1 ] == k_EContextUIPositionUnset || ePositions[ 1 ] == ePositions[ 0 ] )
+ {
+ if ( ePositions[ 0 ] == k_EContextUIPositionLeft )
+ ePositions[ 1 ] = k_EContextUIPositionRight;
+ else if ( ePositions[ 0 ] == k_EContextUIPositionRight )
+ ePositions[ 1 ] = k_EContextUIPositionLeft;
+ else if ( ePositions[ 0 ] == k_EContextUIPositionTop )
+ ePositions[ 1 ] = k_EContextUIPositionBottom;
+ else // eTooltipPositions[ 0 ] == k_EContextUIPositionBottom
+ ePositions[ 1 ] = k_EContextUIPositionTop;
+ }
+
+ // The third spot is normally the opposite of the first spot, unless those are both already used. Then it's just right or bottom.
+ if ( ePositions[ 2 ] == k_EContextUIPositionUnset || ( ePositions[ 2 ] == ePositions[ 0 ] || ePositions[ 2 ] == ePositions[ 1 ] ) )
+ {
+ if ( ( ePositions[ 0 ] == k_EContextUIPositionLeft && ePositions[ 1 ] == k_EContextUIPositionRight ) ||
+ ( ePositions[ 0 ] == k_EContextUIPositionRight && ePositions[ 1 ] == k_EContextUIPositionLeft ) )
+ {
+ ePositions[ 2 ] = k_EContextUIPositionBottom;
+ }
+ else if ( ( ePositions[ 0 ] == k_EContextUIPositionTop && ePositions[ 1 ] == k_EContextUIPositionBottom ) ||
+ ( ePositions[ 0 ] == k_EContextUIPositionBottom && ePositions[ 1 ] == k_EContextUIPositionTop ) )
+ {
+ ePositions[ 2 ] = k_EContextUIPositionRight;
+ }
+ else
+ {
+ if ( ePositions[ 0 ] == k_EContextUIPositionLeft )
+ ePositions[ 2 ] = k_EContextUIPositionRight;
+ else if ( ePositions[ 0 ] == k_EContextUIPositionRight )
+ ePositions[ 2 ] = k_EContextUIPositionLeft;
+ else if ( ePositions[ 0 ] == k_EContextUIPositionTop )
+ ePositions[ 2 ] = k_EContextUIPositionBottom;
+ else // eTooltipPositions[ 0 ] == k_EContextUIPositionBottom
+ ePositions[ 2 ] = k_EContextUIPositionTop;
+ }
+ }
+
+ // The last spot is just whatever is still leftover
+ if ( ePositions[ 3 ] == k_EContextUIPositionUnset || ( ePositions[ 3 ] == ePositions[ 0 ] || ePositions[ 3 ] == ePositions[ 1 ] || ePositions[ 3 ] == ePositions[ 2 ] ) )
+ {
+ CUtlVector< EContextUIPosition > vecPositions( 0, 4 );
+ const EContextUIPosition arrAllPositions[] = { k_EContextUIPositionLeft, k_EContextUIPositionTop, k_EContextUIPositionRight, k_EContextUIPositionBottom };
+ vecPositions.CopyArray( arrAllPositions, V_ARRAYSIZE( arrAllPositions ) );
+ for ( int i = 0; i < 3; ++i )
+ {
+ vecPositions.FindAndFastRemove( ePositions[ i ] );
+ }
+ ePositions[ 3 ] = vecPositions[ 0 ];
+ }
+ }
+
+ // Comparison function
+ virtual bool operator==( const CStyleProperty &other ) const
+ {
+ if ( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyContextUIPosition &rhs = ( const CStylePropertyContextUIPosition & )other;
+
+ for ( int i = 0; i < V_ARRAYSIZE( m_ePositions ); ++i )
+ {
+ if ( m_ePositions[ i ] != rhs.m_ePositions[ i ] )
+ return false;
+ }
+
+ return true;
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ EContextUIPosition m_ePositions[ 4 ];
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Tooltip Position property
+//-----------------------------------------------------------------------------
+class CStylePropertyTooltipPosition : public CStylePropertyContextUIPosition
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyTooltipPosition() : CStylePropertyContextUIPosition( CStylePropertyTooltipPosition::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies where to position a tooltip relative to this panel. Valid options include 'left', 'top', 'right', and 'bottom'. "
+ "List up to 4 positions to determine the order that positions are tried if the tooltip doesn't fully fit on screen. Default "
+ "is 'right left bottom top'. If less than 4 positions are specified, the tooltip first tries the opposite of the specified "
+ "position along the same axis before switching to the other axis.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "tooltip-position: bottom;\n"
+ "tooltip-position: left bottom;"
+ "</pre>";
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Context Menu Position property
+//-----------------------------------------------------------------------------
+class CStylePropertyContextMenuPosition : public CStylePropertyContextUIPosition
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyContextMenuPosition() : CStylePropertyContextUIPosition( CStylePropertyContextMenuPosition::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies where to position a context menu relative to this panel. Valid options include 'left', 'top', 'right', and 'bottom'. "
+ "List up to 4 positions to determine the order that positions are tried if the context menu doesn't fully fit on screen. Default "
+ "is 'right left bottom top'. If less than 4 positions are specified, the context menu first tries the opposite of the specified "
+ "position along the same axis before switching to the other axis.<br><br>"
+ "<b>Examples:</b>"
+ "<pre>"
+ "context-menu-position: bottom;\n"
+ "context-menu-position: left bottom;"
+ "</pre>";
+ }
+};
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Base class for ContextUI Component Position properties
+//-----------------------------------------------------------------------------
+class CStylePropertyContextUIComponentPosition : public CStyleProperty
+{
+public:
+ CStylePropertyContextUIComponentPosition( CStyleSymbol symPropertyName ) : CStyleProperty( symPropertyName )
+ {
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if ( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertyTooltipComponentPosition::MergeTo" );
+ return;
+ }
+
+ CStylePropertyContextUIComponentPosition *p = ( CStylePropertyContextUIComponentPosition * )pTarget;
+ if ( !p->m_HorizontalPosition.IsSet() )
+ {
+ p->m_HorizontalPosition = m_HorizontalPosition;
+ }
+ if ( !p->m_VerticalPosition.IsSet() )
+ {
+ p->m_VerticalPosition = m_VerticalPosition;
+ }
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ return CSSHelpers::BParseIntoTwoUILengths( &m_HorizontalPosition, &m_VerticalPosition, pchString, &pchString );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ CSSHelpers::AppendUILength( pfmtBuffer, m_HorizontalPosition );
+ pfmtBuffer->Append( " " );
+ CSSHelpers::AppendUILength( pfmtBuffer, m_VerticalPosition );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return m_HorizontalPosition.IsSet() && m_VerticalPosition.IsSet();
+ }
+
+ // Comparison function
+ virtual bool operator==( const CStyleProperty &other ) const
+ {
+ if ( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertyContextUIComponentPosition &rhs = ( const CStylePropertyContextUIComponentPosition & )other;
+ return m_HorizontalPosition == rhs.m_HorizontalPosition && m_VerticalPosition == rhs.m_VerticalPosition;
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const { return k_EStyleInvalidateLayoutNone; }
+
+ CUILength m_HorizontalPosition;
+ CUILength m_VerticalPosition;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: ContextUI Body Position property base class
+//-----------------------------------------------------------------------------
+class CStylePropertyContextUIBodyPosition : public CStylePropertyContextUIComponentPosition
+{
+public:
+ CStylePropertyContextUIBodyPosition( CStyleSymbol symPropertyName ) : CStylePropertyContextUIComponentPosition( symPropertyName )
+ {
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ ResolveDefaultBodyPosition( m_HorizontalPosition, m_VerticalPosition );
+ }
+
+ static void ResolveDefaultBodyPosition( CUILength &horizontalPosition, CUILength &verticalPosition )
+ {
+ if ( !horizontalPosition.IsSet() )
+ {
+ horizontalPosition.SetPercent( 0.0f );
+ }
+
+ if ( !verticalPosition.IsSet() )
+ {
+ verticalPosition.SetPercent( 0.0f );
+ }
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Tooltip Body Position property
+//-----------------------------------------------------------------------------
+class CStylePropertyTooltipBodyPosition : public CStylePropertyContextUIBodyPosition
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyTooltipBodyPosition() : CStylePropertyContextUIBodyPosition( CStylePropertyTooltipBodyPosition::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies where to position the body of a tooltip relative to this panel. The first value controls how the body is "
+ "aligned horizontally when the tooltip is to the top or bottom of the panel, and the second value controls how the body is "
+ "aligned vertically when the tooltip is to the left or right of the panel. 0% means left/top aligned, 50% means "
+ "center/middle aligned, and 100% means right/bottom aligned. Default is '0% 0%'.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "tooltip-body-position: 50% 100%;"
+ "</pre>";
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Context Menu Body Position property
+//-----------------------------------------------------------------------------
+class CStylePropertyContextMenuBodyPosition : public CStylePropertyContextUIBodyPosition
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyContextMenuBodyPosition() : CStylePropertyContextUIBodyPosition( CStylePropertyContextMenuBodyPosition::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies where to position the body of a context menu relative to this panel. The first value controls how the body is "
+ "aligned horizontally when the context menu is to the top or bottom of the panel, and the second value controls how the body is "
+ "aligned vertically when the context menu is to the left or right of the panel. 0% means left/top aligned, 50% means "
+ "center/middle aligned, and 100% means right/bottom aligned. Default is '0% 0%'.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "context-menu-body-position: 50% 100%;"
+ "</pre>";
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: ContextUI Arrow Position property base class
+//-----------------------------------------------------------------------------
+class CStylePropertyContextUIArrowPosition : public CStylePropertyContextUIComponentPosition
+{
+public:
+ CStylePropertyContextUIArrowPosition( CStyleSymbol symPropertyName ) : CStylePropertyContextUIComponentPosition( symPropertyName )
+ {
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ ResolveDefaultArrowPosition( m_HorizontalPosition, m_VerticalPosition );
+ }
+
+ static void ResolveDefaultArrowPosition( CUILength &horizontalPosition, CUILength &verticalPosition )
+ {
+ if ( !horizontalPosition.IsSet() )
+ {
+ horizontalPosition.SetPercent( 50.0f );
+ }
+
+ if ( !verticalPosition.IsSet() )
+ {
+ verticalPosition.SetPercent( 50.0f );
+ }
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Tooltip Arrow Position property
+//-----------------------------------------------------------------------------
+class CStylePropertyTooltipArrowPosition : public CStylePropertyContextUIArrowPosition
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyTooltipArrowPosition() : CStylePropertyContextUIArrowPosition( CStylePropertyTooltipArrowPosition::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies where to point the arrow of a tooltip at on this panel. The first value controls how the arrow is "
+ "positioned horizontally when the tooltip is to the top or bottom of the panel, and the second value controls how the arrow is "
+ "positioned vertically when the tooltip is to the left or right of the panel. Default is '50% 50%'.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "tooltip-arrow-position: 25% 50%;"
+ "</pre>";
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Context Menu Arrow Position property
+//-----------------------------------------------------------------------------
+class CStylePropertyContextMenuArrowPosition : public CStylePropertyContextUIArrowPosition
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyContextMenuArrowPosition() : CStylePropertyContextUIArrowPosition( CStylePropertyContextMenuArrowPosition::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies where to point the arrow of a context menu at on this panel. The first value controls how the arrow is "
+ "positioned horizontally when the context menu is to the top or bottom of the panel, and the second value controls how the arrow is "
+ "positioned vertically when the context menu is to the left or right of the panel. Default is '50% 50%'.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "context-menu-arrow-position: 25% 50%;"
+ "</pre>";
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Sound property base class
+//-----------------------------------------------------------------------------
+class CStylePropertySound : public CStyleProperty
+{
+public:
+ CStylePropertySound( CStyleSymbol symPropertyName ) : CStyleProperty( symPropertyName )
+ {
+ }
+
+ virtual void MergeTo( CStyleProperty *pTarget ) const
+ {
+ if ( pTarget->GetPropertySymbol() != GetPropertySymbol() )
+ {
+ AssertMsg( false, "Mismatched types to CStylePropertySound::MergeTo" );
+ return;
+ }
+
+ CStylePropertySound *p = ( CStylePropertySound * )pTarget;
+ if ( p->m_strSoundName.IsEmpty() )
+ p->m_strSoundName = m_strSoundName;
+ }
+
+ // Can this property support animation?
+ virtual bool BCanTransition() { return false; }
+
+ // Interpolation func for animation of this property
+ virtual void Interpolate( IUIPanel *pPanel, const CStyleProperty &target, float flProgress /* 0.0->1.0 */ ) {}
+
+ // Parses string and sets value
+ virtual bool BSetFromString( CStyleSymbol symParsedName, const char *pchString )
+ {
+ return CSSHelpers::BParseQuotedString( m_strSoundName, pchString );
+ }
+
+ // Gets string representation of property
+ virtual void ToString( CFmtStr1024 *pfmtBuffer ) const
+ {
+ pfmtBuffer->AppendFormat( "\"%s\"", m_strSoundName.Get() );
+ }
+
+ // When applying styles to an element, used to determine if all data for this property has been set or if more fields should be found
+ // by looking at lower weight styles
+ virtual bool BFullySet()
+ {
+ return !m_strSoundName.IsEmpty();
+ }
+
+ // called when applied to a panel. Gives the style an opportunity to change any unset values to defaults
+ virtual void ResolveDefaultValues()
+ {
+ }
+
+ // Comparison function
+ virtual bool operator==( const CStyleProperty &other ) const
+ {
+ if ( GetPropertySymbol() != other.GetPropertySymbol() )
+ return false;
+
+ const CStylePropertySound &rhs = ( const CStylePropertySound & )other;
+ return m_strSoundName == rhs.m_strSoundName;
+ }
+
+ // Layout pieces that can be invalidated when the property is applied to a panel
+ virtual EStyleInvalidateLayout GetInvalidateLayout( CStyleProperty *pCompareProperty ) const
+ {
+ return k_EStyleInvalidateLayoutNone;
+ }
+
+ CUtlString m_strSoundName;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Entrance sound property
+//-----------------------------------------------------------------------------
+class CStylePropertyEntranceSound : public CStylePropertySound
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyEntranceSound() : CStylePropertySound( CStylePropertyEntranceSound::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies a sound name to play when this selector is applied.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "sound: \"whoosh_in\";"
+ "</pre>";
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Exit sound property
+//-----------------------------------------------------------------------------
+class CStylePropertyExitSound : public CStylePropertySound
+{
+public:
+ static const CStyleSymbol symbol;
+ CStylePropertyExitSound() : CStylePropertySound( CStylePropertyExitSound::symbol )
+ {
+ }
+
+ // Return a description for this property which will be shown in the debugger
+ virtual const char *GetDescription( CStyleSymbol symProperty )
+ {
+ return "Specifies a sound name to play when this selector is removed.<br><br>"
+ "<b>Example:</b>"
+ "<pre>"
+ "sound-out: \"whoosh_out\";"
+ "</pre>";
+ }
+};
+
+
+} // namespace panorama
+
+#endif // STYLEPROPERTIES_H \ No newline at end of file
diff --git a/public/panorama/source2/ipanoramaui.h b/public/panorama/source2/ipanoramaui.h
new file mode 100644
index 0000000..b5da2e8
--- /dev/null
+++ b/public/panorama/source2/ipanoramaui.h
@@ -0,0 +1,62 @@
+//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
+//
+//==================================================================================================
+
+#if !defined( __IPANORAMAUI_H__ )
+#define __IPANORAMAUI_H__
+
+
+#include "appframework/iappsystem.h"
+#include "tier3/tier3.h"
+#include "inputsystem/inputenums.h"
+#include "inputsystem/buttoncode.h"
+#include "tier1/refcount.h"
+#include "../game/client/iwordfilter.h"
+#include "vscript/ivscript.h"
+#include "rendersystem/irenderdevice.h"
+
+
+// Manages the communication between panorama_client-level code and
+// the Panorama core in panorama.dll.
+class IPanoramaUIEngine : public IAppSystem
+{
+public:
+ virtual bool SetupUIEngine() = 0;
+ virtual void ShutdownUIEngine() = 0;
+
+ // Access UI engine, generally use global panorama::UIEngine() accessor instead as shorthand
+ virtual panorama::IUIEngine * AccessUIEngine() = 0;
+
+ virtual bool HandleInputEvent( const InputEvent_t &event, const CUtlVector<panorama::IUIWindow *> &vecWindowInputOrder, bool bOnlyIfFocused ) = 0;
+};
+
+
+//
+// Panorama class wrappers to make methods virtual for cross-DLL calling.
+//
+
+class IPanoramaClientDebugger
+{
+public:
+ virtual ~IPanoramaClientDebugger() {}
+
+ virtual void BeginInspect() = 0;
+ virtual float GetSplitterPosition() = 0;
+ virtual void SetSplitterPosition( float flParentFlowValue ) = 0;
+};
+
+// Manages the communication between non-Panorama code and
+// a component using panorama_client.
+class IPanoramaUIClient : public IAppSystem
+{
+public:
+ virtual panorama::IUIEngine *SetupUIEngine( const char *pszLanguage, PlatWindow_t hWindow ) = 0;
+ virtual void ShutdownUIEngine() = 0;
+
+ virtual bool HandleInputEvent( const InputEvent_t &event, const CUtlVector<panorama::IUIWindow *> &vecWindowInputOrder, bool bOnlyIfFocused ) = 0;
+
+ virtual panorama::IUIPanelClient *CreatePanel2D( panorama::IUIWindow *pParent, const char *pID ) = 0;
+ virtual IPanoramaClientDebugger *CreateDebugger( panorama::IUIWindow *pParent, const char *pID ) = 0;
+};
+
+#endif
diff --git a/public/panorama/text/iuitextlayout.h b/public/panorama/text/iuitextlayout.h
new file mode 100644
index 0000000..2dd92c8
--- /dev/null
+++ b/public/panorama/text/iuitextlayout.h
@@ -0,0 +1,69 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef IUITEXTLAYOUT_H
+#define IUITEXTLAYOUT_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "mathlib/mathlib.h"
+#include "mathlib/vector2d.h"
+#include "tier1/utlvector.h"
+#include "panorama/panoramatypes.h"
+
+namespace panorama
+{
+
+//
+// Interface that needs to be implemented for text layout on all platforms
+//
+class IUITextLayout
+{
+public:
+ virtual ~IUITextLayout() {}
+
+ // Set formatting for character ranges
+ virtual void SetFontName( uint32 unCharStartIndex, uint32 unCharEndIndex, const char *pchFontName ) = 0;
+ virtual void SetFontSize( uint32 unCharStartIndex, uint32 unCharEndIndex, float flFontSize ) = 0;
+ virtual void SetFontStyle( uint32 unCharStartIndex, uint32 unCharEndIndex, EFontStyle eFontStyle ) = 0;
+ virtual void SetFontWeight( uint32 unCharStartIndex, uint32 unCharEndIndex, EFontWeight eFontWeight ) = 0;
+ virtual void SetUnderline( uint32 unCharStartIndex, uint32 unCharEndIndex, bool bUnderline ) = 0;
+ virtual void SetStrikethrough( uint32 unCharStartIndex, uint32 unCharEndIndex, bool bStrikethrough ) = 0;
+ virtual void SetInlineObject( uint32 unCharIndex, float flWidth, float flHeight ) = 0;
+ virtual void MarkColorRangeForMeasurement( uint32 unCharStartIndex, uint32 unCharEndIndex ) = 0;
+
+ // Gets the size required to fully draw the text layout
+ virtual void GetRequiredSize( float &flWidth, float &flHeight ) = 0;
+
+ // Hit tests a point against the text layout.
+ // unHitRunLength returns the character index hit
+ // bIsTrailingHit indicates whether the hit is on the leading or trailing side of the char
+ // bInside is true if the hit is within the text region, when false the position closest the point is returned as
+ // the character hit offset
+ virtual void HitTestPoint( Vector2D point, uint32 &unFirstHitOffset, bool &bIsTrailingHit, bool &bIsInsideString ) = 0;
+
+ // Struct used in some calls below
+ struct HitTestRegionRect_t
+ {
+ Vector2D topLeft;
+ Vector2D bottomRight;
+ uint32 unCharStart;
+ uint32 unCharEnd;
+ bool bIsText;
+ bool bIsTrimmed;
+ };
+
+ // Determines the layout coordinates for a given character offset, coordinates are relative to top left of text layout
+ virtual void GetCharacterCoordinates( uint32 unCharIndex, HitTestRegionRect_t &charRegionRect ) = 0;
+
+ // Determines a vector of rects enclosing a range of text, normally used for getting selection highlight regions
+ virtual void GetCharacterRangeCoordinates( uint32 unCharStartIndex, uint32 unCharEndIndex, CUtlVector<HitTestRegionRect_t> &vecRangeRegionRects ) = 0;
+};
+
+} // namespace panorama
+
+#endif // IUITEXTLAYOUT_H \ No newline at end of file
diff --git a/public/panorama/textinput/textinput.h b/public/panorama/textinput/textinput.h
new file mode 100644
index 0000000..2403b74
--- /dev/null
+++ b/public/panorama/textinput/textinput.h
@@ -0,0 +1,109 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_TEXTINPUT_H
+#define PANORAMA_TEXTINPUT_H
+
+#include "panorama/controls/panel2d.h"
+#include "panorama/input/iuiinput.h"
+
+namespace panorama
+{
+
+class ITextInputControl;
+class CTextInputHandlerSettings;
+
+// When text input finished, bool = true for Done, = false for Cancel; char const * = string that user typed
+// Dispatched to ITextInputControl::GetAssociatedPanel()
+DECLARE_PANEL_EVENT2( TextInputFinished, bool, char const * );
+
+// When the handler is up and sees gamepad right-stick input, it passes it through to the containing
+// control, so the control can do something with it. Dispatched to ITextInputControl::GetAssociatedPanel()
+DECLARE_PANEL_EVENT1( TextInputAnalogStickPassthrough, GamePadData_t );
+
+panorama::ETextInputHandlerType_t ETextInputHandlerType_tFromName( const char *pchName );
+const char *PchNameFromETextInputHandlerType_t( int eType );
+
+//
+// Input submodes for text input handlers, used also by textentry
+//
+enum ETextInputMode_t
+{
+ k_ETextInputModeNormal,
+ k_ETextInputModeNormalLower,
+ k_ETextInputModePassword,
+ k_ETextInputModeEmail,
+ k_ETextInputModeNumeric,
+ k_ETextInputModeNumericPassword,
+ k_ETextInputModeURL,
+ k_ETextInputModeSteamCode,
+ k_ETextInputModePhoneNumber,
+};
+
+ETextInputMode_t ETextInputMode_tFromName( const char *pchName );
+const char *PchNameFromETextInputMode_t( int eMode );
+
+//-----------------------------------------------------------------------------
+// Purpose: an interface that the text input uses to feed and be fed text
+//-----------------------------------------------------------------------------
+class ITextInputControl
+{
+public:
+ virtual ~ITextInputControl() {}
+
+ virtual bool OnKeyDown( const KeyData_t &code ) = 0;
+ virtual bool OnKeyUp( const KeyData_t & code ) = 0;
+ virtual bool OnKeyTyped( const KeyData_t &unichar ) = 0;
+
+ // return true if you own the backing store of the text and can return it immediately on request,
+ // false otherwise (html returns false here)
+ virtual bool BSupportsImmediateTextReturn() = 0;
+
+ virtual int32 GetCursorOffset() const = 0;
+ virtual uint GetCharCount() const = 0;
+
+ virtual const char *PchGetText() const = 0;
+ virtual const wchar_t *PwchGetText() const = 0;
+
+ virtual void InsertCharacterAtCursor( const wchar_t &unichar ) = 0;
+ virtual void InsertCharactersAtCursor( const wchar_t *pwch, size_t cwch ) = 0;
+
+ virtual CPanel2D *GetAssociatedPanel() = 0;
+
+ // request string the control now contains
+ virtual void RequestControlString() = 0;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: The interface over a text input handler. Derives from CPanel2D
+// for convenience.
+//-----------------------------------------------------------------------------
+class CTextInputHandler : public panorama::CPanel2D
+{
+public:
+ CTextInputHandler( panorama::IUIWindow *pParent, const char *pchID );
+ CTextInputHandler( panorama::CPanel2D *pParent, const char *pchID );
+ virtual ~CTextInputHandler();
+
+ virtual void OpenHandler() = 0;
+ void CloseHandler( bool bCommitText );
+ virtual ETextInputHandlerType_t GetType() = 0;
+ virtual ITextInputControl *GetControlInterface() = 0;
+ virtual void SuggestWord( const wchar_t *pwch, int ich ) = 0;
+ virtual void SetYButtonAction( const char *pchLabel, IUIEvent *pEvent ) = 0;
+
+protected:
+ virtual void CloseHandlerImpl( bool bCommitText ) = 0;
+};
+
+// Factory methods
+CTextInputHandler *CreateTextInputHandler( panorama::IUIWindow *pParent, const CTextInputHandlerSettings &settings, ITextInputControl *pControl );
+CTextInputHandler *CreateTextInputHandler( panorama::CPanel2D *pParent, const CTextInputHandlerSettings &settings, ITextInputControl *pControl );
+
+} // namespace panorama
+
+#endif // PANORAMA_TEXTINPUT_H
+
diff --git a/public/panorama/textinput/textinput_daisywheel.h b/public/panorama/textinput/textinput_daisywheel.h
new file mode 100644
index 0000000..a523fc9
--- /dev/null
+++ b/public/panorama/textinput/textinput_daisywheel.h
@@ -0,0 +1,377 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_TEXTINPUT_DAISYWHEEL_H
+#define PANORAMA_TEXTINPUT_DAISYWHEEL_H
+
+#include "panorama/textinput/textinput.h"
+#include "panorama/controls/panel2d.h"
+#include "panorama/controls/label.h"
+#include "panorama/input/iuiinput.h"
+#include "mathlib/beziercurve.h"
+#include "tier1/utlptr.h"
+#include "panorama/uischeduleddel.h"
+
+namespace panorama
+{
+
+// Forward declaration
+class CTextInputDaisyWheel;
+class CTextEntry;
+class ITextInputSuggest;
+class CLabel;
+
+//-----------------------------------------------------------------------------
+// Purpose: Implementation of daisy wheel text input handler
+//-----------------------------------------------------------------------------
+class CTextInputDaisyWheel : public panorama::CTextInputHandler
+{
+ DECLARE_PANEL2D( CTextInputDaisyWheel, panorama::CPanel2D );
+
+public:
+ // Constructor
+ CTextInputDaisyWheel( panorama::IUIWindow *pParent, const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
+ CTextInputDaisyWheel( panorama::CPanel2D *parent, const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
+
+ // Destructor
+ ~CTextInputDaisyWheel();
+
+ // CTextInputHandler overrides
+ virtual void OpenHandler() OVERRIDE;
+ virtual void CloseHandlerImpl( bool bCommitText ) OVERRIDE;
+ virtual ETextInputHandlerType_t GetType() OVERRIDE;
+ virtual ITextInputControl *GetControlInterface() OVERRIDE;
+ virtual void SuggestWord( const wchar_t *pwch, int ich ) OVERRIDE;
+ virtual void SetYButtonAction( const char *pchLabel, IUIEvent *pEvent ) OVERRIDE;
+
+ static void GetSupportedLanguages( CUtlVector<ELanguage> &vecLangs );
+private:
+ void Initialize( const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
+
+ // This isn't part of CTextInputHandler because currently there is no need to set this dynamically
+ void SetMode( ETextInputMode_t mode );
+
+ // CPanel2D overrides
+ virtual bool OnGamePadUp( const panorama::GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadDown( const panorama::GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadAnalog( const panorama::GamePadData_t &code ) OVERRIDE;
+ virtual bool OnKeyTyped( const KeyData_t &unichar ) OVERRIDE;
+ virtual bool OnKeyDown( const KeyData_t &code ) OVERRIDE;
+ virtual bool OnKeyUp( const KeyData_t &code ) OVERRIDE;
+
+ //
+ // Daisy wheel input type
+ //
+ enum EDaisyInputType_t
+ {
+ k_EDaisyInputTypeABXY, // ABXY layout has color buttons printing keys
+ k_EDaisyInputTypeRS, // RS layout requires Right Stick usage to print keys
+ k_EDaisyInputTypePIN, // Button map to numbers for secret PIN entry
+ };
+
+ // Set daisy wheel type
+ void SetDaisyInputType( EDaisyInputType_t eType );
+
+ // Add an emoticon to the list of emoji this daisywheel will show
+ // TODO: Currently not part of CTextInputHandler because emoticons need work
+ void AddEmoticon( const char *szInsert, const char *szImageURL );
+ void CommitEmoticons();
+
+#ifdef DBGFLAG_VALIDATE
+ void ValidateClientPanel( CValidator &validator, const tchar *pchName );
+#endif
+
+ // User wants to move focus to the next field on the page
+ bool NextFocus();
+
+ static const int k_cPetals = 8; // # petals in flower (hardcoded for now)
+ static const int k_cItemsPerPetal = 4; // # letters visible on each petal, max
+ static const int k_cItemsPerLayoutMax = k_cPetals * k_cItemsPerPetal; // # letters total per layout, max
+
+ struct Emoticon_t
+ {
+ CUtlString sType;
+ CUtlString sImageURL;
+ };
+
+ //
+ // A single wheel layout configuration: name and UTF-8 sequences of characters
+ // Structure is allocated with more memory at the end of the structure, name and
+ // UTF-8 sequences follow this structure object
+ //
+ class CDaisyConfig
+ {
+ public:
+ CDaisyConfig( const char *pchName ) : m_sName( pchName )
+ {
+ }
+
+ // Get the name of wheel layout
+ char const * GetName() const { return m_sName.String(); }
+
+ // Get number of items in this wheel layout
+ int GetNumItems() const { return m_cItems; }
+
+ // Get a given item in this wheel layout, must be >= zero and < number of items
+ // double the index, because each item is NUL terminated
+ const char * GetItem( int idx ) const
+ {
+ if ( idx >= k_cItemsPerLayoutMax || idx < 0 )
+ {
+ Assert( false );
+ return "";
+ }
+
+ return m_vecText.Base() + m_rgich[ idx ];
+ }
+
+ #ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_sName );
+ ValidateObj( m_vecText );
+ }
+ #endif
+
+ // name of this layout
+ CUtlString m_sName;
+
+ // Number of items in this wheel layout
+ int m_cItems;
+
+ // offsets into the text block for each item in this layout
+ int m_rgich[ k_cItemsPerLayoutMax ];
+
+ // block of text for this layout, UTF-8
+ CUtlVector< char > m_vecText;
+ };
+
+ // After configuration has been loaded and assigned walk through all
+ // controls and set their values to represent the loaded config
+ void SetControlsFromConfiguration();
+
+ // map the trigger inputs to a config
+ enum EDaisyConfig_t
+ {
+ k_EDaisyConfigNone = -1,
+ k_EDaisyConfigCaps,
+ k_EDaisyConfigLetters,
+ k_EDaisyConfigNumbers,
+ k_EDaisyConfigSpecial,
+ k_EDaisyConfigNumbersOnly,
+ k_EDaisyConfigPhoneNumber,
+ k_EDaisyConfigSteamCodeChars,
+ k_EDaisyConfigEmoji,
+ };
+ typedef CUtlMap< EDaisyConfig_t, CUtlPtr< CDaisyConfig >, int, CDefLess< EDaisyConfig_t > > MapConfigEntries_t;
+
+ EDaisyConfig_t EDaisyConfigFromString( const char *pchValue );
+ EDaisyConfig_t ConfigFromTriggerState( bool bLeftTrigger, bool bRightTrigger );
+
+ // update the trigger legends based on the current trigger state
+ void UpdateTriggerLegends();
+
+ // moves controls to existing config (caps -> lowercase)
+ void AdvanceControlsConfiguration( EDaisyConfig_t eConfig );
+
+ // Types a character from selected group's side of world: "E" | "W" | "N" | "S"
+ bool TypeCharacterFromSide( char chSide );
+
+ // Types a given wide character into text entry
+ bool TypeWchar( uchar16 wch );
+
+ // Simulates a key down event
+ bool TypeKeyDown( panorama::KeyCode eCode );
+
+ // Loads configuration file for specified language
+ bool LoadInputConfigurationFile( ELanguage language );
+
+ // Loads configuration file
+ bool LoadInputConfigurationFile( const char *szConfig, const char *szConfigRootDir );
+
+ // Builds configuration structure based on buffer loaded from config file
+ bool LoadConfigurationBuffer( char const *pszBase, MapConfigEntries_t *pmapConfigs );
+
+ // Switch between most recent languages
+ bool SwitchLanguage();
+ bool ShowThisLanguage( ELanguage language );
+
+ // For a given config item determine which group and group side the item should be at
+ void GetItemLocation( CDaisyConfig *pCfg, int iItem, char const *&szGroup, char const *&szItem );
+
+ // Get name of the group square indexed by -1|0|1 pair of x,y coordinates; returns side or wolrd like: "E" | "NE" | "N" | "NW" | etc.
+ char const * GetGroupNameSq( int x, int y );
+
+ // Gets a sequential index of the group square indexed by -1|0|1 pair of x,y coordinates
+ int GetGroupIdxSq( int x, int y );
+
+ // Gets the side of world name of group by its sequential index
+ char const * GetGroup( int idxGroup );
+
+ // Gets the side of world name of item by its sequential index
+ char const * GetSide( int idxSide );
+
+ // Process scheduled key repeat
+ void ScheduleKeyRepeats( panorama::GamePadCode eCode );
+ void CancelOutstandingRepeats() { ScheduleKeyRepeats( XK_NULL ); }
+
+ void ScheduledKeyRepeatFunction();
+
+ bool HandlePropertyTransitionEnd( const panorama::CPanelPtr< panorama::IUIPanel > &pPanel, CStyleSymbol sym );
+
+ // Listen for focus lost
+ bool HandleInputFocusLost( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+
+ // events bound in window_keybinds.cfg
+ bool ShowHideSettings();
+
+ // settings events
+ bool CancelSettings();
+
+ // auto-suggestion
+ void ShowSuggestion( const char *szPrefix, const char *szSuffix );
+ void ClearSuggestionVisual()
+ {
+ ShowSuggestion( "", "" );
+ }
+ void ClearSuggestionState()
+ {
+ m_sSuggestion.Clear();
+ ClearSuggestionVisual();
+ }
+
+ bool BCursorAtStartOfSentence();
+ bool BConvertNextSpaceToPeriod();
+
+ // Play sound for a give daisy wheel activity
+ enum EDaisyAction_t
+ {
+ k_EDaisySound_ButtonA,
+ k_EDaisySound_ButtonB,
+ k_EDaisySound_ButtonX,
+ k_EDaisySound_ButtonY,
+ k_EDaisySound_KeySpacebar,
+ k_EDaisySound_KeyBackspace,
+ k_EDaisySound_KeyLeft,
+ k_EDaisySound_KeyRight,
+ k_EDaisySound_KeyHome,
+ k_EDaisySound_KeyEnd,
+ k_EDaisySound_FocusAreaChanged,
+ k_EDaisySound_ConfigChanged,
+ k_EDaisySound_FocusAreaCold,
+ k_EDaisySound_PerformAutosuggest,
+ };
+ void PlayDaisyActionSound( EDaisyAction_t eAction );
+
+ // Function to handle gamepad data depending on daisy wheel settings
+ typedef bool (CTextInputDaisyWheel::*PFNGamePadData)( const panorama::GamePadData_t &code );
+
+ MapConfigEntries_t m_mapConfigEntries; // Processed configuration entries
+ EDaisyConfig_t m_eConfigCurrent; // Current config, can be cycled with triggers
+ bool m_bRestrictConfig; // if true, stick to current config (no changing layouts)
+
+ panorama::CPanel2D *m_pStickPri; // Primary stick control
+ float m_flStickPriSelectOct[2]; // Selection octant angles (std: lo=M_PI/6, hi=M_PI/3)
+ float m_flStickPriMoveScale[2]; // Scale for primary stick movement
+ float m_flStickPriSelectDist[2]; // Selection distances
+ float m_flStickPriSelectAngleSticky; // Selection angle to stick to area
+ float m_flStickPriColdTime; // How long we need primary stick to remain cold
+ int m_nSelectionGroup[2]; // Currently selected group
+
+ panorama::CPanel2D *m_pStickSnd; // Secondary stick control
+ float m_flStickSndMoveScale[2]; // Scale for secondary stick movement
+ float m_flStickSndSelectDist[2]; // Selection distances for secondary stick
+ float m_flStickSndSelectAngleSticky; // Selection angle for secondary stick to stick to area
+
+ panorama::CLabel *m_pLang; // Language legend label
+
+ double m_flPickedItemTransitionTime; // Time for picked item to highlight
+
+ PFNGamePadData m_pfnOnGamePadDown; // Current config for gamepad down
+ PFNGamePadData m_pfnOnGamePadAnalog; // Current config for gamepad analog
+
+ // settings
+ bool m_bDoubleSpaceToDotSpace;
+ bool m_bAutoCaps;
+
+ // Tracking doublespace = dot+space
+ bool m_bOnlySpacesEnteredSinceBackspace;
+
+ // Tracking trigger state for typing
+ bool m_bTriggersDownState[2]; // Whether trigger is down
+
+ // Tracking stick cold state
+ double m_flTimeStickCold; // When stick went into cold state (rolls when hot)
+
+ // Tracking key repeats
+ CCubicBezierCurve< Vector2D > m_repeatCurve; // Curve for key repeats
+ double m_repeatStartTime; // Time when the key was initially pressed
+ double m_repeatNextTime; // Time when the key will repeat next
+ panorama::GamePadCode m_repeatGamePadCode; // Which key was pressed (low level, for key-up tracking)
+ uint32 m_repeatCounter; // How many key repeats have happened
+ panorama::CUIScheduledDel m_repeatFunction; // Scheduled function triggering key repeats
+
+ // Stick processing routines
+ bool OnGamePadAnalog_ProcessLeftStickForGroup( const panorama::GamePadData_t &code );
+ bool OnGamePadAnalog_ProcessRightStickForSide( const panorama::GamePadData_t &code );
+ bool OnGamePadAnalog_Trigger( const panorama::GamePadData_t &code );
+ bool HandleTextInputDaisyWheelOnGamePadAnalogTriggersChanged();
+
+ // ABXY handlers
+ bool DaisyABXY_OnGamePadDown( const panorama::GamePadData_t &code );
+ bool DaisyABXY_OnGamePadAnalog( const panorama::GamePadData_t &code );
+
+ // RS handlers
+ bool DaisyRS_OnGamePadDown( const panorama::GamePadData_t &code );
+ bool DaisyRS_OnGamePadAnalog( const panorama::GamePadData_t &code );
+
+ // PINpad handlers
+ bool DaisyPIN_OnGamePadDown( const panorama::GamePadData_t & code );
+ bool DaisyPIN_OnGamePadAnalog( const panorama::GamePadData_t &code );
+
+ ELanguage m_language; // currently loaded language
+
+ ITextInputSuggest *m_psuggest; // suggestion engine
+ CUtlString m_sSuggestion; // result of suggestion
+
+ panorama::CLabel *m_plabelSuggestionPrefix; // label containing prefix of current suggestion
+ panorama::CLabel *m_plabelSuggestionSuffix; // label containing prefix of current suggestion
+
+ double m_flInputStartTime; // when did the user first start typing
+ bool m_bUsedKeyboard; // true if the kb was used for ANY input
+ bool m_bUsedGamepad; // true if the gamepad was used for ANY input
+
+ ITextInputControl *m_pTextInputControl; // control interface for moving text input between a control and daisy wheel
+ IUIEvent *m_pYbuttonAction; // the action to fire if the Y button is hit
+ panorama::CLabel *m_pYButtonText; // label for ybutton text
+ ETextInputMode_t m_mode; // text input mode
+ bool m_bDisplaySuggestions; // If true, allow suggestions to be displayed
+
+ // mode can disable specific footer sections
+ bool m_bDisableRightTrigger;
+ bool m_bDisableRightBumper;
+ bool m_bDisableLeftTrigger;
+ bool m_bDisableLanguageSelect;
+
+ enum ERightStickPos
+ {
+ k_RightStick_None,
+ k_RightStick_Up,
+ k_RightStick_Down,
+ k_RightStick_Left,
+ k_RightStick_Right,
+ };
+ ERightStickPos m_eSteamRightStickPos;
+ Vector2D m_vecRightPadPos;
+
+ CUtlVector< Emoticon_t > m_vecEmoji;
+ bool m_bLoadedEmoji;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_TEXTINPUT_DAISYWHEEL_H
+
diff --git a/public/panorama/textinput/textinput_dualtouch.h b/public/panorama/textinput/textinput_dualtouch.h
new file mode 100644
index 0000000..f7cb4ab
--- /dev/null
+++ b/public/panorama/textinput/textinput_dualtouch.h
@@ -0,0 +1,228 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose: QWERTY keyboard text entry method for Steam controller
+//=============================================================================//
+
+#ifndef PANORAMA_TEXTINPUT_DUALTOUCH_H
+#define PANORAMA_TEXTINPUT_DUALTOUCH_H
+
+#include "panorama/textinput/textinput.h"
+#include "panorama/controls/panel2d.h"
+#include "panorama/controls/label.h"
+#include "panorama/input/iuiinput.h"
+#include "mathlib/beziercurve.h"
+#include "tier1/utlptr.h"
+#include "panorama/uischeduleddel.h"
+
+namespace panorama
+{
+
+ // Forward declaration
+ class CTextInputDualTouch;
+ class CTextEntry;
+ class ITextInputSuggest;
+ class CLabel;
+
+ // this weights the frequency of words typed without any possible typos above
+ // autocorrected words, as otherwise if you legitimately type 'test' it'll
+ // auto-correct into 'rest'
+ static const float k_flExactWordFrequencyWeight = 1.2f;
+
+ class CTextInputDualTouch : public panorama::CTextInputHandler
+ {
+ DECLARE_PANEL2D( CTextInputDualTouch, panorama::CPanel2D );
+
+ public:
+ // Constructor
+ CTextInputDualTouch( panorama::IUIWindow *pParent, const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
+ CTextInputDualTouch( panorama::CPanel2D *parent, const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
+
+ // Destructor
+ ~CTextInputDualTouch();
+
+ // CTextInputHandler overrides
+ virtual void OpenHandler() OVERRIDE;
+ virtual void CloseHandlerImpl( bool bCommitText ) OVERRIDE;
+ virtual ETextInputHandlerType_t GetType() OVERRIDE;
+ virtual ITextInputControl *GetControlInterface() OVERRIDE;
+ virtual void SuggestWord( const wchar_t *pwch, int ich ) OVERRIDE;
+ virtual void SetYButtonAction( const char *pchLabel, IUIEvent *pEvent ) OVERRIDE;
+
+ static void GetSupportedLanguages( CUtlVector<ELanguage> &vecLangs );
+
+ private:
+ static const int k_DualTouchRowCount = 4;
+ static const int k_DualTouchColumnCount = 11;
+ static const int k_SuggestionCount = 4;
+
+ enum EDualTouchModifier_t
+ {
+ k_EDualTouchModifierNone = 0,
+ k_EDualTouchModifierShift = 1,
+ k_EDualTouchModifierAlt = 2,
+ k_EDualTouchModifierCount = 3,
+ };
+
+ class CTouchPad
+ {
+ public:
+ bool Initialize( CTextInputDualTouch *pParent, const char *pointerID, const char *padID,
+ IUIEngine::EHapticFeedbackPosition eHapticsPosition );
+ void UpdatePointerState( bool bPointersEnabled, uint32 nTextureID );
+ void OnTouch( void );
+ void OnRelease( void );
+ bool OnMove( float touchX, float touchY );
+ void OnButtonDown( void );
+
+ SteamPadPointer_t m_renderPointerState;
+
+ CPanel2D *m_pPointerPanel;
+ CPanel2D *m_pPadPanel;
+ CPanel2D *m_pHoverKey; // what key are we currently hovering over?
+ CPanel2D *m_pLastHoverKey; // what was the last key we were hovering over? this will either match m_pHoverKey or have the last value m_pHoverKey had if its currently nullptr
+ CUtlVector< IUIPanel * > m_vecTouchKeys;
+ bool m_bFingerOnPad;
+
+ float m_hoverX;
+ float m_hoverY;
+
+ CTextInputDualTouch *m_pTextInputDualTouch;
+
+ IUIEngine::EHapticFeedbackPosition m_eHapticsPosition;
+ };
+
+ void Initialize( const CTextInputHandlerSettings &settings, ITextInputControl *pTextControl );
+ void SetMode( ETextInputMode_t mode );
+
+ // CPanel2D overrides
+ virtual bool OnGamePadUp( const panorama::GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadDown( const panorama::GamePadData_t &code ) OVERRIDE;
+ virtual bool OnGamePadAnalog( const panorama::GamePadData_t &code ) OVERRIDE;
+ virtual bool OnKeyTyped( const KeyData_t &unichar ) OVERRIDE;
+ virtual bool OnKeyDown( const KeyData_t &code ) OVERRIDE;
+ virtual bool OnKeyUp( const KeyData_t &code ) OVERRIDE;
+
+ void UpdateSteamPadPointers( void );
+ bool OnPropertyTransitionEnd( const CPanelPtr< IUIPanel > &pPanel, CStyleSymbol prop );
+ bool OnRemoveStyleFromLinkedKeys( CPanelPtr<CPanel2D> pPanel, const char *pszStyle );
+
+ bool TouchPadClicked( CTouchPad* pTouchPad );
+
+ // Listen for focus lost
+ bool HandleInputFocusLost( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel );
+ bool OnActiveControllerTypeChanged( EActiveControllerType eActiveControllerType );
+
+ bool BConvertNextSpaceToPeriod( void );
+ bool TypeWchar( uchar16 wch, const char *pUTFf8Char = NULL );
+ bool TypeKeyDown( panorama::KeyCode eCode );
+
+ bool SwitchLanguage( void );
+ bool LoadInputConfigurationFile( ELanguage language );
+ bool LoadInputConfigurationFile( char const *szConfigFile, const char *szConfigRootDir );
+ bool LoadConfigurationBuffer( char const *pszIncoming );
+
+ void SetModifierKeyState( EDualTouchModifier_t modifier, bool bIsButtonPressEvent );
+ EDualTouchModifier_t CalculateDesiredModifierState() const;
+ void ApplyCurrentModifierLayout();
+
+ void TouchKeyClicked( CPanel2D *pTouchKey, CTouchPad *pTouchPad );
+
+ // Process scheduled key repeat
+ void ScheduleKeyRepeats( panorama::GamePadCode eCode );
+ void CancelOutstandingRepeats() { ScheduleKeyRepeats( XK_NULL ); }
+
+ void ScheduledKeyRepeatFunction();
+
+ // auto-suggestion
+ void ClearSuggestionVisual( void )
+ {
+ for ( int i = 0; i < k_SuggestionCount; i++ )
+ {
+ m_pSuggestionLabels[i]->SetText( "" );
+ }
+ }
+ void ClearSuggestionState( bool bFlush = true )
+ {
+ // flush what we have into the buffer
+ if ( bFlush && m_vecPossibleWordsBeingTyped.Count() )
+ {
+ CStrAutoEncode s( m_vecPossibleWordsBeingTyped[0] );
+ m_pTextInputControl->InsertCharactersAtCursor( s.ToWString(), V_wcslen( s.ToWString() ) );
+ }
+ m_vecPossibleWordsBeingTyped.Purge();
+ ClearSuggestionVisual();
+ UpdateTextPreview();
+ }
+ void ProcessSuggestions( void );
+ void ApplySuggestion( int iSuggestion );
+ void UpdateTextPreview( void );
+
+ bool PerformBackspace( void );
+
+ void CursorMove( const panorama::GamePadData_t &code );
+ void DisableCursorMode( void );
+
+ private:
+ void ChangeTouchkeyStyle( CPanel2D *pTouchKey, const char *pchStyle, bool bAddStyle );
+
+ public:
+ ITextInputControl *m_pTextInputControl; // control interface for moving text input between a control and daisy wheel
+
+ CPanel2D *m_pBodyContainer;
+
+ IUIEvent *m_pYbuttonAction; // the action to fire if the Y button is hit
+ CLabel *m_pYButtonText; // label for ybutton text
+ CLabel *m_pLang;
+
+ CLabel *m_pSuggestionLabels[k_SuggestionCount];
+ CUtlVector< CUtlString > m_vecPossibleWordsBeingTyped;
+
+ ELanguage m_language; // currently loaded language
+
+ ITextInputSuggest *m_pSuggest; // suggestion engine
+
+ CTextEntry *m_pTextPreview;
+
+ bool m_bDoubleSpaceToDotSpace;
+ bool m_bOnlySpacesEnteredSinceBackspace;
+
+ ETextInputMode_t m_mode;
+
+ bool m_bAutoComplete;
+ bool m_bDisplaySuggestions;
+ bool m_bHidePreviewField;
+ bool m_bAutoCaps;
+
+ // This controls the direct-rendered steampad crosshairs; we can only
+ // have them up while we're not animating around, otherwise use higher-latency
+ // panel crosshairs
+ bool m_bSteamPadPointersEnabled;
+ IImageSource *m_pSteamPadPointerImage;
+
+ CTouchPad m_leftTouchPad;
+ CTouchPad m_rightTouchPad;
+
+ CUtlVector< CTouchPad * > m_vecTouchPads;
+
+ uchar32 m_keyLayout[k_DualTouchColumnCount][k_DualTouchRowCount][k_EDualTouchModifierCount];
+ EDualTouchModifier_t m_currentModifier;
+ int m_iCharactersTypedSinceModifierStateChanged;
+
+ // Tracking key repeats
+ CCubicBezierCurve< Vector2D > m_repeatCurve; // Curve for key repeats
+ double m_repeatStartTime; // Time when the key was initially pressed
+ double m_repeatNextTime; // Time when the key will repeat next
+ panorama::GamePadCode m_repeatGamePadCode; // Which key was pressed (low level, for key-up tracking)
+ uint32 m_repeatCounter; // How many key repeats have happened
+ panorama::CUIScheduledDel m_repeatFunction; // Scheduled function triggering key repeats
+
+ bool m_bCursorMode;
+ CPanel2D *m_pCursorKey;
+ bool m_bUseTouchPads;
+
+ bool m_bModifierKeysHeld[ k_EDualTouchModifierCount ];
+ };
+
+} // namespace panorama
+
+#endif // PANORAMA_TEXTINPUT_DUALTOUCH_H \ No newline at end of file
diff --git a/public/panorama/textinput/textinput_fullscreen.h b/public/panorama/textinput/textinput_fullscreen.h
new file mode 100644
index 0000000..020e3d7
--- /dev/null
+++ b/public/panorama/textinput/textinput_fullscreen.h
@@ -0,0 +1,50 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_TEXTINPUT_FULLSCREEN_H
+#define PANORAMA_TEXTINPUT_FULLSCREEN_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "panorama/controls/panel2d.h"
+#include "panorama/controls/textentry.h"
+
+namespace panorama
+{
+
+DECLARE_PANEL_EVENT2( TextInputFullscreenClosed, bool, const char * );
+
+//-----------------------------------------------------------------------------
+// Purpose: Full screen + daisy wheel
+//-----------------------------------------------------------------------------
+class CTextInputFullscreen : public panorama::CPanel2D
+{
+ DECLARE_PANEL2D( CTextInputFullscreen, panorama::CPanel2D );
+
+public:
+ CTextInputFullscreen( panorama::CPanel2D *pPanel, const char * pchPanelID, const CTextInputHandlerSettings &settings );
+ ~CTextInputFullscreen();
+
+ void SetMultiline( bool bMultiline );
+ void SetDescription( const char *pchDescription );
+ void SetMaxChars( uint32 unCharMax );
+ void SetEnteredText( const char *pchText );
+ virtual panorama::IUIPanel *OnGetDefaultInputFocus();
+
+private:
+ bool EventTextInputHandlerStateChange( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel, bool bActivating );
+ bool EventTextInputFinished( const panorama::CPanelPtr< panorama::IUIPanel > &ptrPanel, bool bSubmitted, const char *pchText );
+
+ panorama::CTextInputHandler *m_pTextInputHandler;
+ panorama::CTextEntry *m_pEnteredText;
+ panorama::CLabel *m_pInputDescription;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_TEXTINPUT_FULLSCREEN_H
+
diff --git a/public/panorama/textinput/textinput_settings.h b/public/panorama/textinput/textinput_settings.h
new file mode 100644
index 0000000..f961846
--- /dev/null
+++ b/public/panorama/textinput/textinput_settings.h
@@ -0,0 +1,74 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PANORAMA_TEXTINPUT_SETTINGS_H
+#define PANORAMA_TEXTINPUT_SETTINGS_H
+
+#include "panorama/controls/panel2d.h"
+#include "panorama/input/iuiinput.h"
+#include "panorama/textinput/textinput.h"
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Handler settings that get passed in at construction time
+//-----------------------------------------------------------------------------
+class CTextInputHandlerSettings
+{
+public:
+ CTextInputHandlerSettings();
+
+ // Parses property from configuration
+ bool BSetProperty( CPanoramaSymbol symName, const char *pchValue );
+
+ // Convenient accessor methods
+ void SetCancellable( bool bCancellable ) { m_bCancellable = bCancellable; }
+ bool BCancellable() const { return m_bCancellable; }
+
+ void SetHideSuggestions( bool bHideSuggestions ) { m_bHideSuggestions = bHideSuggestions; }
+ bool BHideSuggestions() const { return m_bHideSuggestions; }
+
+ void SetDoubleSpaceToDotSpace( bool bDoubleSpaceToDotSpace ) { m_bDoubleSpaceToDotSpace = bDoubleSpaceToDotSpace; }
+ bool BDoubleSpaceToDotSpace() const { return m_bDoubleSpaceToDotSpace; }
+
+ void SetAutoCaps( bool bAutoCaps ) { m_bAutoCaps = bAutoCaps; }
+ bool BAutoCaps() const { return m_bAutoCaps; }
+
+ void SetID( const char *pszID ) { m_strID = pszID; }
+ const char *GetID() const { return m_strID; }
+
+ void SetClasses( const char *pszClasses ) { m_strClasses = pszClasses; }
+ const char *GetClasses() const { return m_strClasses; }
+
+ void SetDoneActionString( const char *pszActionString ) { m_strDoneActionString = pszActionString; }
+ const char *GetDoneActionString() const { return m_strDoneActionString; }
+
+ void SetCancelActionString( const char *pszCancelActionString ) { m_strCancelActionString = pszCancelActionString; }
+ const char *GetCancelActionString() const { return m_strCancelActionString; }
+
+ void SetMode( ETextInputMode_t mode ) { m_mode = mode; }
+ ETextInputMode_t GetMode() const { return m_mode; }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName );
+#endif
+
+public:
+ bool m_bCancellable;
+ bool m_bHideSuggestions;
+ bool m_bDoubleSpaceToDotSpace;
+ bool m_bAutoCaps;
+ CUtlString m_strID;
+ CUtlString m_strClasses;
+ CUtlString m_strDoneActionString;
+ CUtlString m_strCancelActionString;
+ ETextInputMode_t m_mode;
+};
+
+} // namespace panorama
+
+#endif // PANORAMA_TEXTINPUT_SETTINGS_H
+
diff --git a/public/panorama/transformations.h b/public/panorama/transformations.h
new file mode 100644
index 0000000..b2da1d1
--- /dev/null
+++ b/public/panorama/transformations.h
@@ -0,0 +1,246 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef TRANSFORMATIONS_H
+#define TRANSFORMATIONS_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "mathlib/mathlib.h"
+#include "mathlib/vmatrix.h"
+#include "tier1/utlbuffer.h"
+#include "panorama.h"
+#include "panoramatypes.h"
+#include "layout/uilength.h"
+
+namespace panorama
+{
+
+class CTransform3D
+{
+public:
+ virtual ~CTransform3D() {}
+
+ virtual ETransform3DType GetType() const = 0;
+ virtual VMatrix GetTransformMatrix( float flParentWidth, float flParentHeight ) const = 0;
+ virtual CTransform3D *Clone() const = 0;
+ virtual void ScaleLengthValues( float flScaleFactor ) = 0;
+ virtual bool BOnlyImpacts2DValues() = 0;
+
+ virtual bool operator==( const CTransform3D &rhs ) const = 0;
+ bool operator!=( const CTransform3D &rhs ) const { return !(*this == rhs); }
+};
+
+// Helpers for interpolating 3d transform matrixes
+struct DecomposedMatrix_t
+{
+ DecomposedMatrix_t()
+ {
+ m_flTranslationXYZ[0] = 0.0f;
+ m_flTranslationXYZ[1] = 0.0f;
+ m_flTranslationXYZ[2] = 0.0f;
+ m_flScaleXYZ[0] = 1.0;
+ m_flScaleXYZ[1] = 1.0;
+ m_flScaleXYZ[2] = 1.0;
+ m_flSkewXY = 0.0f;
+ m_flSkewXZ = 0.0f;
+ m_flSkewYZ = 0.0f;
+
+ m_quatTransform.Init();
+ }
+ float m_flTranslationXYZ[3];
+ float m_flScaleXYZ[3];
+ float m_flSkewXY;
+ float m_flSkewXZ;
+ float m_flSkewYZ;
+ Quaternion m_quatTransform;
+
+
+};
+DecomposedMatrix_t DecomposeTransformMatrix( VMatrix matrix );
+VMatrix RecomposeTransformMatrix( const DecomposedMatrix_t &decomposed );
+VMatrix InterpolateTransformMatrix( VMatrix from, VMatrix to, float flTimeProgress );
+
+class CTransformRotate3D : public CTransform3D
+{
+public:
+ // Transform in 3D space:
+ // PITCH: Clockwise rotation around the Y axis.
+ // YAW: Counterclockwise rotation around the Z axis.
+ // ROLL: Counterclockwise rotation around the X axis.
+ CTransformRotate3D( float flDegreesPitch, float flDegreesYaw, float flDegreesRoll )
+ {
+ QAngle angle( flDegreesPitch, flDegreesYaw, flDegreesRoll );
+ AngleQuaternion( angle, m_quatTransform );
+ }
+
+ ETransform3DType GetType() const { return k_ETransform3DRotate; }
+
+ VMatrix GetTransformMatrix( float flParentWidth, float flParentHeight ) const
+ {
+ matrix3x4_t mat;
+ QuaternionMatrix( m_quatTransform, mat );
+ return VMatrix( mat );
+ }
+
+ bool BOnlyImpacts2DValues()
+ {
+ return false;
+ }
+
+ virtual CTransform3D *Clone() const
+ {
+ CTransformRotate3D *pRet = new CTransformRotate3D();
+ pRet->m_quatTransform = m_quatTransform;
+
+ return pRet;
+ }
+
+ QAngle GetAngles() const
+ {
+ QAngle angle;
+ QuaternionAngles( m_quatTransform, angle );
+
+ return angle;
+ }
+
+ virtual void ScaleLengthValues( float flScaleFactor ) { }
+
+ virtual bool operator==( const CTransform3D &other ) const
+ {
+ if ( other.GetType() != k_ETransform3DRotate )
+ return false;
+
+ const CTransformRotate3D &rhs = (const CTransformRotate3D &)other;
+ return (m_quatTransform == rhs.m_quatTransform);
+ }
+
+protected:
+ CTransformRotate3D() {}
+
+private:
+
+ Quaternion m_quatTransform;
+};
+
+class CTransformTranslate3D : public CTransform3D
+{
+public:
+ // Translate in 3D space
+ CTransformTranslate3D( float x, float y, float z )
+ {
+ m_x.SetLength( x );
+ m_y.SetLength( y );
+ m_z.SetLength( z );
+ }
+
+ CTransformTranslate3D( const CUILength &x, const CUILength &y, const CUILength &z )
+ {
+ m_x = x;
+ m_y = y;
+ m_z = z;
+ }
+
+ bool BOnlyImpacts2DValues()
+ {
+ if( fabs( m_z.GetValueAsLength( 100 ) - 0.0f ) < 0.0001f )
+ return true;
+
+ return false;
+ }
+
+ ETransform3DType GetType() const { return k_ETransform3DTranslate; }
+
+ VMatrix GetTransformMatrix( float flParentWidth, float flParentHeight ) const
+ {
+
+ VMatrix mat = VMatrix::GetIdentityMatrix();
+ mat.SetTranslation( Vector( m_x.GetValueAsLength( flParentWidth ), m_y.GetValueAsLength( flParentHeight ), m_z.GetValueAsLength( 0 ) ) );
+ return mat;
+ }
+
+ virtual CTransform3D *Clone() const
+ {
+ return new CTransformTranslate3D( m_x, m_y, m_z );
+ }
+
+ virtual void ScaleLengthValues( float flScaleFactor )
+ {
+ m_x.ScaleLengthValue( flScaleFactor );
+ m_y.ScaleLengthValue( flScaleFactor );
+ m_z.ScaleLengthValue( flScaleFactor );
+ }
+
+ CUILength GetX() const { return m_x; }
+ CUILength GetY() const { return m_y; }
+ CUILength GetZ() const { return m_z; }
+
+ virtual bool operator==( const CTransform3D &other ) const
+ {
+ if ( other.GetType() != k_ETransform3DTranslate )
+ return false;
+
+ const CTransformTranslate3D &rhs = (const CTransformTranslate3D &)other;
+ return ( m_x == rhs.m_x && m_y == rhs.m_y && m_z == rhs.m_z );
+ }
+
+private:
+ CUILength m_x;
+ CUILength m_y;
+ CUILength m_z;
+};
+
+
+class CTransformScale3D : public CTransform3D
+{
+public:
+ // Scale in 3D space
+ CTransformScale3D( float x, float y, float z ) : m_VecScale( x, y, z )
+ {
+ }
+
+ ETransform3DType GetType() const { return k_ETransform3DScale; }
+
+ bool BOnlyImpacts2DValues()
+ {
+ return false;
+ }
+
+ VMatrix GetTransformMatrix( float flParentWidth, float flParentHeight ) const
+ {
+ VMatrix mat;
+ MatrixBuildScale( mat, m_VecScale.x, m_VecScale.y, m_VecScale.z );
+ return mat;
+ }
+
+ virtual CTransform3D *Clone() const
+ {
+ return new CTransformScale3D( m_VecScale.x, m_VecScale.y, m_VecScale.z );
+ }
+
+ virtual void ScaleLengthValues( float flScaleFactor ) { }
+
+ float GetX() const { return m_VecScale.x; }
+ float GetY() const { return m_VecScale.y; }
+ float GetZ() const { return m_VecScale.z; }
+
+ virtual bool operator==( const CTransform3D &other ) const
+ {
+ if ( other.GetType() != k_ETransform3DScale )
+ return false;
+
+ const CTransformScale3D &rhs = (const CTransformScale3D &)other;
+ return ( m_VecScale == rhs.m_VecScale );
+ }
+
+private:
+ Vector m_VecScale;
+};
+
+} // namespace panorama
+
+#endif // TRANSFORMATIONS_H \ No newline at end of file
diff --git a/public/panorama/uievent.h b/public/panorama/uievent.h
new file mode 100644
index 0000000..d355fd6
--- /dev/null
+++ b/public/panorama/uievent.h
@@ -0,0 +1,1793 @@
+
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UIEVENT_H
+#define UIEVENT_H
+#pragma once
+
+#include "tier1/utlsymbol.h"
+#include "tier1/utldelegate.h"
+#include "controls/panelhandle.h"
+#include "controls/panelptr.h"
+#include "iuipanel.h"
+#include "iuipanelclient.h"
+#include "tier1/fmtstr.h"
+#include "panoramacxx.h"
+
+// Strict template usage is just a dev-time convenience
+// for finding missing template specializations.
+// It should never be enabled by default as there are
+// types that do not have or need template support by-design.
+#if 0
+#define PANORAMA_STRICT_EVENT_TEMPLATE_USAGE
+#endif
+#if 0
+#define PANORAMA_STRICT_V8_TEMPLATE_USAGE
+#endif
+#if defined(PANORAMA_STRICT_EVENT_TEMPLATE_USAGE) || defined(PANORAMA_STRICT_V8_TEMPLATE_USAGE)
+#define PANORAMA_ANY_STRICT_EVENT_TEMPLATE_USAGE
+#endif
+
+namespace panorama
+{
+
+
+extern void RegisterEventTypesWithEngine( IUIEngine *pEngine );
+
+#ifdef DBGFLAG_VALIDATE
+void ValidateGlobalEvents( CValidator &validator );
+#endif
+
+inline bool IsEndOfUIEventString( const char *pchEvent, const char **pchEndOfEvent )
+{
+ {
+ while( pchEvent[0] != '\0' && pchEvent[0] != ')' )
+ {
+ if( !V_isspace( pchEvent[0] ) )
+ return false;
+
+ pchEvent++;
+ }
+
+ if( pchEvent[0] == ')' )
+ ++pchEvent;
+
+ *pchEndOfEvent = pchEvent;
+
+ return true;
+ }
+}
+class IUIEvent;
+
+inline v8::Isolate *GetV8Isolate() { return UIEngine()->GetV8Isolate(); }
+
+inline const char *GetPanelID( const panorama::IUIPanel *pPanel ) { return pPanel->GetID(); }
+
+//-----------------------------------------------------------------------------
+// Purpose: Helpers to create an event from string
+//-----------------------------------------------------------------------------
+template < typename T >
+bool ParseUIEventParam( T *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam )
+{
+#ifdef PANORAMA_STRICT_EVENT_TEMPLATE_USAGE
+ TEMPLATE_USAGE_INVALID( T );
+#else
+ AssertMsg( false, "ParseUIEventParam not implemented for type" );
+ // Zero-fill so that the compiler doesn't complain about use
+ // of uninitialized data, even though this code path is not functional.
+ memset( pOut, 0, sizeof(*pOut) );
+ return false;
+#endif
+}
+
+template <> bool ParseUIEventParam< const char * >( const char **pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< uint8 >( uint8 *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< uint16 >( uint16 *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< uint32 >( uint32 *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< uint64 >( uint64 *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< int32 >( int32 *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< int64 >( int64 *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< float >( float *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< bool >( bool *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< IUIEvent * >( IUIEvent **pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< panorama::EPanelEventSource_t >( panorama::EPanelEventSource_t *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+template <> bool ParseUIEventParam< panorama::ScrollBehavior_t >( panorama::ScrollBehavior_t *pOut, panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchNextParam );
+
+int CountUIEventParams( const char *pchParams );
+bool ParseUIEventParamHelper( CUtlBuffer &bufValue, const char *pchEvent, const char **pchNextParam );
+bool IsEndOfUIEventString( const char *pchEvent, const char **pchEndOfEvent );
+
+//-----------------------------------------------------------------------------
+// Purpose: Helpers to turn event params in JS params
+//-----------------------------------------------------------------------------
+
+// Default, complain not implemented!
+template < typename T > typename panorama_enable_if< !panorama_is_enum< T >::value, void>::type
+PanoramaTypeToV8Param( T &pIn, v8::Handle<v8::Value> *pValueOut )
+{
+#ifdef PANORAMA_STRICT_V8_TEMPLATE_USAGE
+ TEMPLATE_USAGE_INVALID( T );
+#else
+ AssertMsg( false, "EventParamToV8Param not implemented for type" );
+#endif
+}
+
+// Default for enum types
+template < typename T > typename panorama_enable_if< panorama_is_enum< T >::value, void>::type
+PanoramaTypeToV8Param( T &pIn, v8::Handle<v8::Value> *pValueOut )
+{
+ COMPILE_TIME_ASSERT( sizeof( pIn ) <= sizeof( int32 ) );
+ int32 iVal = (int32)pIn;
+ return PanoramaTypeToV8Param<int32>( iVal, pValueOut );
+}
+
+// Basic non pointer specializations
+template <> void PanoramaTypeToV8Param< CUtlSymbol >( CUtlSymbol &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< panorama::CPanoramaSymbol >( panorama::CPanoramaSymbol &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< uint32 >( uint32 &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< uint64 >( uint64 &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< int32 >( int32 &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< int64 >( int64 &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< float >( float &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< double >( double &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< bool >( bool &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< CUtlVector< IUIPanel * > const >( CUtlVector< IUIPanel * > const &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< panorama::EPanelEventSource_t >( panorama::EPanelEventSource_t &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< v8::Local<v8::Value> >( v8::Local<v8::Value> &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< v8::Local<v8::Object> >( v8::Local<v8::Object> &pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param< v8::Local<v8::Array> >( v8::Local<v8::Array> &pIn, v8::Handle<v8::Value> *pValueOut );
+
+// Helper for specific pointer types we have special handling for via rules in the base T* specialization
+void PanoramaTypeToV8ParamJSObject( IUIJSObject *pJSObj, void *pIn, v8::Handle<v8::Value> *pValueOut );
+void PanoramaPanelTypeToV8Param( IUIPanel * &pIn, v8::Handle<v8::Value> *pValueOut );
+void PanoramaPanelStyleTypeToV8Param( IUIPanelStyle * &pIn, v8::Handle<v8::Value> *pValueOut );
+
+// Template overload for ptr types, so we can see if we should turn into base CPanel2D, or other special known types,
+// otherwise we'll call PanoramaPtrTypeToV8ParamJSObject and let the specialization rules figure it out
+template < typename T >
+void PanoramaTypeToV8Param( T * pIn, v8::Handle<v8::Value> *pValueOut )
+{
+ if( panorama_is_base_of< IUIPanelClient, T >::value )
+ {
+ IUIPanel *pPanel = pIn ? ( (IUIPanelClient*)pIn )->UIPanel() : NULL;
+ return PanoramaPanelTypeToV8Param( pPanel, pValueOut );
+ }
+ else if( panorama_is_base_of< IUIPanel, T >::value )
+ {
+ IUIPanel *pPanel = (IUIPanel*)pIn;
+ return PanoramaPanelTypeToV8Param( pPanel, pValueOut );
+ }
+ else if( panorama_is_base_of< IUIPanelStyle, T >::value )
+ {
+ IUIPanelStyle *pPanel = (IUIPanelStyle*)pIn;
+ return PanoramaPanelStyleTypeToV8Param( pPanel, pValueOut );
+ }
+ else if( panorama_is_base_of< IUIJSObject, T>::value )
+ {
+ IUIJSObject *pObject = (IUIJSObject*)pIn;
+ return PanoramaTypeToV8ParamJSObject( pObject, (void*)pIn, pValueOut );
+ }
+
+ AssertMsg( false, "PanoramaTypeToV8Param not implemented for type" );
+}
+
+// Specialization of above ptr overload
+template <> void PanoramaTypeToV8Param<const char>( const char * pIn, v8::Handle<v8::Value> *pValueOut );
+template <> void PanoramaTypeToV8Param<char>( char * pIn, v8::Handle<v8::Value> *pValueOut );
+
+// bugbug jmccaskey - add IUIEvent, panel source, panel2d? more?
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helpers to turn JS params into native params
+//-----------------------------------------------------------------------------
+template < typename T >
+void V8ParamToPanoramaType( const v8::Handle<v8::Value> &pValueIn, T *out )
+{
+#ifdef PANORAMA_STRICT_V8_TEMPLATE_USAGE
+ TEMPLATE_USAGE_INVALID( T );
+#else
+ AssertMsg( false, "V8ParamToPanoramaType not implemented for type" );
+#endif
+}
+template <> void V8ParamToPanoramaType< const char *>( const v8::Handle<v8::Value> &pValueIn, const char ** out );
+template <> void V8ParamToPanoramaType< CUtlSymbol >( const v8::Handle<v8::Value> &pValueIn, CUtlSymbol* out );
+template <> void V8ParamToPanoramaType< panorama::CPanoramaSymbol >( const v8::Handle<v8::Value> &pValueIn, panorama::CPanoramaSymbol* out );
+template <> void V8ParamToPanoramaType< float >( const v8::Handle<v8::Value> &pValueIn, float *out );
+template <> void V8ParamToPanoramaType< double >( const v8::Handle<v8::Value> &pValueIn, double *out );
+template <> void V8ParamToPanoramaType< int >( const v8::Handle<v8::Value> &pValueIn, int *out );
+template <> void V8ParamToPanoramaType< uint >( const v8::Handle<v8::Value> &pValueIn, uint *out );
+template <> void V8ParamToPanoramaType< bool >( const v8::Handle<v8::Value> &pValueIn, bool *out );
+template <> void V8ParamToPanoramaType< IUIPanel * >( const v8::Handle<v8::Value> &pValueIn, IUIPanel **out );
+#ifndef PANORAMA_EXPORTS
+template <> void V8ParamToPanoramaType< CPanel2D * >( const v8::Handle<v8::Value> &pValueIn, CPanel2D **out );
+#endif
+template <> void V8ParamToPanoramaType< IUIPanelStyle * >( const v8::Handle<v8::Value> &pValueIn, IUIPanelStyle **out );
+#ifdef PANORAMA_EXPORTS
+template <> void V8ParamToPanoramaType< CPanelStyle * >( const v8::Handle<v8::Value> &pValueIn, CPanelStyle **out );
+#endif
+template <> void V8ParamToPanoramaType< v8::Persistent<v8::Function> * >( const v8::Handle<v8::Value> &pValueIn, v8::Persistent<v8::Function> **out );
+template <> void V8ParamToPanoramaType< CUtlVector< IUIPanel *> >( const v8::Handle<v8::Value> &pValueIn, CUtlVector< IUIPanel *>*out );
+template <> void V8ParamToPanoramaType< v8::Local<v8::Value> >( const v8::Handle<v8::Value> &pValueIn, v8::Local<v8::Value> *out );
+template <> void V8ParamToPanoramaType< v8::Local<v8::Object> >( const v8::Handle<v8::Value> &pValueIn, v8::Local<v8::Object> *out );
+template <> void V8ParamToPanoramaType< v8::Local<v8::Array> >( const v8::Handle<v8::Value> &pValueIn, v8::Local<v8::Array> *out );
+
+template <typename T> void FreeConvertedParam(T out) { }
+template <> void FreeConvertedParam< const char *>( const char *out );
+template <> void FreeConvertedParam< v8::Persistent<v8::Function> *>( v8::Persistent<v8::Function> *out );
+
+//-----------------------------------------------------------------------------
+// Purpose: Wrappers to handle copying params. const char * is specialized to dup the string
+//-----------------------------------------------------------------------------
+template < class T >
+void UIEventSet( T* pTo, T &pFrom )
+{
+ *pTo = pFrom;
+}
+
+template <>
+void UIEventSet( const char** pTo, const char *&pFrom );
+
+
+template <>
+void UIEventSet( IUIEvent** pTo, IUIEvent *&pFrom );
+
+
+template <>
+void UIEventSet( v8::Persistent<v8::Function>** pTo, v8::Persistent<v8::Function> *&pFrom );
+
+template < class T >
+void UIEventFree( T &p )
+{
+}
+
+template <>
+void UIEventFree( const char *& p );
+
+
+template <>
+void UIEventFree( IUIEvent *& p );
+
+template <>
+void UIEventFree( v8::Persistent<v8::Function> *&p );
+
+#ifdef DBGFLAG_VALIDATE
+
+template < class T >
+void UIEventValidate( CValidator &validator, T &p )
+{
+}
+
+template <>
+void UIEventValidate( CValidator &validator, const char *& p );
+
+
+template <>
+void UIEventValidate( CValidator &validator, IUIEvent *& p );
+
+template <>
+void UIEventValidate( CValidator &validator, v8::Persistent<v8::Function> *& p );
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose: Macros to declare a event
+// Includes Register/Unregister calls to enforce type safety
+//-----------------------------------------------------------------------------
+
+//
+// Events with 0 params
+//
+namespace UIEvent
+{
+ template < class T >
+ IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchEventEnd )
+ {
+ if ( !IsEndOfUIEventString( pchEvent, &pchEvent ) )
+ return NULL;
+
+ *pchEventEnd = pchEvent;
+ IUIEvent *pEvent = T::MakeEvent( pPanel ? pPanel->ClientPtr() : NULL );
+ return pEvent;
+ }
+}
+
+
+#define DECLARE_PANORAMA_EVENT0( name ) \
+ class name \
+ { \
+ public: \
+ static const int cParams = 0; static const bool bPanelEvent = false; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget ) { return new panorama::CUIEvent0( symbol, pTarget ? pTarget->UIPanel() : NULL ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pHandlerPanel, bool (U::*memberfunc)() ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pHandlerPanel, UtlMakeDelegate( pHandlerPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pHandlerPanel, bool (U::*memberfunc)() ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pHandlerPanel, UtlMakeDelegate( pHandlerPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)() ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)() ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pHandlerObj, bool (U::*memberfunc)() ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pHandlerObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pHandlerObj, bool (U::*memberfunc)() ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pHandlerObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool (PanelType::*memberfunc)() ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+#define DECLARE_PANEL_EVENT0( name ) \
+class name \
+ { \
+ public: \
+ static const int cParams = 0; static const bool bPanelEvent = true; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget ) { return new panorama::CUIPanelEvent0( symbol, pTarget ? pTarget->UIPanel() : NULL ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T * pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > & ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > & ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T * pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > & ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > & ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > & ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > & ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( const panorama::CPanelPtr< panorama::IUIPanel > & ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+//
+// Events with 1 params
+//
+namespace UIEvent
+{
+ template < class T, typename param1 >
+ IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchEventEnd )
+ {
+ param1 p1;
+ if ( !ParseUIEventParam< param1 >( &p1, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ if ( !IsEndOfUIEventString( pchEvent, &pchEvent ) )
+ return NULL;
+
+ *pchEventEnd = pchEvent;
+
+ IUIEvent *pEvent = T::MakeEvent( pPanel ? pPanel->ClientPtr() : NULL, p1 );
+ UIEventFree( p1 );
+ return pEvent;
+ }
+}
+
+#define DECLARE_PANORAMA_EVENT1( name, param1 ) \
+ class name \
+ { \
+ public: \
+ typedef param1 TypenameParam1; static const int cParams = 1; static const bool bPanelEvent = false; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1 ) { return new panorama::CUIEvent1< param1 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1 >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel->UIPanel(), UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( param1 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+#define DECLARE_PANEL_EVENT1( name, param1 ) \
+class name \
+ { \
+ public: \
+ typedef param1 TypenameParam1; static const int cParams = 1; static const bool bPanelEvent = true; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1 ) { return new panorama::CUIPanelEvent1< param1 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1 >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel->UIPanel(), UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( const panorama::CPanelPtr< panorama::IUIPanel > &, param1 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+//
+// Events with 2 params
+//
+namespace UIEvent
+{
+ template < class T, typename param1, typename param2 >
+ IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchEventEnd )
+ {
+ param1 p1;
+ if ( !ParseUIEventParam< param1 >( &p1, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param2 p2;
+ if ( !ParseUIEventParam< param2 >( &p2, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ if ( !IsEndOfUIEventString( pchEvent, &pchEvent ) )
+ return NULL;
+
+ *pchEventEnd = pchEvent;
+ IUIEvent *pEvent = T::MakeEvent( pPanel ? pPanel->ClientPtr() : NULL, p1, p2 );
+ UIEventFree( p1 );
+ UIEventFree( p2 );
+ return pEvent;
+ }
+}
+
+#define DECLARE_PANORAMA_EVENT2( name, param1, param2 ) \
+ class name \
+ { \
+ public: \
+ typedef param1 TypenameParam1; typedef param2 TypenameParam2; static const int cParams = 2; static const bool bPanelEvent = false; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1, param2 p2 ) { return new panorama::CUIEvent2< param1, param2 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1, p2 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1, param2 >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1, param2 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1, param2 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1, param2 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1, param2 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1, param2 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1, param2 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( param1, param2 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+#define DECLARE_PANEL_EVENT2( name, param1, param2 ) \
+ class name \
+ { \
+ public: \
+ typedef param1 TypenameParam1; typedef param2 TypenameParam2; static const int cParams = 2; static const bool bPanelEvent = true; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1, param2 p2 ) { return new panorama::CUIPanelEvent2< param1, param2 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1, p2 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1, param2 >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+//
+// Events with 3 params
+//
+namespace UIEvent
+{
+ template < class T, typename param1, typename param2, typename param3 >
+ IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchEventEnd )
+ {
+ param1 p1;
+ if ( !ParseUIEventParam< param1 >( &p1, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param2 p2;
+ if ( !ParseUIEventParam< param2 >( &p2, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param3 p3;
+ if ( !ParseUIEventParam< param3 >( &p3, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ if ( !IsEndOfUIEventString( pchEvent, &pchEvent ) )
+ return NULL;
+
+ *pchEventEnd = pchEvent;
+
+ IUIEvent *pEvent = T::MakeEvent( pPanel ? pPanel->ClientPtr() : NULL, p1, p2, p3 );
+ UIEventFree( p1 );
+ UIEventFree( p2 );
+ UIEventFree( p3 );
+ return pEvent;
+ }
+}
+
+#define DECLARE_PANORAMA_EVENT3( name, param1, param2, param3 ) \
+class name \
+ { \
+ public: \
+ typedef param1 TypenameParam1; typedef param2 TypenameParam2; typedef param3 TypenameParam3; static const int cParams = 3; static const bool bPanelEvent = false; static panorama::CPanoramaSymbol symbol; static const char *pchEvent; \
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1, param2 p2, param3 p3 ) { return new panorama::CUIEvent3< param1, param2, param3 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1, p2, p3 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1, param2, param3 >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1, param2, param3 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1, param2, param3 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1, param2, param3 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1, param2, param3 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1, param2, param3 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1, param2, param3 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( param1, param2, param3 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+#define DECLARE_PANEL_EVENT3( name, param1, param2, param3 ) \
+ class name \
+ { \
+ public: \
+ typedef param1 TypenameParam1; typedef param2 TypenameParam2; typedef param3 TypenameParam3; static const int cParams = 3; static const bool bPanelEvent = true; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1, param2 p2, param3 p3 ) { return new panorama::CUIPanelEvent3< param1, param2, param3 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1, p2, p3 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1, param2, param3 >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+//
+// Events with 4 params
+//
+namespace UIEvent
+{
+ template < class T, typename param1, typename param2, typename param3, typename param4 >
+ IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchEventEnd )
+ {
+ param1 p1;
+ if ( !ParseUIEventParam< param1 >( &p1, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param2 p2;
+ if ( !ParseUIEventParam< param2 >( &p2, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param3 p3;
+ if ( !ParseUIEventParam< param3 >( &p3, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param4 p4;
+ if ( !ParseUIEventParam< param4 >( &p4, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ if ( !IsEndOfUIEventString( pchEvent, &pchEvent ) )
+ return NULL;
+
+ *pchEventEnd = pchEvent;
+ IUIEvent *pEvent = T::MakeEvent( pPanel ? pPanel->ClientPtr() : NULL, p1, p2, p3, p4 );
+ UIEventFree( p1 );
+ UIEventFree( p2 );
+ UIEventFree( p3 );
+ UIEventFree( p4 );
+ return pEvent;
+ }
+}
+
+#define DECLARE_PANORAMA_EVENT4( name, param1, param2, param3, param4 ) \
+ class name \
+ { \
+ public: \
+ typedef param1 TypenameParam1; typedef param2 TypenameParam2; typedef param3 TypenameParam3; typedef param4 TypenameParam4; static const int cParams = 4; static const bool bPanelEvent = false; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1, param2 p2, param3 p3, param4 p4 ) { return new panorama::CUIEvent4< param1, param2, param3, param4 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1, p2, p3, p4 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1, param2, param3, param4 >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1, param2, param3, param4 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1, param2, param3, param4 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1, param2, param3, param4 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1, param2, param3, param4 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1, param2, param3, param4 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1, param2, param3, param4 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( param1, param2, param3, param4 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+#define DECLARE_PANEL_EVENT4( name, param1, param2, param3, param4 ) \
+ class name \
+ { \
+ public: \
+ typedef param1 TypenameParam1; typedef param2 TypenameParam2; typedef param3 TypenameParam3; typedef param4 TypenameParam4; static const int cParams = 4; static const bool bPanelEvent = true; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1, param2 p2, param3 p3, param4 p4 ) { return new panorama::CUIPanelEvent4< param1, param2, param3, param4 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1, p2, p3, p4 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1, param2, param3, param4 >( pPanel, pchEventCreate, pchEventEnd ); } \
+ }; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+//
+// Events with 5 params
+//
+namespace UIEvent
+{
+ template < class T, typename param1, typename param2, typename param3, typename param4, typename param5 >
+ IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEvent, const char **pchEventEnd )
+ {
+ param1 p1;
+ if ( !ParseUIEventParam< param1 >( &p1, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param2 p2;
+ if ( !ParseUIEventParam< param2 >( &p2, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param3 p3;
+ if ( !ParseUIEventParam< param3 >( &p3, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param4 p4;
+ if ( !ParseUIEventParam< param4 >( &p4, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ param5 p5;
+ if ( !ParseUIEventParam< param5 >( &p5, pPanel, pchEvent, &pchEvent ) )
+ return NULL;
+
+ if ( !IsEndOfUIEventString( pchEvent, &pchEvent ) )
+ return NULL;
+
+ *pchEventEnd = pchEvent;
+
+ IUIEvent *pEvent = T::MakeEvent( pPanel ? pPanel->ClientPtr() : NULL, p1, p2, p3, p4, p5 );
+ UIEventFree( p1 );
+ UIEventFree( p2 );
+ UIEventFree( p3 );
+ UIEventFree( p4 );
+ UIEventFree( p5 );
+ return pEvent;
+ }
+}
+
+#define DECLARE_PANORAMA_EVENT5( name, param1, param2, param3, param4, param5 ) \
+class name \
+{ \
+public: \
+ typedef param1 TypenameParam1; typedef param2 TypenameParam2; typedef param3 TypenameParam3; typedef param4 TypenameParam4; typedef param5 TypenameParam5; static const int cParams = 5; static const bool bPanelEvent = false; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { Assert( symbol.IsValid() ); return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1, param2 p2, param3 p3, param4 p4, param5 p5 ) { return new panorama::CUIEvent5< param1, param2, param3, param4, param5 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1, p2, p3, p4, p5 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1, param2, param3, param4, param5 >( pPanel, pchEventCreate, pchEventEnd ); } \
+}; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+#define DECLARE_PANEL_EVENT5( name, param1, param2, param3, param4, param5 ) \
+class name \
+{ \
+public: \
+ typedef param1 TypenameParam1; typedef param2 TypenameParam2; typedef param3 TypenameParam3; typedef param4 TypenameParam4; typedef param5 TypenameParam5; static const int cParams = 5; static const bool bPanelEvent = true; static panorama::CPanoramaSymbol symbol; static const char *pchEvent;\
+ static panorama::CPanoramaSymbol GetEventType() { return symbol; } \
+ static panorama::IUIEvent *MakeEvent( const panorama::IUIPanelClient *pTarget, param1 p1, param2 p2, param3 p3, param4 p4, param5 p5 ) { return new panorama::CUIPanelEvent5< param1, param2, param3, param4, param5 >( symbol, pTarget ? pTarget->UIPanel() : NULL, p1, p2, p3, p4, p5 ); } \
+ static panorama::IUIEvent *CreateEventFromString( panorama::IUIPanel *pPanel, const char *pchEventCreate, const char **pchEventEnd ) { return panorama::UIEvent::CreateEventFromString< name, param1, param2, param3, param4, param5 >( pPanel, pchEventCreate, pchEventEnd ); } \
+}; \
+ template< class T, class U > void RegisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandler( const name &t, T *pPanel, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pPanel, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->RegisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterEventHandlerOnPanel( const name &t, panorama::IUIPanel *pPanel, T *pHandler, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->UnregisterEventHandler( t.GetEventType(), pPanel, UtlMakeDelegate( pHandler, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void RegisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->RegisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class T, class U > void UnregisterForUnhandledEvent( const name &t, T *pObj, bool (U::*memberfunc)( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->UnregisterForUnhandledEvent( t.GetEventType(), UtlMakeDelegate( pObj, memberfunc ).GetAbstractDelegate() ); } \
+ template< class PanelType > void RegisterEventHandlerOnPanelType( const name &t, bool( PanelType::*memberfunc )( const panorama::CPanelPtr< panorama::IUIPanel > &, param1, param2, param3, param4, param5 ) ) { panorama::UIEngine()->RegisterPanelTypeEventHandler( t.GetEventType(), PanelType::GetPanelSymbol(), UtlMakeDelegate( (PanelType*)NULL, memberfunc ).GetAbstractDelegate() ); }
+
+
+#define DEFINE_PANORAMA_EVENT( name ) \
+ panorama::CPanoramaSymbol name::symbol; \
+ const char *name::pchEvent = #name; \
+ panorama::CAutoRegisterUIEvent< name, name::cParams > g_##name##_EventAutoRegister( #name );
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Class to automatically register events at startup
+//-----------------------------------------------------------------------------
+void RegisterUIEvent( panorama::CPanoramaSymbol *pSymEvent, const char *pchEventType, int cParams, bool bPanelEvent,
+ PFN_ParseUIEvent pfnParseUIEvent, PFN_MakeUIEvent0 pfnMakeUIEvent0, PFN_MakeUIEvent1Repeats pfnMakeUIEvent1Repeats, PFN_MakeUIEvent1Source pfnMakeUIEvent1Source );
+
+
+template < class T, int N >
+class CAutoRegisterUIEvent
+{
+public:
+ CAutoRegisterUIEvent( const char *pch )
+ {
+ RegisterUIEvent( &T::symbol, T::pchEvent, T::cParams, T::bPanelEvent, T::CreateEventFromString, NULL, NULL, NULL );
+ }
+};
+
+template < class T >
+class CAutoRegisterUIEvent<T, 0>
+{
+public:
+ CAutoRegisterUIEvent( const char *pch )
+ {
+ RegisterUIEvent( &T::symbol, T::pchEvent, T::cParams, T::bPanelEvent, T::CreateEventFromString, T::MakeEvent, NULL, NULL );
+ }
+};
+
+template < class T, typename TParam1 >
+class CAutoRegisterUIEventWithParam1
+{
+public:
+ CAutoRegisterUIEventWithParam1( const char *pch )
+ {
+ RegisterUIEvent( &T::symbol, T::pchEvent, T::cParams, T::bPanelEvent, T::CreateEventFromString, NULL, NULL, NULL );
+ }
+};
+
+template < class T >
+class CAutoRegisterUIEventWithParam1< T, panorama::EPanelEventSource_t >
+{
+public:
+ CAutoRegisterUIEventWithParam1( const char *pch )
+ {
+ RegisterUIEvent( &T::symbol, T::pchEvent, T::cParams, T::bPanelEvent, T::CreateEventFromString, NULL, NULL, T::MakeEvent );
+ }
+};
+
+template < class T >
+class CAutoRegisterUIEventWithParam1< T, int >
+{
+public:
+ CAutoRegisterUIEventWithParam1( const char *pch )
+ {
+ RegisterUIEvent( &T::symbol, T::pchEvent, T::cParams, T::bPanelEvent, T::CreateEventFromString, NULL, T::MakeEvent, NULL );
+ }
+};
+
+template < class T >
+class CAutoRegisterUIEvent<T, 1>
+{
+public:
+ typedef typename T::TypenameParam1 TTypenameParam1;
+ CAutoRegisterUIEventWithParam1< T, TTypenameParam1 > m_autoregister;
+ CAutoRegisterUIEvent( const char *pch ) : m_autoregister( pch )
+ {
+ }
+};
+
+
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Event interface
+//-----------------------------------------------------------------------------
+class IUIEvent
+{
+public:
+ virtual ~IUIEvent() {}
+
+ virtual const CPanelPtr< const IUIPanel > &GetTargetPanel() const = 0;
+ virtual void SetTargetPanel( const IUIPanel *pTarget ) = 0;
+ virtual panorama::CPanoramaSymbol GetEventType() const = 0;
+ virtual bool CanBubble() const { return false; }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc ) = 0;
+ virtual IUIEvent *Copy() const = 0;
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs ) = 0;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName ) = 0;
+#endif
+
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Event base class
+//-----------------------------------------------------------------------------
+class CUIEventBase : public IUIEvent
+{
+public:
+ CUIEventBase( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel )
+ {
+ m_symEvent = symEvent;
+ m_pTargetPanel = pTargetPanel;
+ }
+
+ virtual const CPanelPtr< const IUIPanel > &GetTargetPanel() const
+ {
+ return m_pTargetPanel;
+ }
+
+ virtual void SetTargetPanel( const IUIPanel *pTarget )
+ {
+ m_pTargetPanel = pTarget;
+ }
+
+ virtual panorama::CPanoramaSymbol GetEventType() const
+ {
+ return m_symEvent;
+ }
+
+private:
+ panorama::CPanoramaSymbol m_symEvent;
+ CPanelPtr< const IUIPanel > m_pTargetPanel;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: UI Event types
+//-----------------------------------------------------------------------------
+class CUIEvent0 : public CUIEventBase
+{
+public:
+ CUIEvent0( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ }
+
+ virtual ~CUIEvent0()
+ {
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool ( void ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del();
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIEvent0( GetEventType(), GetTargetPanel().Get() );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 0;
+ *pArgs = NULL;
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+
+ }
+#endif
+};
+
+class CUIPanelEvent0 : public CUIEventBase
+{
+public:
+ CUIPanelEvent0( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ }
+
+ virtual ~CUIPanelEvent0()
+ {
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool( const CPanelPtr< const IUIPanel > & ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( GetTargetPanel() );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIPanelEvent0( GetEventType(), GetTargetPanel().Get() );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 1;
+ *pArgs = new v8::Handle< v8::Value >[1];
+ *pArgs[0] = v8::String::NewFromUtf8( GetV8Isolate(), GetPanelID( GetTargetPanel().Get() ) );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+
+ }
+#endif
+};
+
+
+
+template < typename PARAM1_TYPE >
+class CUIEvent1 : public CUIEventBase
+{
+public:
+ CUIEvent1( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ }
+
+ virtual ~CUIEvent1()
+ {
+ UIEventFree( m_param1 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool ( PARAM1_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( m_param1 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIEvent1( GetEventType(), GetTargetPanel().Get(), m_param1 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 1;
+ *pArgs = new v8::Handle< v8::Value>[1];
+ PanoramaTypeToV8Param( m_param1, *pArgs );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+
+private:
+ PARAM1_TYPE m_param1;
+};
+
+template < typename PARAM1_TYPE >
+class CUIPanelEvent1 : public CUIEventBase
+{
+public:
+ CUIPanelEvent1( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ }
+
+ virtual ~CUIPanelEvent1()
+ {
+ UIEventFree( m_param1 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool( const CPanelPtr< const IUIPanel > &, PARAM1_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( GetTargetPanel(), m_param1 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIPanelEvent1( GetEventType(), GetTargetPanel().Get(), m_param1 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 2;
+ *pArgs = new v8::Handle< v8::Value >[2];
+ *pArgs[0] = v8::String::NewFromUtf8( GetV8Isolate(), GetPanelID( GetTargetPanel().Get() ) );
+ PanoramaTypeToV8Param( m_param1, *pArgs+1 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+
+private:
+ PARAM1_TYPE m_param1;
+};
+
+template < typename PARAM1_TYPE, typename PARAM2_TYPE >
+class CUIPanelEvent2 : public CUIEventBase
+{
+public:
+ CUIPanelEvent2( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1, PARAM2_TYPE param2 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ UIEventSet( &m_param2, param2 );
+ }
+
+ virtual ~CUIPanelEvent2()
+ {
+ UIEventFree( m_param1 );
+ UIEventFree( m_param2 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool( const CPanelPtr< const IUIPanel > &, PARAM1_TYPE, PARAM2_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( GetTargetPanel(), m_param1, m_param2 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIPanelEvent2( GetEventType(), GetTargetPanel().Get(), m_param1, m_param2 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 3;
+ *pArgs = new v8::Handle< v8::Value >[3];
+ *pArgs[0] = v8::String::NewFromUtf8( GetV8Isolate(), GetPanelID( GetTargetPanel().Get() ) );
+ PanoramaTypeToV8Param( m_param1, *pArgs+1 );
+ PanoramaTypeToV8Param( m_param2, *pArgs+2 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ UIEventValidate( validator, m_param2 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+ const PARAM2_TYPE &GetParam2() const { return m_param2; }
+
+private:
+ PARAM1_TYPE m_param1;
+ PARAM2_TYPE m_param2;
+};
+
+
+template < typename PARAM1_TYPE, typename PARAM2_TYPE >
+class CUIEvent2 : public CUIEventBase
+{
+public:
+ CUIEvent2( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1, PARAM2_TYPE param2 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ UIEventSet( &m_param2, param2 );
+ }
+
+ virtual ~CUIEvent2()
+ {
+ UIEventFree( m_param1 );
+ UIEventFree( m_param2 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool ( PARAM1_TYPE, PARAM2_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( m_param1, m_param2 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIEvent2( GetEventType(), GetTargetPanel().Get(), m_param1, m_param2 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 2;
+ *pArgs = new v8::Handle< v8::Value >[2];
+ PanoramaTypeToV8Param( m_param1, *pArgs+0 );
+ PanoramaTypeToV8Param( m_param2, *pArgs+1 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ UIEventValidate( validator, m_param2 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+ const PARAM2_TYPE &GetParam2() const { return m_param2; }
+
+private:
+ PARAM1_TYPE m_param1;
+ PARAM2_TYPE m_param2;
+};
+
+template < typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE >
+class CUIEvent3 : public CUIEventBase
+{
+public:
+ CUIEvent3( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ UIEventSet( &m_param2, param2 );
+ UIEventSet( &m_param3, param3 );
+ }
+
+ virtual ~CUIEvent3()
+ {
+ UIEventFree( m_param1 );
+ UIEventFree( m_param2 );
+ UIEventFree( m_param3 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool ( PARAM1_TYPE, PARAM2_TYPE, PARAM3_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( m_param1, m_param2, m_param3 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIEvent3( GetEventType(), GetTargetPanel().Get(), m_param1, m_param2, m_param3 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 3;
+ *pArgs = new v8::Handle< v8::Value >[3];
+ PanoramaTypeToV8Param( m_param1, *pArgs+0 );
+ PanoramaTypeToV8Param( m_param2, *pArgs+1 );
+ PanoramaTypeToV8Param( m_param3, *pArgs+2 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ UIEventValidate( validator, m_param2 );
+ UIEventValidate( validator, m_param3 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+ const PARAM2_TYPE &GetParam2() const { return m_param2; }
+ const PARAM3_TYPE &GetParam3() const { return m_param3; }
+
+private:
+ PARAM1_TYPE m_param1;
+ PARAM2_TYPE m_param2;
+ PARAM3_TYPE m_param3;
+};
+
+template < typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE >
+class CUIPanelEvent3 : public CUIEventBase
+{
+public:
+ CUIPanelEvent3( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ UIEventSet( &m_param2, param2 );
+ UIEventSet( &m_param3, param3 );
+ }
+
+ virtual ~CUIPanelEvent3()
+ {
+ UIEventFree( m_param1 );
+ UIEventFree( m_param2 );
+ UIEventFree( m_param3 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool( const CPanelPtr< const IUIPanel > &, PARAM1_TYPE, PARAM2_TYPE, PARAM3_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( GetTargetPanel(), m_param1, m_param2, m_param3 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIPanelEvent3( GetEventType(), GetTargetPanel().Get(), m_param1, m_param2, m_param3 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 4;
+ *pArgs = new v8::Handle< v8::Value >[4];
+ *pArgs[0] = v8::String::NewFromUtf8( GetV8Isolate(), GetPanelID( GetTargetPanel().Get() ) );
+ PanoramaTypeToV8Param( m_param1, *pArgs+1 );
+ PanoramaTypeToV8Param( m_param2, *pArgs+2 );
+ PanoramaTypeToV8Param( m_param3, *pArgs+3 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ UIEventValidate( validator, m_param2 );
+ UIEventValidate( validator, m_param3 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+ const PARAM2_TYPE &GetParam2() const { return m_param2; }
+ const PARAM3_TYPE &GetParam3() const { return m_param3; }
+
+private:
+ PARAM1_TYPE m_param1;
+ PARAM2_TYPE m_param2;
+ PARAM3_TYPE m_param3;
+};
+
+template < typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE >
+class CUIEvent4 : public CUIEventBase
+{
+public:
+ CUIEvent4( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ UIEventSet( &m_param2, param2 );
+ UIEventSet( &m_param3, param3 );
+ UIEventSet( &m_param4, param4 );
+ }
+
+ virtual ~CUIEvent4()
+ {
+ UIEventFree( m_param1 );
+ UIEventFree( m_param2 );
+ UIEventFree( m_param3 );
+ UIEventFree( m_param4 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool ( PARAM1_TYPE, PARAM2_TYPE, PARAM3_TYPE, PARAM4_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( m_param1, m_param2, m_param3, m_param4 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIEvent4( GetEventType(), GetTargetPanel().Get(), m_param1, m_param2, m_param3, m_param4 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 4;
+ *pArgs = new v8::Handle< v8::Value >[4];
+ PanoramaTypeToV8Param( m_param1, *pArgs+0 );
+ PanoramaTypeToV8Param( m_param2, *pArgs+1 );
+ PanoramaTypeToV8Param( m_param3, *pArgs+2 );
+ PanoramaTypeToV8Param( m_param4, *pArgs+3 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ UIEventValidate( validator, m_param2 );
+ UIEventValidate( validator, m_param3 );
+ UIEventValidate( validator, m_param4 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+ const PARAM2_TYPE &GetParam2() const { return m_param2; }
+ const PARAM3_TYPE &GetParam3() const { return m_param3; }
+ const PARAM4_TYPE &GetParam4() const { return m_param4; }
+
+private:
+ PARAM1_TYPE m_param1;
+ PARAM2_TYPE m_param2;
+ PARAM3_TYPE m_param3;
+ PARAM4_TYPE m_param4;
+};
+
+
+template < typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE >
+class CUIPanelEvent4 : public CUIEventBase
+{
+public:
+ CUIPanelEvent4( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ UIEventSet( &m_param2, param2 );
+ UIEventSet( &m_param3, param3 );
+ UIEventSet( &m_param4, param4 );
+ }
+
+ virtual ~CUIPanelEvent4()
+ {
+ UIEventFree( m_param1 );
+ UIEventFree( m_param2 );
+ UIEventFree( m_param3 );
+ UIEventFree( m_param4 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool( const CPanelPtr< const IUIPanel > &, PARAM1_TYPE, PARAM2_TYPE, PARAM3_TYPE, PARAM4_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( GetTargetPanel(), m_param1, m_param2, m_param3, m_param4 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIPanelEvent4( GetEventType(), GetTargetPanel().Get(), m_param1, m_param2, m_param3, m_param4 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 5;
+ *pArgs = new v8::Handle< v8::Value >[5];
+ *pArgs[0] = v8::String::NewFromUtf8( GetV8Isolate(), GetPanelID( GetTargetPanel().Get() ) );
+ PanoramaTypeToV8Param( m_param1, *pArgs+1 );
+ PanoramaTypeToV8Param( m_param2, *pArgs+2 );
+ PanoramaTypeToV8Param( m_param3, *pArgs+3 );
+ PanoramaTypeToV8Param( m_param4, *pArgs+4 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ UIEventValidate( validator, m_param2 );
+ UIEventValidate( validator, m_param3 );
+ UIEventValidate( validator, m_param4 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+ const PARAM2_TYPE &GetParam2() const { return m_param2; }
+ const PARAM3_TYPE &GetParam3() const { return m_param3; }
+ const PARAM4_TYPE &GetParam4() const { return m_param4; }
+
+private:
+ PARAM1_TYPE m_param1;
+ PARAM2_TYPE m_param2;
+ PARAM3_TYPE m_param3;
+ PARAM4_TYPE m_param4;
+};
+
+
+template < typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE, typename PARAM5_TYPE >
+class CUIEvent5 : public CUIEventBase
+{
+public:
+ CUIEvent5( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4, PARAM5_TYPE param5 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ UIEventSet( &m_param2, param2 );
+ UIEventSet( &m_param3, param3 );
+ UIEventSet( &m_param4, param4 );
+ UIEventSet( &m_param5, param5 );
+ }
+
+ virtual ~CUIEvent5()
+ {
+ UIEventFree( m_param1 );
+ UIEventFree( m_param2 );
+ UIEventFree( m_param3 );
+ UIEventFree( m_param4 );
+ UIEventFree( m_param5 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool ( PARAM1_TYPE, PARAM2_TYPE, PARAM3_TYPE, PARAM4_TYPE, PARAM5_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( m_param1, m_param2, m_param3, m_param4, m_param5 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIEvent5( GetEventType(), GetTargetPanel().Get(), m_param1, m_param2, m_param3, m_param4, m_param5 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 5;
+ *pArgs = new v8::Handle< v8::Value >[5];
+ PanoramaTypeToV8Param( m_param1, *pArgs+0 );
+ PanoramaTypeToV8Param( m_param2, *pArgs+1 );
+ PanoramaTypeToV8Param( m_param3, *pArgs+2 );
+ PanoramaTypeToV8Param( m_param4, *pArgs+3 );
+ PanoramaTypeToV8Param( m_param5, *pArgs+4 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ UIEventValidate( validator, m_param2 );
+ UIEventValidate( validator, m_param3 );
+ UIEventValidate( validator, m_param4 );
+ UIEventValidate( validator, m_param5 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+ const PARAM2_TYPE &GetParam2() const { return m_param2; }
+ const PARAM3_TYPE &GetParam3() const { return m_param3; }
+ const PARAM4_TYPE &GetParam4() const { return m_param4; }
+ const PARAM5_TYPE &GetParam5() const { return m_param5; }
+
+private:
+ PARAM1_TYPE m_param1;
+ PARAM2_TYPE m_param2;
+ PARAM3_TYPE m_param3;
+ PARAM4_TYPE m_param4;
+ PARAM5_TYPE m_param5;
+};
+
+
+template < typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE, typename PARAM5_TYPE >
+class CUIPanelEvent5 : public CUIEventBase
+{
+public:
+ CUIPanelEvent5( panorama::CPanoramaSymbol symEvent, const IUIPanel *pTargetPanel, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4, PARAM5_TYPE param5 ) : CUIEventBase( symEvent, pTargetPanel )
+ {
+ UIEventSet( &m_param1, param1 );
+ UIEventSet( &m_param2, param2 );
+ UIEventSet( &m_param3, param3 );
+ UIEventSet( &m_param4, param4 );
+ UIEventSet( &m_param5, param5 );
+ }
+
+ virtual ~CUIPanelEvent5()
+ {
+ UIEventFree( m_param1 );
+ UIEventFree( m_param2 );
+ UIEventFree( m_param3 );
+ UIEventFree( m_param4 );
+ UIEventFree( m_param5 );
+ }
+
+ virtual bool Dispatch( CUtlAbstractDelegate pFunc )
+ {
+ CUtlDelegate< bool( const CPanelPtr< const IUIPanel > &, PARAM1_TYPE, PARAM2_TYPE, PARAM3_TYPE, PARAM4_TYPE, PARAM5_TYPE ) > del;
+ del.SetAbstractDelegate( pFunc );
+ return del( GetTargetPanel(), m_param1, m_param2, m_param3, m_param4, m_param5 );
+ }
+
+ virtual IUIEvent *Copy() const
+ {
+ return new CUIPanelEvent5( GetEventType(), GetTargetPanel().Get(), m_param1, m_param2, m_param3, m_param4, m_param5 );
+ }
+
+ virtual void GetJavaScriptArgs( int *pCount, v8::Handle<v8::Value> **pArgs )
+ {
+ *pCount = 6;
+ *pArgs = new v8::Handle< v8::Value >[6];
+ *pArgs[0] = v8::String::NewFromUtf8( GetV8Isolate(), GetPanelID( GetTargetPanel().Get() ) );
+ PanoramaTypeToV8Param( m_param1, *pArgs+1 );
+ PanoramaTypeToV8Param( m_param2, *pArgs+2 );
+ PanoramaTypeToV8Param( m_param3, *pArgs+3 );
+ PanoramaTypeToV8Param( m_param4, *pArgs+4 );
+ PanoramaTypeToV8Param( m_param5, *pArgs+5 );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ UIEventValidate( validator, m_param1 );
+ UIEventValidate( validator, m_param2 );
+ UIEventValidate( validator, m_param3 );
+ UIEventValidate( validator, m_param4 );
+ UIEventValidate( validator, m_param5 );
+ }
+#endif
+
+ const PARAM1_TYPE &GetParam1() const { return m_param1; }
+ const PARAM2_TYPE &GetParam2() const { return m_param2; }
+ const PARAM3_TYPE &GetParam3() const { return m_param3; }
+ const PARAM4_TYPE &GetParam4() const { return m_param4; }
+ const PARAM5_TYPE &GetParam5() const { return m_param5; }
+
+private:
+ PARAM1_TYPE m_param1;
+ PARAM2_TYPE m_param2;
+ PARAM3_TYPE m_param3;
+ PARAM4_TYPE m_param4;
+ PARAM5_TYPE m_param5;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Dispatch synchronous event helpers
+//-----------------------------------------------------------------------------
+#ifdef PANORAMA_EXPORTS
+template < typename T >
+bool DispatchEvent( T t, const IUIPanel *pTarget )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL ) );
+}
+
+template < typename T, typename PARAM1_TYPE >
+bool DispatchEvent( T t, const IUIPanel *pTarget, PARAM1_TYPE param1 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE >
+bool DispatchEvent( T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE >
+bool DispatchEvent( T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2, param3 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE >
+bool DispatchEvent( T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2, param3, param4 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE, typename PARAM5_TYPE >
+bool DispatchEvent( T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4, PARAM5_TYPE param5 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2, param3, param4, param5 ) );
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose: Dispatch synchronous event helpers
+//-----------------------------------------------------------------------------
+template < typename T >
+bool DispatchEvent( T t, const IUIPanelClient *pTarget )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget ) );
+}
+
+template < typename T, typename PARAM1_TYPE >
+bool DispatchEvent( T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget, param1 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE >
+bool DispatchEvent( T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget, param1, param2 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE >
+bool DispatchEvent( T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget, param1, param2, param3 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE >
+bool DispatchEvent( T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget, param1, param2, param3, param4 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE, typename PARAM5_TYPE >
+bool DispatchEvent( T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4, PARAM5_TYPE param5 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return false;
+
+ return UIEngine()->DispatchEvent( t.MakeEvent( pTarget, param1, param2, param3, param4, param5 ) );
+}
+
+#ifdef PANORAMA_EXPORTS
+//-----------------------------------------------------------------------------
+// Purpose: Dispatch asynchronous event helpers
+//-----------------------------------------------------------------------------
+template < typename T >
+void DispatchEventAsync( T t, const IUIPanel *pTarget )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( 0.0f, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL ) );
+}
+
+template < typename T >
+void DispatchEventAsync( float flDelay, T t, const IUIPanel *pTarget )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL ) );
+}
+
+
+template < typename T, typename PARAM1_TYPE >
+void DispatchEventAsync( T t, const IUIPanel *pTarget, PARAM1_TYPE param1 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( 0.0f, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1 ) );
+}
+
+template < typename T, typename PARAM1_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanel *pTarget, PARAM1_TYPE param1 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE >
+void DispatchEventAsync( T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( 0.0f, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE >
+void DispatchEventAsync( T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( 0.0f, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2, param3 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2, param3 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2, param3, param4 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE, typename PARAM5_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanel *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4, PARAM5_TYPE param5 )
+{
+ if ( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget ? pTarget->ClientPtr() : NULL, param1, param2, param3, param4, param5 ) );
+}
+#endif
+
+template < typename T >
+void DispatchEventAsync( T t, const IUIPanelClient *pTarget )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( 0.0f, t.MakeEvent( pTarget ) );
+}
+
+template < typename T >
+void DispatchEventAsync( float flDelay, T t, const IUIPanelClient *pTarget )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget ) );
+}
+
+
+template < typename T, typename PARAM1_TYPE >
+void DispatchEventAsync( T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( 0.0f, t.MakeEvent( pTarget, param1 ) );
+}
+
+template < typename T, typename PARAM1_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget, param1 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE >
+void DispatchEventAsync( T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( 0.0f, t.MakeEvent( pTarget, param1, param2 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE >
+void DispatchEventAsync( T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( 0.0f, t.MakeEvent( pTarget, param1, param2, param3 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget, param1, param2 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget, param1, param2, param3 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget, param1, param2, param3, param4 ) );
+}
+
+template < typename T, typename PARAM1_TYPE, typename PARAM2_TYPE, typename PARAM3_TYPE, typename PARAM4_TYPE, typename PARAM5_TYPE >
+void DispatchEventAsync( float flDelay, T t, const IUIPanelClient *pTarget, PARAM1_TYPE param1, PARAM2_TYPE param2, PARAM3_TYPE param3, PARAM4_TYPE param4, PARAM5_TYPE param5 )
+{
+ if( !UIEngine()->BAnyHandlerRegisteredForEvent( T::symbol ) )
+ return;
+
+ UIEngine()->DispatchEventAsync( flDelay, t.MakeEvent( pTarget, param1, param2, param3, param4, param5 ) );
+}
+
+
+/*
+IUIEvent *CreateEventFromSymbol( panorama::CPanoramaSymbol symEvent, IUIPanel *pPanel );
+template <typename PARAM1> IUIEvent *CreateEventFromSymbol( panorama::CPanoramaSymbol symEvent, IUIPanel *pPanel, PARAM1 p1 );
+template <typename PARAM1, typename PARAM2> IUIEvent *CreateEventFromSymbol( panorama::CPanoramaSymbol symEvent, IUIPanel *pPanel, PARAM1 p1, PARAM2 p2 );
+template <typename PARAM1, typename PARAM2, typename PARAM3> IUIEvent *CreateEventFromSymbol( panorama::CPanoramaSymbol symEvent, IUIPanel *pPanel, PARAM1 p1, PARAM2 p2, PARAM3 p3 );
+*/
+} // namespace panorama
+
+#endif // UIEVENT_H
diff --git a/public/panorama/uieventcodes.h b/public/panorama/uieventcodes.h
new file mode 100644
index 0000000..1447a34
--- /dev/null
+++ b/public/panorama/uieventcodes.h
@@ -0,0 +1,18 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UIEVENTCODES_H
+#define UIEVENTCODES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+};
+
+#endif // UIEVENTCODES_H
diff --git a/public/panorama/uievents.h b/public/panorama/uievents.h
new file mode 100644
index 0000000..af5a1f1
--- /dev/null
+++ b/public/panorama/uievents.h
@@ -0,0 +1,211 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UIEVENTS_H
+#define UIEVENTS_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "uievent.h"
+#include "uieventcodes.h"
+#include "layout/stylesymbol.h"
+#include "localization/ilocalize.h"
+class IVideoPlayer;
+
+
+namespace panorama
+{
+
+// general panel events
+DECLARE_PANEL_EVENT1( AddStyle, const char * );
+DECLARE_PANEL_EVENT1( RemoveStyle, const char * );
+DECLARE_PANEL_EVENT1( ToggleStyle, const char * );
+DECLARE_PANEL_EVENT1( AddStyleToEachChild, const char * );
+DECLARE_PANEL_EVENT1( RemoveStyleFromEachChild, const char * );
+DECLARE_PANEL_EVENT0( PanelLoaded );
+DECLARE_PANEL_EVENT0( CheckChildrenScrolledIntoView );
+DECLARE_PANEL_EVENT2( ScrollPanelIntoView, ScrollBehavior_t, bool );
+DECLARE_PANEL_EVENT0( ScrolledIntoView );
+DECLARE_PANEL_EVENT0( ScrolledOutOfView );
+DECLARE_PANEL_EVENT2( LoadLayoutFileAsync, const char *, bool );
+DECLARE_PANEL_EVENT1( AppendChildrenFromLayoutFileAsync, const char * );
+DECLARE_PANEL_EVENT2( LoadLayoutFromXMLStringAsync, const char *, bool );
+DECLARE_PANEL_EVENT2( LoadLayoutFromBase64XMLStringAsync, const char *, bool );
+DECLARE_PANEL_EVENT1( Activated, EPanelEventSource_t );
+DECLARE_PANEL_EVENT1( Cancelled, EPanelEventSource_t );
+DECLARE_PANEL_EVENT1( ContextMenu, EPanelEventSource_t );
+DECLARE_PANEL_EVENT1( LocalizationChanged, const ILocalizationString * );
+DECLARE_PANEL_EVENT0( InputFocusSet );
+DECLARE_PANEL_EVENT0( InputFocusLost );
+DECLARE_PANORAMA_EVENT1( InputFocusTopLevelChanged, CPanelPtr< CPanel2D > );
+DECLARE_PANEL_EVENT0( SetInputFocus );
+DECLARE_PANEL_EVENT0( ShowTooltip );
+DECLARE_PANEL_EVENT0( StyleFlagsChanged );
+DECLARE_PANEL_EVENT0( StyleClassesChanged );
+DECLARE_PANEL_EVENT0( PanelStyleChanged );
+DECLARE_PANEL_EVENT1( AnimationStart, CPanoramaSymbol );
+DECLARE_PANEL_EVENT1( AnimationEnd, CPanoramaSymbol );
+DECLARE_PANEL_EVENT1( PropertyTransitionEnd, CStyleSymbol );
+DECLARE_PANEL_EVENT1( CopyStringToClipboard, const char * );
+DECLARE_PANEL_EVENT1( SetAllChildrenActivationEnabled, bool );
+DECLARE_PANEL_EVENT2( SetPanelEvent, const char *, const char * );
+DECLARE_PANEL_EVENT1( ClearPanelEvent, const char * );
+DECLARE_PANEL_EVENT2( IfHasClassEvent, const char *, IUIEvent * );
+DECLARE_PANEL_EVENT2( IfNotHasClassEvent, const char *, IUIEvent * );
+DECLARE_PANEL_EVENT2( IfHoverOtherEvent, const char *, IUIEvent * );
+DECLARE_PANEL_EVENT2( IfNotHoverOtherEvent, const char *, IUIEvent * );
+DECLARE_PANEL_EVENT0( ScrollToTop );
+DECLARE_PANEL_EVENT0( ScrollToBottom );
+DECLARE_PANEL_EVENT3( LoadAsyncComplete, bool, ELoadLayoutAsyncDetails, bool );
+DECLARE_PANEL_EVENT1( SetPanelSelected, bool );
+DECLARE_PANEL_EVENT0( ResetToDefaultValue );
+DECLARE_PANEL_EVENT0( TogglePanelSelected );
+DECLARE_PANEL_EVENT1( SetChildPanelsSelected, bool );
+DECLARE_PANEL_EVENT0( ScrollPanelLeft );
+DECLARE_PANEL_EVENT0( ScrollPanelRight );
+DECLARE_PANEL_EVENT0( ScrollPanelUp );
+DECLARE_PANEL_EVENT0( ScrollPanelDown );
+DECLARE_PANEL_EVENT0( PagePanelLeft );
+DECLARE_PANEL_EVENT0( PagePanelRight );
+DECLARE_PANEL_EVENT0( PagePanelUp );
+DECLARE_PANEL_EVENT0( PagePanelDown );
+DECLARE_PANEL_EVENT1( DropdownMenuFocusChanged, CPanelPtr< IUIPanel > );
+
+// window events
+class CTopLevelWindow;
+DECLARE_PANORAMA_EVENT1( WindowGotFocus, IUIWindow * );
+DECLARE_PANORAMA_EVENT1( WindowLostFocus, IUIWindow * );
+DECLARE_PANORAMA_EVENT1( WindowCursorShown, IUIWindow * );
+DECLARE_PANORAMA_EVENT1( WindowCursorHidden, IUIWindow * );
+DECLARE_PANORAMA_EVENT1( WindowShown, IUIWindow * );
+DECLARE_PANORAMA_EVENT1( WindowHidden, IUIWindow * );
+DECLARE_PANORAMA_EVENT1( WindowOffScreen, IUIWindow * );
+DECLARE_PANORAMA_EVENT1( WindowOnScreen, IUIWindow * );
+
+// global events
+DECLARE_PANORAMA_EVENT0( QuitApp );
+DECLARE_PANORAMA_EVENT0( ExitSteam );
+DECLARE_PANORAMA_EVENT0( ShutdownMachine );
+DECLARE_PANORAMA_EVENT0( RestartMachine );
+DECLARE_PANORAMA_EVENT0( SuspendMachine );
+DECLARE_PANORAMA_EVENT0( TurnOffActiveController );
+DECLARE_PANORAMA_EVENT0( GoOffline );
+DECLARE_PANORAMA_EVENT0( GoOnline );
+DECLARE_PANORAMA_EVENT0( ShowQuitDialog );
+DECLARE_PANORAMA_EVENT0( ChangeUser );
+DECLARE_PANORAMA_EVENT0( ToggleDebugger );
+DECLARE_PANORAMA_EVENT0( ShowPanelZoo );
+DECLARE_PANORAMA_EVENT0( DumpMemory );
+DECLARE_PANORAMA_EVENT0( ProfileOn );
+DECLARE_PANORAMA_EVENT0( ProfileOff );
+DECLARE_PANORAMA_EVENT0( ToggleConsole );
+DECLARE_PANORAMA_EVENT0( Refresh );
+DECLARE_PANORAMA_EVENT1( MoveUp, int );
+DECLARE_PANORAMA_EVENT1( MoveDown, int );
+DECLARE_PANORAMA_EVENT1( MoveLeft, int );
+DECLARE_PANORAMA_EVENT1( MoveRight, int );
+DECLARE_PANORAMA_EVENT0( ScrollUp );
+DECLARE_PANORAMA_EVENT0( ScrollDown );
+DECLARE_PANORAMA_EVENT0( ScrollLeft );
+DECLARE_PANORAMA_EVENT0( ScrollRight );
+DECLARE_PANORAMA_EVENT0( PageUp );
+DECLARE_PANORAMA_EVENT0( PageDown );
+DECLARE_PANORAMA_EVENT0( PageLeft );
+DECLARE_PANORAMA_EVENT0( PageRight );
+DECLARE_PANORAMA_EVENT1( TabForward, int );
+DECLARE_PANORAMA_EVENT1( TabBackward, int );
+DECLARE_PANORAMA_EVENT0( GamepadInserted );
+DECLARE_PANORAMA_EVENT0( GamepadRemoved );
+DECLARE_PANORAMA_EVENT1( ReloadStyleFile, CPanoramaSymbol );
+DECLARE_PANORAMA_EVENT1( TopLevelWindowClose, IUIWindow* ); // fired when top level window is destructing while all children are still valid
+DECLARE_PANORAMA_EVENT1( TopLevelWindowClosed, IUIWindow* ); // fired after top level window has already destroyed all children
+DECLARE_PANORAMA_EVENT0( GamepadInput );
+DECLARE_PANEL_EVENT0( DeletePanel );
+DECLARE_PANORAMA_EVENT0( ActivateMainWindow );
+DECLARE_PANORAMA_EVENT2( ToggleFullscreen, IUIWindow*, bool );
+DECLARE_PANORAMA_EVENT0( GuideButton );
+DECLARE_PANORAMA_EVENT0( GuideButtonUp );
+DECLARE_PANORAMA_EVENT2( SoundFinished, const char *, HAUDIOSAMPLE );
+DECLARE_PANORAMA_EVENT0( None ); // short circuited in the bind code not to fire an event
+DECLARE_PANORAMA_EVENT1( ExecuteSteamURL, const char * );
+DECLARE_PANORAMA_EVENT0( UserInputActive );
+DECLARE_PANORAMA_EVENT1( AsyncPanoramaQuitWithError, const char * );
+DECLARE_PANORAMA_EVENT0( GameControllerMappingChanged );
+DECLARE_PANORAMA_EVENT0( StopStreaming );
+DECLARE_PANORAMA_EVENT0( CloseModalDialog );
+DECLARE_PANORAMA_EVENT2( SoundVolumeChanged, ESoundType, float );
+DECLARE_PANORAMA_EVENT1( SoundMuteChanged, bool );
+DECLARE_PANORAMA_EVENT1( ActiveControllerTypeChanged, EActiveControllerType );
+
+void OnActiveControllerTypeChangedDefaultHandler( IUIPanel *pPanel, EActiveControllerType eActiveControllerType );
+
+DECLARE_PANORAMA_EVENT0( MediaVolumeMute );
+DECLARE_PANORAMA_EVENT0( MediaVolumeDown );
+DECLARE_PANORAMA_EVENT0( MediaVolumeUp );
+DECLARE_PANORAMA_EVENT0( MediaNextTrack );
+DECLARE_PANORAMA_EVENT0( MediaPrevTrack );
+DECLARE_PANORAMA_EVENT0( MediaStop );
+DECLARE_PANORAMA_EVENT0( MediaPlayPause );
+
+DECLARE_PANORAMA_EVENT0( SteamPadRightHighActivity );
+
+
+DECLARE_PANORAMA_EVENT2( JSConsoleOutput, CPanelPtr< CPanel2D >, const char * );
+
+// Not necessarily universal but shared across multiple panels
+DECLARE_PANORAMA_EVENT0( RemoveUser );
+DECLARE_PANEL_EVENT0( PollingForSteamClientUpdate );
+DECLARE_PANORAMA_EVENT0( SettingsPanelShown );
+
+// Event to wrap any other event up async
+DECLARE_PANORAMA_EVENT2( AsyncEvent, float, IUIEvent * );
+
+// Request from some UI to show a URL in the systems browser, may be hooked and handled differently in different applications, not handled by default in panorama itself
+DECLARE_PANEL_EVENT1( BrowserGoToURL, const char * );
+
+DECLARE_PANORAMA_EVENT0( AsyncPanoramaSurfaceLost ); // 3d surface detected that its output became unavailable, currently fired by Linux on VTT switch
+DECLARE_PANORAMA_EVENT0( AsyncPanoramaSurfaceReturned ); // 3d surface detected that its previously lost surface is now renderable again but will need a full reload
+
+// When text input handler is coming up or down, bool = true when showing, = false for hiding
+DECLARE_PANEL_EVENT1( TextInputHandlerStateChange, bool );
+
+// InMemoryFileUpdate event params:
+// 1 - symbol of file that changed
+// 2 - location in file that changed
+// 3 - old size
+// 4 - new size
+DECLARE_PANORAMA_EVENT4( InMemoryFileUpdate, CPanoramaSymbol, uint, uint, uint );
+DECLARE_PANORAMA_EVENT0( InMemoryFilesSaved );
+
+
+// video player events
+DECLARE_PANORAMA_EVENT1( VideoPlayerInitalized, IVideoPlayer* );
+DECLARE_PANORAMA_EVENT1( VideoPlayerRepeated, IVideoPlayer* );
+DECLARE_PANORAMA_EVENT1( VideoPlayerEnded, IVideoPlayer* );
+DECLARE_PANORAMA_EVENT1( VideoPlayerPlaybackStateChange, IVideoPlayer* );
+DECLARE_PANORAMA_EVENT1( VideoPlayerChangedRepresentation, IVideoPlayer* );
+
+DECLARE_PANORAMA_EVENT2( OverlayGamepadInputMsg, panorama::IUIWindow *, InputMessage_t * )
+
+// debugger events
+DECLARE_PANORAMA_EVENT0( CreateDebuggerWindow );
+DECLARE_PANORAMA_EVENT0( CloseDebuggerWindow );
+DECLARE_PANORAMA_EVENT0( BeginDebuggerInspect );
+
+DECLARE_PANEL_EVENT2( JSONWebAPIResponse, KeyValues *, void * );
+
+// panel drag events
+DECLARE_PANEL_EVENT1( DragStart, IUIPanel** ); // first event for drag sent to panel user started dragging on (must be marked with draggable="true")
+DECLARE_PANEL_EVENT1( DragEnter, panorama::CPanelPtr< panorama::IUIPanel > ); // sent to panel drag is hovering over
+DECLARE_PANEL_EVENT1( DragDrop, panorama::CPanelPtr< panorama::IUIPanel > ); // sent to panel where user released mouse while dragging
+DECLARE_PANEL_EVENT1( DragLeave, panorama::CPanelPtr< panorama::IUIPanel > ); // sent to panel drag stopped hovering over
+DECLARE_PANEL_EVENT1( DragEnd, panorama::CPanelPtr< panorama::IUIPanel > ); // sent to panel which received DragStart after Drop event was sent
+
+
+} // namespace panorama
+
+#endif // UIEVENTS_H
diff --git a/public/panorama/uifileresource.h b/public/panorama/uifileresource.h
new file mode 100644
index 0000000..102875c
--- /dev/null
+++ b/public/panorama/uifileresource.h
@@ -0,0 +1,87 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UIFILERESOURCE_H
+#define UIFILERESOURCE_H
+
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier1/utlstring.h"
+
+namespace panorama
+{
+
+//
+// A file reference container, you pass in an opaque string and it interprets what kind of reference is it
+// Supports local file and HTTP url right now
+//
+class CFileResource
+{
+public:
+ CFileResource();
+ CFileResource( const char *pchUTF8Path );
+ CFileResource( const CFileResource &src) { operator=(src); }
+ ~CFileResource();
+
+ bool BIsValid() const;
+ bool BIsHTTPURL() const;
+ bool BIsLocalPath() const;
+ bool BIsSMBShare() const;
+ const CUtlVector<CUtlString> &GetCookieHeadersForHTTPURL() const;
+
+ const CUtlString &GetReferencePath() const;
+ CUtlString &GetReferencePathForModify();
+
+ void Set( const char *pchUTF8Path );
+ CFileResource &operator=( const CFileResource & src);
+ bool operator<( const CFileResource &left ) const;
+ bool operator==( const CFileResource &left);
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+ ValidateObj( m_sReference );
+ ValidateObj( m_vecCookieHeaders );
+ FOR_EACH_VEC( m_vecCookieHeaders, iVec )
+ ValidateObj( m_vecCookieHeaders[iVec] );
+ }
+#endif
+private:
+
+ enum EReferenceType
+ {
+ eNone,
+ eHTTPURL,
+ eFile,
+ eSMB,
+ eSource2Relative
+ };
+ EReferenceType m_eRefType;
+ CUtlString m_sReference;
+
+ // Only used for eHTTPURL type
+ CUtlVector<CUtlString> m_vecCookieHeaders;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: ResourceImage types
+//-----------------------------------------------------------------------------
+enum EResourceImageType
+{
+ k_EResourceImageTypeUnknown = 0,
+ k_EResourceImageTypeImage,
+ k_EResourceImageTypeMovie
+};
+
+// Function to determine resource type for a file resource
+EResourceImageType DetermineResourceType( const CFileResource &resource );
+
+} // namespace panorama
+
+#endif // UIFILERESOURCE_H \ No newline at end of file
diff --git a/public/panorama/uijsregistration.h b/public/panorama/uijsregistration.h
new file mode 100644
index 0000000..4d6b06b
--- /dev/null
+++ b/public/panorama/uijsregistration.h
@@ -0,0 +1,724 @@
+
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UIJSREGISTRATION_H
+#define UIJSREGISTRATION_H
+#pragma once
+
+#include "../panorama/uiengine.h"
+#if defined( OSX ) && !defined( SOURCE2_PANORAMA )
+ #include <tr1/tuple>
+ #include <tr1/utility>
+ #define STDTR1 std::tr1
+#else
+ #define STDTR1 std
+#endif
+
+#if _GNUC
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif // _GNUC
+
+#ifdef None
+#undef None // X11 defines None breaking the ability to use v8::None down below, so remove the preprocessor macro here
+#endif
+
+#pragma warning(push)
+//warning C4700 : uninitialized local variable 'getcaster' used -- we'll do a lot of this, but its ok
+#pragma warning( disable : 4700 )
+
+namespace panorama
+{
+
+ template<typename T> struct RegisterJSTypeDeducer_t { static RegisterJSType_t Type() { return k_ERegisterJSTypeUnknown; } };
+#define PANORAMA_DECLARE_DEDUCE_JSTYPE( _JSType, _T ) template<> struct RegisterJSTypeDeducer_t<_T> { static RegisterJSType_t Type() { return k_ERegisterJSType##_JSType; } };
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Void, void )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Bool, bool )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Int8, int8 )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Uint8, uint8 )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Int16, int16 )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Uint16, uint16 )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Int32, int32 )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Uint32, uint32 )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Int64, int64 )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Uint64, uint64 )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Float, float )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( Double, double )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( ConstString, const char * )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( PanoramaSymbol, CPanoramaSymbol )
+ PANORAMA_DECLARE_DEDUCE_JSTYPE( RawV8Args, const v8::FunctionCallbackInfo<v8::Value>& )
+
+ inline void JSCheckObjectValidity( const v8::FunctionCallbackInfo<v8::Value>& args )
+ {
+ // Don't use helper for getting panel, as it will throw exception, which we don't want in just this function
+ v8::Local<v8::Object> obj = args.Holder();
+ if( obj->InternalFieldCount() != 1 )
+ {
+ v8::Handle< v8::Boolean > value = v8::Boolean::New( args.GetIsolate(), false );
+ args.GetReturnValue().Set( value );
+ }
+
+ v8::Local<v8::External> wrap = v8::Local<v8::External>::Cast( obj->GetInternalField( 0 ) );
+ void *pPanel = (void*)wrap->Value();
+ if( !pPanel )
+ {
+ v8::Handle< v8::Boolean > value = v8::Boolean::New( args.GetIsolate(), false );
+ args.GetReturnValue().Set( value );
+ }
+ else
+ {
+ v8::Handle< v8::Boolean > value = v8::Boolean::New( args.GetIsolate(), true );
+ args.GetReturnValue().Set( value );
+ }
+ }
+
+ // Register special IsValid(), which makes the JS obj like a safe handle where you can use this
+ // to check if the obj has been deleted in C++ and is gone. You must still track all objects that are
+ // created and set their internal value to 0 so they point at nothing to make this work.
+ inline void RegisterJSIsValid()
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+
+ v8::Handle<v8::ObjectTemplate> objTemplate = UIEngine()->GetCurrentV8ObjectTemplateToSetup();
+ objTemplate->Set( v8::String::NewFromUtf8( GetV8Isolate(), "IsValid" ), v8::FunctionTemplate::New( GetV8Isolate(), &JSCheckObjectValidity ) );
+ }
+
+ // Register a member to expose to JavaScript as read/write
+ template< typename ObjType, typename MemberType >
+ void RegisterJSAccessor( const char *jsMemberName, MemberType( ObjType::*pGetFunc )() const, void(ObjType::*pSetFunc)(MemberType), const char *pDesc = NULL );
+
+ // Register a read-only member to expose to JavaScript
+ template< typename ObjType, typename MemberType >
+ void RegisterJSAccessorReadOnly( const char *jsMemberName, MemberType( ObjType::*pGetFunc )() const, const char *pDesc = NULL );
+
+ template < typename ObjType, typename RetType, typename ...Args>
+ void RegisterJSMethod( const char *pchMethodName, RetType( ObjType::*mf )(Args...) const, const char *pDesc = NULL );
+
+ template <typename T>
+ void RegisterJSConstantValue( const char *pchJSMemberName, T value, const char *pDesc = NULL );
+
+ template < typename RetType, typename ...Args>
+ void RegisterJSGlobalFunction( const char *pchJSFunctionName, RetType(*pFunc)(Args...), bool bTrueGlobal = false, const char *pDesc = NULL );
+
+
+ //
+ // Everything below here is internals, and should be ignored if you aren't adding additional type
+ // support inside panorama itself.
+ //
+
+ template< typename ObjType> ObjType* GetThisPtrForJSCall( v8::Local<v8::Object> self )
+ {
+ v8::Local<v8::External> wrap = v8::Local<v8::External>::Cast( self->GetInternalField( 0 ) );
+ ObjType *pPanel = (ObjType*)wrap->Value();
+
+ if( pPanel && panorama_is_base_of< IUIPanelClient, ObjType >::value )
+ {
+ IUIPanel *pUIPanel = (IUIPanel*)(pPanel);
+ pPanel = (ObjType*)(pUIPanel->ClientPtr());
+ }
+
+ if( !pPanel )
+ {
+ GetV8Isolate()->ThrowException( v8::String::NewFromUtf8( GetV8Isolate(), "Underlying object is deleted!" ) );
+ return NULL;
+ }
+ return pPanel;
+ }
+
+
+ template < typename T > void GetPtrToCallbackArray( T pGetFunc, v8::Handle<v8::Array> &callbackArray );
+ template < typename T > void SetPtrToCallbackArray( T pSetFunc, v8::Handle<v8::Array> &callbackArray );
+
+ struct funcbytes
+ {
+ void * v1;
+ void * v2;
+ void * v3;
+ };
+
+ template< typename T> union HACKY_FUNC_PTR_CASTER
+ {
+ T funcPtr;
+ funcbytes funcBytes;
+ };
+
+ template< typename T> void RestoreFuncPtr( HACKY_FUNC_PTR_CASTER< T > &caster, v8::Local<v8::Array> &callbackArray, int iOffset )
+ {
+ Assert( (int)callbackArray->Length() >= iOffset + 3 );
+ caster.funcBytes.v1 = v8::Local<v8::External>::Cast( callbackArray->Get( iOffset++ ) )->Value();
+ caster.funcBytes.v2 = v8::Local<v8::External>::Cast( callbackArray->Get( iOffset++ ) )->Value();
+ caster.funcBytes.v3 = v8::Local<v8::External>::Cast( callbackArray->Get( iOffset++ ) )->Value();
+ }
+
+ template <typename T>
+ void RegisterJSConstantValue( const char *pchJSMemberName, T value, const char *pDesc )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+
+ v8::Handle<v8::ObjectTemplate> objTemplate = UIEngine()->GetCurrentV8ObjectTemplateToSetup();
+ v8::Handle<v8::Value> val;
+
+ PanoramaTypeToV8Param( value, &val );
+
+ objTemplate->Set( v8::String::NewFromUtf8( GetV8Isolate(), pchJSMemberName ), val, v8::PropertyAttribute( v8::ReadOnly | v8::DontDelete ) );
+
+ UIEngine()->NewRegisterJSEntry( pchJSMemberName, RegisterJSEntryInfo_t::k_EConstantValue, pDesc, RegisterJSTypeDeducer_t<T>::Type() );
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // Purpose: More heavily templated helper for registering accessors of various types. We'll
+ // expose explicit more strongly typed versions, but this avoids duplicating setup code in each.
+ //-----------------------------------------------------------------------------
+ template <typename JSGetterCallback, typename JSSetterCallback, typename ObjGetMethod, typename ObjSetMethod>
+ void RegisterJSAccessorInternal( const char *pchJSMemberName, ObjGetMethod pGetFunc, ObjSetMethod pSetFunc, JSGetterCallback pGetCallback, JSSetterCallback pSetCallback, const char *pDesc = NULL, RegisterJSType_t eDataType = k_ERegisterJSTypeUnknown )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+
+ v8::Handle<v8::Array> callbackArray = v8::Array::New( GetV8Isolate(), 6 );
+ GetPtrToCallbackArray( pGetFunc, callbackArray );
+ SetPtrToCallbackArray( pSetFunc, callbackArray );
+
+ v8::Handle<v8::ObjectTemplate> objTemplate = UIEngine()->GetCurrentV8ObjectTemplateToSetup();
+ if( pSetFunc )
+ objTemplate->SetAccessor( v8::String::NewFromUtf8( GetV8Isolate(), pchJSMemberName ), pGetCallback, pSetCallback, callbackArray, v8::DEFAULT, v8::None );
+ else
+ objTemplate->SetAccessor( v8::String::NewFromUtf8( GetV8Isolate(), pchJSMemberName ), pGetCallback, 0, callbackArray, v8::DEFAULT, v8::ReadOnly );
+
+ UIEngine()->NewRegisterJSEntry( pchJSMemberName, pSetFunc ? RegisterJSEntryInfo_t::k_EAccessor : RegisterJSEntryInfo_t::k_EAccessorReadOnly, pDesc, eDataType );
+ }
+
+
+ template < class ObjType, class T > class CJSPropGetter
+ {
+ public:
+
+ static void GetProp( v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+ ObjType *pPanel = GetThisPtrForJSCall<ObjType>( info.Holder() );
+ if( !pPanel )
+ return;
+
+ v8::Local<v8::Array> callbackArray = v8::Local<v8::Array>::Cast( info.Data() );
+
+ HACKY_FUNC_PTR_CASTER< T( ObjType::* )() const > caster;
+ RestoreFuncPtr( caster, callbackArray, 0 );
+
+ v8::Handle< v8::Value > val;
+ T nativeval = (pPanel->*caster.funcPtr)();
+ PanoramaTypeToV8Param( nativeval, &val );
+ info.GetReturnValue().Set( val );
+ }
+
+ static void SetProp( v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+ ObjType *pPanel = GetThisPtrForJSCall<ObjType>( info.Holder() );
+ if( !pPanel )
+ return;
+
+ v8::Local<v8::Array> callbackArray = v8::Local<v8::Array>::Cast( info.Data() );
+
+ HACKY_FUNC_PTR_CASTER< void (ObjType::*)(T) > caster;
+ RestoreFuncPtr( caster, callbackArray, 3 );
+
+ T val;
+ V8ParamToPanoramaType( value, &val );
+ (pPanel->*caster.funcPtr)(val);
+
+ FreeConvertedParam( val );
+ }
+ };
+
+
+ //-----------------------------------------------------------------------------
+ // Purpose: Register a float member to expose to JavaScript, can pass NULL for pSetFunc if this is only able to be read not written
+ //-----------------------------------------------------------------------------
+ template< typename ObjType, typename MemberType >
+ void RegisterJSAccessor( const char *jsMemberName, MemberType( ObjType::*pGetFunc )() const, void(ObjType::*pSetFunc)(MemberType), const char *pDesc )
+ {
+ RegisterJSAccessorInternal( jsMemberName, pGetFunc, pSetFunc, &CJSPropGetter<ObjType, MemberType>::GetProp, &CJSPropGetter<ObjType, MemberType>::SetProp, pDesc, RegisterJSTypeDeducer_t<MemberType>::Type() );
+ }
+
+ // Register a read-only member to expose to JavaScript
+ template< typename ObjType, typename MemberType >
+ void RegisterJSAccessorReadOnly( const char *jsMemberName, MemberType( ObjType::*pGetFunc )() const, const char *pDesc )
+ {
+ RegisterJSAccessorInternal( jsMemberName, pGetFunc, 0, &CJSPropGetter<ObjType, MemberType>::GetProp, &CJSPropGetter<ObjType, MemberType>::SetProp, pDesc, RegisterJSTypeDeducer_t<MemberType>::Type() );
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // Purpose: Convert a v8 argument to native panorama type
+ //-----------------------------------------------------------------------------
+ template< typename T> bool BConvertV8ArgToPanorama( const v8::Handle<v8::Value> &val, T *pNativeVal )
+ {
+ v8::TryCatch try_catch;
+ V8ParamToPanoramaType( val, pNativeVal );
+ if( try_catch.HasCaught() )
+ {
+ UIEngine()->OutputJSExceptionToConsole( try_catch, UIEngine()->GetPanelForJavaScriptContext( *(GetV8Isolate()->GetCurrentContext()) ) );
+ return false;
+ }
+
+ return true;
+ }
+
+ void JSCheckObjectValidity( const v8::FunctionCallbackInfo<v8::Value>& args );
+
+ //-----------------------------------------------------------------------------
+ // Purpose: Helper for passing function pointers into js data callback
+ //-----------------------------------------------------------------------------
+ template < typename T > void GetPtrToCallbackArray( T pGetFunc, v8::Handle<v8::Array> &callbackArray )
+ {
+ COMPILE_TIME_ASSERT( sizeof( T ) <= sizeof( funcbytes ) );
+
+ Assert( callbackArray->Length() >= 3 );
+ HACKY_FUNC_PTR_CASTER< T > getcaster;
+ // single a legit GCC warning when our func pointers are 2 bytes, not 3
+ getcaster.funcBytes.v3 = NULL;
+ getcaster.funcPtr = pGetFunc;
+
+ callbackArray->Set( 0, v8::External::New( GetV8Isolate(), getcaster.funcBytes.v1 ) );
+ callbackArray->Set( 1, v8::External::New( GetV8Isolate(), getcaster.funcBytes.v2 ) );
+ callbackArray->Set( 2, v8::External::New( GetV8Isolate(), getcaster.funcBytes.v3 ) );
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // Purpose: Helper for passing function pointers into js data callback
+ //-----------------------------------------------------------------------------
+ template < typename T > void SetPtrToCallbackArray( T pSetFunc, v8::Handle<v8::Array> &callbackArray )
+ {
+ COMPILE_TIME_ASSERT( sizeof( T ) <= sizeof( funcbytes ) );
+
+ Assert( callbackArray->Length() >= 6 );
+ if( pSetFunc )
+ {
+ HACKY_FUNC_PTR_CASTER< T > setcaster;
+ // single a legit GCC warning when our func pointers are 2 bytes, not 3
+ setcaster.funcBytes.v3 = NULL;
+ setcaster.funcPtr = pSetFunc;
+
+ callbackArray->Set( 3, v8::External::New( GetV8Isolate(), setcaster.funcBytes.v1 ) );
+ callbackArray->Set( 4, v8::External::New( GetV8Isolate(), setcaster.funcBytes.v2 ) );
+ callbackArray->Set( 5, v8::External::New( GetV8Isolate(), setcaster.funcBytes.v3 ) );
+ }
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // Purpose: Handler for JS method call callbacks
+ //-----------------------------------------------------------------------------
+
+ // two JSMethodCallbackWrappers to handle void callbacks & callbacks with return values
+ template< typename RetType, typename ObjType, typename ...Args >
+ struct JSMethodCallbackWrapper
+ {
+ static void Call( ObjType *pObject, RetType( ObjType::*mf )(Args...), const v8::FunctionCallbackInfo<v8::Value>& v8Args, Args... args )
+ {
+ RetType ret = (pObject->*mf)(panorama_forward< Args >( args )...);
+
+ v8::Handle< v8::Value > value;
+ PanoramaTypeToV8Param( ret, &value );
+
+ v8Args.GetReturnValue().Set( value );
+ }
+
+ };
+
+ template< typename ObjType, typename ...Args >
+ struct JSMethodCallbackWrapper< void, ObjType, Args... >
+ {
+ static void Call( ObjType *pObject, void(ObjType::*mf)(Args...), const v8::FunctionCallbackInfo<v8::Value>& v8Args, Args... args )
+ {
+ (pObject->*mf)(panorama_forward< Args >( args )...);
+ }
+ };
+
+ template< typename RetType, typename ...Args >
+ struct JSFunctionCallbackWrapper
+ {
+ static void Call( RetType( *mf )(Args...), const v8::FunctionCallbackInfo<v8::Value>& v8Args, Args... args )
+ {
+ RetType ret = mf(panorama_forward< Args >( args )... );
+
+ v8::Handle< v8::Value > value;
+ PanoramaTypeToV8Param( ret, &value );
+
+ v8Args.GetReturnValue().Set( value );
+ }
+
+ };
+
+ template< typename ...Args >
+ struct JSFunctionCallbackWrapper < void, Args... >
+ {
+ static void Call( void(*mf)(Args...), const v8::FunctionCallbackInfo<v8::Value>& v8Args, Args... args )
+ {
+ mf(panorama_forward< Args >( args )...);
+ }
+ };
+
+
+ // helper to generate a sequences of index to iterate
+ template<int...> struct index_tuple {};
+
+ template<int I, typename IndexTuple, typename... Types>
+ struct make_indexes_impl;
+
+ template<int I, int... Indexes, typename T, typename ... Types>
+ struct make_indexes_impl < I, index_tuple<Indexes...>, T, Types... >
+ {
+ typedef typename make_indexes_impl<I + 1, index_tuple<Indexes..., I>, Types...>::type type;
+ };
+
+ template<int I, int... Indexes>
+ struct make_indexes_impl < I, index_tuple<Indexes...> >
+ {
+ typedef index_tuple<Indexes...> type;
+ };
+
+ template<typename ... Types>
+ struct make_indexes : make_indexes_impl < 0, index_tuple<>, Types... >
+ {
+ };
+
+
+ // Expands values in tuple into a single function call
+ template< typename ObjType, typename RetType, typename TupleType, class... Args, int... Indexes >
+ void JSMethodCallTuple_Helper( ObjType *pPanel, RetType( ObjType::*mf )(Args...), const v8::FunctionCallbackInfo<v8::Value> &args, index_tuple< Indexes... >, TupleType &tup )
+ {
+ JSMethodCallbackWrapper< RetType, ObjType, Args... >::Call( pPanel, mf, args, panorama_forward<Args>( STDTR1::get<Indexes>( tup ) )... );
+ }
+
+ // Expands values in tuple into a single function call
+ template< typename RetType, typename TupleType, class... Args, int... Indexes >
+ void JSFunctionCallTuple_Helper( RetType( *pFunc )(Args...), const v8::FunctionCallbackInfo<v8::Value> &args, index_tuple< Indexes... >, TupleType &tup )
+ {
+ JSFunctionCallbackWrapper< RetType, Args... >::Call( pFunc, args, panorama_forward<Args>( STDTR1::get<Indexes>( tup ) )... );
+ }
+
+ // converts all v8 args into a tuple
+ template< int Index, typename T >
+ struct ConvertV8ArgsToTuple
+ {
+ static void Call( T &tup, const v8::FunctionCallbackInfo<v8::Value> &args, bool *pbSucceeded )
+ {
+ bool bSucceeded = BConvertV8ArgToPanorama( args[Index - 1], &STDTR1::get< Index - 1>( tup ) );
+ if ( pbSucceeded )
+ pbSucceeded[Index - 1] = bSucceeded;
+
+ if ( !bSucceeded )
+ return;
+
+ ConvertV8ArgsToTuple<Index - 1, T >::Call( tup, args, pbSucceeded );
+ }
+ };
+
+ template< typename T >
+ struct ConvertV8ArgsToTuple< 0, T >
+ {
+ static void Call( T &tup, const v8::FunctionCallbackInfo<v8::Value> &args, bool *pbSucceeded )
+ {
+ }
+ };
+
+
+ // frees all args in tuple
+ template< int Index, typename T >
+ struct FreeV8ArgsToTuple
+ {
+ static void Call( T &tup, bool *pbSucceeded )
+ {
+ if ( pbSucceeded && pbSucceeded[Index - 1] )
+ FreeConvertedParam( STDTR1::get< Index - 1 >( tup ) );
+
+ FreeV8ArgsToTuple<Index - 1, T >::Call( tup, pbSucceeded );
+ }
+ };
+
+ template< typename T >
+ struct FreeV8ArgsToTuple < 0, T >
+ {
+ static void Call( T &tup, bool *pbSucceeded )
+ {
+ }
+ };
+
+ template< typename ObjType, typename RetType, typename ...Args >
+ void JSMethodCallTuple( const v8::FunctionCallbackInfo<v8::Value>& args )
+ {
+ v8::Isolate::Scope isolate_scope( args.GetIsolate() );
+ v8::HandleScope handle_scope( args.GetIsolate() );
+ v8::Persistent<v8::Context> &perContext = UIEngine()->GetV8GlobalContext();
+ v8::Handle<v8::Context> context = v8::Local<v8::Context>::New( GetV8Isolate(), perContext );
+ v8::Context::Scope context_scope( context );
+
+ if( args.Length() < sizeof...(Args) )
+ {
+ v8::String::Utf8Value str( args.Callee()->GetName()->ToString() );
+ GetV8Isolate()->ThrowException( v8::String::NewFromUtf8( GetV8Isolate(), CFmtStr1024( "%s requires %d arguments; only %d given.", *str, (int)sizeof...(Args), (int)args.Length() ).String() ) );
+ return;
+ }
+
+ ObjType *pPanel = GetThisPtrForJSCall<ObjType>( args.Holder() );
+ if ( !pPanel )
+ return;
+
+ v8::Local<v8::Array> callbackArray = v8::Local<v8::Array>::Cast( args.Data() );
+
+ HACKY_FUNC_PTR_CASTER< RetType( ObjType::* )(Args...) > caster;
+ RestoreFuncPtr( caster, callbackArray, 0 );
+
+ bool *pbSucceeded = NULL;
+ if ( sizeof...(Args) > 0 )
+ {
+ pbSucceeded = new bool[sizeof...(Args)];
+ V_memset( pbSucceeded, 0, sizeof...(Args)* sizeof( bool ) );
+ }
+
+ STDTR1::tuple< Args... > tupleArgs;
+ ConvertV8ArgsToTuple< sizeof...(Args), STDTR1::tuple< Args... > >::Call( tupleArgs, args, pbSucceeded );
+
+ bool bSucceeded = true;
+ for ( int i = 0; i < sizeof...(Args); i++ )
+ {
+ if ( !pbSucceeded[i] )
+ bSucceeded = false;
+ }
+
+
+ if ( bSucceeded )
+ JSMethodCallTuple_Helper( pPanel, caster.funcPtr, args, typename make_indexes<Args...>::type(), tupleArgs );
+
+ FreeV8ArgsToTuple< sizeof...(Args), STDTR1::tuple< Args... > >::Call( tupleArgs, pbSucceeded );
+ delete[] pbSucceeded;
+ }
+
+ template< typename ObjType >
+ void JSMethodCallTupleRaw( const v8::FunctionCallbackInfo<v8::Value>& args )
+ {
+ v8::Isolate::Scope isolate_scope( args.GetIsolate() );
+ v8::HandleScope handle_scope( args.GetIsolate() );
+ v8::Persistent<v8::Context> &perContext = UIEngine()->GetV8GlobalContext();
+ v8::Handle<v8::Context> context = v8::Local<v8::Context>::New( GetV8Isolate(), perContext );
+ v8::Context::Scope context_scope( context );
+
+ ObjType *pPanel = GetThisPtrForJSCall<ObjType>( args.Holder() );
+ if ( !pPanel )
+ return;
+
+ v8::Local<v8::Array> callbackArray = v8::Local<v8::Array>::Cast( args.Data() );
+
+ HACKY_FUNC_PTR_CASTER< void ( ObjType::* )( const v8::FunctionCallbackInfo<v8::Value>& ) > caster;
+ RestoreFuncPtr( caster, callbackArray, 0 );
+
+ (pPanel->*caster.funcPtr)( args );
+ }
+
+ template< typename RetType, typename ...Args >
+ void JSFunctionCallTuple( const v8::FunctionCallbackInfo<v8::Value>& args )
+ {
+ v8::Isolate::Scope isolate_scope( args.GetIsolate() );
+ v8::HandleScope handle_scope( args.GetIsolate() );
+ v8::Persistent<v8::Context> &perContext = UIEngine()->GetV8GlobalContext();
+ v8::Handle<v8::Context> context = v8::Local<v8::Context>::New( GetV8Isolate(), perContext );
+ v8::Context::Scope context_scope( context );
+
+ if( args.Length() < sizeof...(Args) )
+ {
+ v8::String::Utf8Value str( args.Callee()->GetName()->ToString() );
+ GetV8Isolate()->ThrowException( v8::String::NewFromUtf8( GetV8Isolate(), CFmtStr1024( "%s requires %d arguments; only %d given.", *str, (int)sizeof...(Args), (int)args.Length() ).String() ) );
+ return;
+ }
+
+ v8::Local<v8::Array> callbackArray = v8::Local<v8::Array>::Cast( args.Data() );
+
+ HACKY_FUNC_PTR_CASTER< RetType( * )(Args...) > caster;
+ RestoreFuncPtr( caster, callbackArray, 0 );
+
+ bool *pbSucceeded = NULL;
+ if( sizeof...(Args) > 0 )
+ {
+ pbSucceeded = new bool[sizeof...(Args)];
+ V_memset( pbSucceeded, 0, sizeof...(Args)* sizeof( bool ) );
+ }
+
+ STDTR1::tuple< Args... > tupleArgs;
+ ConvertV8ArgsToTuple< sizeof...(Args), STDTR1::tuple< Args... > >::Call( tupleArgs, args, pbSucceeded );
+
+ bool bSucceeded = true;
+ for( int i = 0; i < sizeof...(Args); i++ )
+ {
+ if( !pbSucceeded[i] )
+ bSucceeded = false;
+ }
+
+ if( bSucceeded )
+ JSFunctionCallTuple_Helper( caster.funcPtr, args, typename make_indexes<Args...>::type(), tupleArgs );
+
+ FreeV8ArgsToTuple< sizeof...(Args), STDTR1::tuple< Args... > >::Call( tupleArgs, pbSucceeded );
+ delete[] pbSucceeded;
+ }
+
+
+ // Infer types for all arguments.
+ template< uint8 unIndex, typename Type1, typename ...Types >
+ struct RegisterJSTypesDeducer
+ {
+ static void Call( RegisterJSType_t *pTypes, uint8 unMaxIndex )
+ {
+ Assert( unIndex <= RegisterJSEntryInfo_t::k_unMaxParams );
+ if ( unIndex <= RegisterJSEntryInfo_t::k_unMaxParams )
+ {
+ pTypes[unMaxIndex - unIndex] = RegisterJSTypeDeducer_t<Type1>::Type();
+#if defined( SOURCE2_PANORAMA )
+ RegisterJSTypesDeducer< unIndex - 1, Types... >::Call( pTypes, unMaxIndex );
+#endif
+ }
+ }
+ };
+
+ template< typename Type1 >
+ struct RegisterJSTypesDeducer< 0, Type1 >
+ {
+ static void Call( RegisterJSType_t *pTypes, uint8 unMaxIndex )
+ {
+ // This is the termination placeholder.
+ }
+ };
+
+
+ // two RegisterJSMethods, one for const function pointers, one for mutable
+ template < typename ObjType, typename RetType, typename ...Args>
+ void RegisterJSMethod( const char *pchMethodName, RetType( ObjType::*mf )(Args...), const char *pDesc = NULL )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+
+ v8::Handle<v8::Array> callbackArray = v8::Array::New( GetV8Isolate(), 3 );
+ GetPtrToCallbackArray( mf, callbackArray );
+
+ v8::Handle<v8::ObjectTemplate> objTemplate = UIEngine()->GetCurrentV8ObjectTemplateToSetup();
+ objTemplate->Set( v8::String::NewFromUtf8( GetV8Isolate(), pchMethodName ), v8::FunctionTemplate::New( GetV8Isolate(), &JSMethodCallTuple<ObjType, RetType, Args...>, callbackArray ) );
+
+ int nEntry = UIEngine()->NewRegisterJSEntry( pchMethodName, RegisterJSEntryInfo_t::k_EMethod, pDesc, RegisterJSTypeDeducer_t<RetType>::Type() );
+#if defined( SOURCE2_PANORAMA )
+ RegisterJSType_t pParamTypes[RegisterJSEntryInfo_t::k_unMaxParams];
+ RegisterJSTypesDeducer< sizeof...(Args), Args..., void >::Call( pParamTypes, sizeof...(Args) );
+ UIEngine()->SetRegisterJSEntryParams( nEntry, sizeof...(Args), pParamTypes );
+#else
+ REFERENCE( nEntry );
+#endif
+ }
+
+ template < typename ObjType, typename RetType, typename ...Args>
+ void RegisterJSMethod( const char *pchMethodName, RetType( ObjType::*mf )(Args...) const, const char *pDesc )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+
+ v8::Handle<v8::Array> callbackArray = v8::Array::New( GetV8Isolate(), 3 );
+ GetPtrToCallbackArray( mf, callbackArray );
+
+ v8::Handle<v8::ObjectTemplate> objTemplate = UIEngine()->GetCurrentV8ObjectTemplateToSetup();
+ objTemplate->Set( v8::String::NewFromUtf8( GetV8Isolate(), pchMethodName ), v8::FunctionTemplate::New( GetV8Isolate(), &JSMethodCallTuple<ObjType, RetType, Args...>, callbackArray ) );
+
+ int nEntry = UIEngine()->NewRegisterJSEntry( pchMethodName, RegisterJSEntryInfo_t::k_EMethod, pDesc, RegisterJSTypeDeducer_t<RetType>::Type() );
+#if defined( SOURCE2_PANORAMA )
+ RegisterJSType_t pParamTypes[RegisterJSEntryInfo_t::k_unMaxParams];
+ RegisterJSTypesDeducer< sizeof...(Args), Args..., void >::Call( pParamTypes, sizeof...(Args) );
+ UIEngine()->SetRegisterJSEntryParams( nEntry, sizeof...(Args), pParamTypes );
+#else
+ REFERENCE( nEntry );
+#endif
+ }
+
+ template < typename RetType, typename ...Args>
+ void RegisterJSGlobalFunction( const char *pchJSFunctionName, RetType( *pFunc )(Args...), bool bTrueGlobal, const char *pDesc )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+ v8::Persistent<v8::Context> &perContext = UIEngine()->GetV8GlobalContext();
+ v8::Handle<v8::Context> context = v8::Local<v8::Context>::New( GetV8Isolate(), perContext );
+ v8::Context::Scope context_scope( context );
+
+
+ v8::Handle<v8::Array> callbackArray = v8::Array::New( GetV8Isolate(), 3 );
+ GetPtrToCallbackArray( pFunc, callbackArray );
+
+ v8::Handle< v8::FunctionTemplate > funcTempl = v8::FunctionTemplate::New( GetV8Isolate(), &JSFunctionCallTuple< RetType, Args...>, callbackArray );
+ UIEngine()->AddGlobalV8FunctionTemplate( pchJSFunctionName, &funcTempl, bTrueGlobal );
+
+ int nEntry = UIEngine()->NewRegisterJSEntry( pchJSFunctionName, RegisterJSEntryInfo_t::k_EGlobalFunction, pDesc, RegisterJSTypeDeducer_t<RetType>::Type() );
+#if defined( SOURCE2_PANORAMA )
+ RegisterJSType_t pParamTypes[RegisterJSEntryInfo_t::k_unMaxParams];
+ RegisterJSTypesDeducer< sizeof...(Args), Args..., void >::Call( pParamTypes, sizeof...(Args) );
+ UIEngine()->SetRegisterJSEntryParams( nEntry, sizeof...(Args), pParamTypes );
+#else
+ REFERENCE( nEntry );
+#endif
+ }
+
+ inline void RegisterJSGlobalFunctionRaw( const char *pchJSFunctionName, void (*pCallbackFunc)( const v8::FunctionCallbackInfo< v8::Value > &callbackInfo ), bool bTrueGlobal, const char *pDesc = NULL )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+ v8::Persistent<v8::Context> &perContext = UIEngine()->GetV8GlobalContext();
+ v8::Handle<v8::Context> context = v8::Local<v8::Context>::New( GetV8Isolate(), perContext );
+ v8::Context::Scope context_scope( context );
+
+ v8::Handle< v8::FunctionTemplate > funcTempl = v8::FunctionTemplate::New( GetV8Isolate(), pCallbackFunc );
+ UIEngine()->AddGlobalV8FunctionTemplate( pchJSFunctionName, &funcTempl, bTrueGlobal );
+
+ int nEntry = UIEngine()->NewRegisterJSEntry( pchJSFunctionName, RegisterJSEntryInfo_t::k_EGlobalFunction, pDesc, k_ERegisterJSTypeVoid );
+ RegisterJSType_t pParamTypes[1] = { k_ERegisterJSTypeRawV8Args };
+ UIEngine()->SetRegisterJSEntryParams( nEntry, 1, pParamTypes );
+ }
+
+ template < typename ObjType >
+ inline void RegisterJSMethodRaw( const char *pchMethodName, void ( ObjType::*mf )( const v8::FunctionCallbackInfo< v8::Value > &callbackInfo ), const char *pDesc = NULL )
+ {
+ v8::Isolate::Scope isolate_scope( GetV8Isolate() );
+ v8::HandleScope handle_scope( GetV8Isolate() );
+
+ v8::Handle<v8::Array> callbackArray = v8::Array::New( GetV8Isolate(), 3 );
+ GetPtrToCallbackArray( mf, callbackArray );
+
+ v8::Handle<v8::ObjectTemplate> objTemplate = UIEngine()->GetCurrentV8ObjectTemplateToSetup();
+ objTemplate->Set( v8::String::NewFromUtf8( GetV8Isolate(), pchMethodName ), v8::FunctionTemplate::New( GetV8Isolate(), &JSMethodCallTupleRaw<ObjType>, callbackArray ) );
+
+ int nEntry = UIEngine()->NewRegisterJSEntry( pchMethodName, RegisterJSEntryInfo_t::k_EMethod, pDesc, k_ERegisterJSTypeVoid );
+ RegisterJSType_t pParamTypes[1] = { k_ERegisterJSTypeRawV8Args };
+ UIEngine()->SetRegisterJSEntryParams( nEntry, 1, pParamTypes );
+ }
+
+ inline v8::Local< v8::String > JSObjectToJSON( v8::Isolate *pIsolate, v8::Local< v8::Value > object )
+ {
+ v8::Local< v8::Context > context = pIsolate->GetCurrentContext();
+ v8::Local< v8::Object > global = context->Global();
+ v8::Local< v8::Object > global_JSON = v8::Handle< v8::Object >::Cast( global->Get( v8::String::NewFromUtf8( pIsolate, "JSON" ) ) );
+ v8::Local< v8::Function > global_JSON_stringify = v8::Handle< v8::Function >::Cast( global_JSON->Get( v8::String::NewFromUtf8( pIsolate, "stringify" ) ) );
+
+ v8::Local< v8::Value > args[] = { object };
+ return v8::Local< v8::String >::Cast( global_JSON_stringify->Call( global_JSON, 1, args ) );
+ }
+}
+
+#pragma warning(pop)
+
+#if _GNUC
+#pragma GCC diagnostic pop
+#endif
+
+#endif // _WIN32
diff --git a/public/panorama/uioverlaybuffersettype.h b/public/panorama/uioverlaybuffersettype.h
new file mode 100644
index 0000000..8587f3a
--- /dev/null
+++ b/public/panorama/uioverlaybuffersettype.h
@@ -0,0 +1,31 @@
+//========= Copyright ??? 1996-2006, Valve LLC, All rights reserved. ============
+//
+// Purpose: Shared memory for panorama communications.
+//
+// $NoKeywords: $
+//=============================================================================
+
+#ifndef PANORAMA_UIOVERLAYBUFFERSETTYPE_H
+#define PANORAMA_UIOVERLAYBUFFERSETTYPE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+
+// Panorama "top level windows", specified in the order of occlusion
+// priority, bottom windows go first, followed by more visible windows
+// that will occlude the ones below
+enum EPanoramaOverlayBufferSetType
+{
+ k_EPanoramaOverlayBufferSetType_MainWindow = 0,
+ k_EPanoramaOverlayBufferSetType_Notifications = 1,
+ k_EPanoramaOverlayBufferSetType_TotalCount = 2
+};
+
+
+};
+
+#endif // PANORAMA_UIOVERLAYBUFFERSETTYPE_H
diff --git a/public/panorama/uipbmsgbase.h b/public/panorama/uipbmsgbase.h
new file mode 100644
index 0000000..141eb9c
--- /dev/null
+++ b/public/panorama/uipbmsgbase.h
@@ -0,0 +1,597 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef PROTOBUFPOOL_H
+#define PROTOBUFPOOL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "tier0/tslist.h"
+#include "tier1/fmtstr.h"
+#include "tier1/utlstring.h"
+#include "tier1/utlvector.h"
+#if !defined( SOURCE2_PANORAMA )
+#include "tier1/tsmempool.h"
+#include "misc.h"
+#endif
+#include "tier0/vprof.h"
+
+#include "protobuf-2.3.0/src/google/protobuf/message_lite.h"
+
+namespace panorama
+{
+
+#define PBMEM_POOL_LOW_TARGET 256
+#define PBMEM_POOL_HIGH_TARGET 512
+
+class IProtoBufMsgMemoryPool
+{
+public:
+
+ virtual ~IProtoBufMsgMemoryPool() {}
+
+ // Methods that need to be exposed out to examine memory
+ virtual uint32 GetEstimatedSize() = 0;
+ virtual uint32 GetCount() = 0;
+ virtual CUtlString GetName() = 0;
+ virtual uint32 GetAllocHitCount() = 0;
+ virtual uint32 GetAllocMissCount() = 0;
+ virtual void Free( void *pObjectVoid ) = 0;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const char *pchName ) = 0;
+#endif
+};
+
+
+#if defined( SOURCE2_PANORAMA )
+#include <tier0/memdbgon.h>
+#endif
+
+//-----------------------------------------------------------------------------
+// CProtoBufMsgMemoryPool - Implementation for allocation pools for protobufmsgs.
+// We create one of these per protobuf msg type, created on first construction of
+// an object of that type.
+//-----------------------------------------------------------------------------
+template< typename PB_OBJECT_TYPE >
+class CUIProtoBufMsgMemoryPool : public IProtoBufMsgMemoryPool
+{
+public:
+
+ typedef typename CTSList< PB_OBJECT_TYPE * >::Node_t Node;
+
+ CUIProtoBufMsgMemoryPool( uint32 unTargetLow, uint32 unTargetHigh )
+ {
+ m_unTargetCountLow = unTargetLow;
+ m_unTargetCountHigh = unTargetHigh;
+ m_unEstimatedSize = 0;
+ m_unAllocHitCounter = 0;
+ m_unAllocMissCounter = 0;
+ m_pTListFreeObjects = new CTSList< PB_OBJECT_TYPE * >();
+ }
+
+
+ ~CUIProtoBufMsgMemoryPool()
+ {
+ Node *pObject = m_pTListFreeObjects->Pop();
+ while ( pObject )
+ {
+ Destruct( pObject->elem );
+#if defined( SOURCE2_PANORAMA )
+ free( pObject->elem );
+#else
+ FreePv( pObject->elem );
+#endif
+ delete pObject;
+
+ pObject = m_pTListFreeObjects->Pop();
+ }
+ m_pTListFreeObjects->Purge();
+ delete m_pTListFreeObjects;
+ }
+
+ CUtlString GetName()
+ {
+ return PB_OBJECT_TYPE::default_instance().GetTypeName().c_str();
+ }
+
+ uint32 GetEstimatedSize()
+ {
+ return m_pTListFreeObjects->Count()*m_unEstimatedSize;
+ }
+
+ uint32 GetCount()
+ {
+ return m_pTListFreeObjects->Count();
+ }
+
+ uint32 GetAllocHitCount()
+ {
+ return m_unAllocHitCounter;
+ }
+
+ uint32 GetAllocMissCount()
+ {
+ return m_unAllocMissCounter;
+ }
+
+
+ Node * AllocProtoBuf()
+ {
+ Node *pObject = m_pTListFreeObjects->Pop();
+ if ( !pObject )
+ {
+ ++m_unAllocMissCounter;
+ pObject = new Node;
+#if defined( SOURCE2_PANORAMA )
+ pObject->elem = (PB_OBJECT_TYPE *)malloc( sizeof( PB_OBJECT_TYPE ) );
+#else
+ pObject->elem = (PB_OBJECT_TYPE *)PvAllocNoLeakTracking( sizeof( PB_OBJECT_TYPE ) );
+#endif
+ Construct( pObject->elem );
+ }
+ else
+ {
+ ++m_unAllocHitCounter;
+ bool bFreeAnother = false;
+ uint32 unCount = m_pTListFreeObjects->Count();
+
+ // We'll free an extra cached msg every alloc if we are over the higher limit, and every 6th if we
+ // are over the lower limit. This allows some elasticity to peaks in demand.
+ if ( unCount > m_unTargetCountHigh )
+ bFreeAnother = true;
+ else if ( unCount > m_unTargetCountLow && m_unAllocHitCounter % 6 == 0 )
+ bFreeAnother = true;
+
+ if ( bFreeAnother )
+ {
+ // Pop an extra item, so we can get down to target count over time
+ Node *pThrowAway = m_pTListFreeObjects->Pop();
+ if ( pThrowAway )
+ {
+ Destruct( pThrowAway->elem );
+#if defined( SOURCE2_PANORAMA )
+ free( pThrowAway->elem );
+#else
+ FreePv( pThrowAway->elem );
+#endif
+ delete pThrowAway;
+ }
+ }
+ }
+ return pObject;
+ }
+
+ inline void Free( void *pObjectVoid )
+ {
+ Free( (Node *)pObjectVoid );
+ }
+
+ void Free( Node *pObject )
+ {
+ if ( m_unFreeCounter++ % 2000 == 0 || m_unEstimatedSize == 0 )
+ {
+ m_unEstimatedSize = pObject->elem->SpaceUsed();
+ }
+
+ if ( m_unTargetCountHigh > 0 )
+ {
+ // We always cache for re-use on free, though we may throw out later on alloc to shrink the pool
+ pObject->elem->Clear();
+ m_pTListFreeObjects->Push( pObject );
+ }
+ else
+ {
+ Destruct( pObject->elem );
+#if defined( SOURCE2_PANORAMA )
+ free( pObject->elem );
+#else
+ FreePv( pObject->elem );
+#endif
+ delete pObject;
+ }
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const char *pchName )
+ {
+ m_pTListFreeObjects->Validate( validator, "m_pTListFreeObjects" );
+ validator.ClaimMemory_Aligned( m_pTListFreeObjects );
+ }
+#endif // DBGFLAG_VALIDATE
+
+private:
+ CTSList< PB_OBJECT_TYPE * > *m_pTListFreeObjects;
+
+ // Not critical for these to be "right" so they don't need to be thread safe
+ uint32 m_unEstimatedSize;
+ uint32 m_unFreeCounter;
+
+ // These counters are important to get correct, so interlocked in case of allocating on threads
+ CInterlockedInt m_unAllocHitCounter;
+ CInterlockedInt m_unAllocMissCounter;
+
+ // Only set at construction, so not needed to be thread safe
+ uint32 m_unTargetCountLow;
+ uint32 m_unTargetCountHigh;
+};
+
+#if defined( SOURCE2_PANORAMA )
+#include <tier0/memdbgoff.h>
+#endif
+
+//-----------------------------------------------------------------------------
+// Purpose: Ref count wrapper around protobuf message objects
+//-----------------------------------------------------------------------------
+class CMsgLiteRefCount
+{
+public:
+ CMsgLiteRefCount()
+ {
+ m_pMemoryPool = NULL;
+ m_pTSListNode = NULL;
+ m_cRef = 1;
+ }
+
+ // Has to be public, so we can use in memory pool, should always already be at zero ref count though
+ ~CMsgLiteRefCount() { DbgAssert( 0 == m_cRef ); }
+
+ inline int AddRef()
+ {
+ return ThreadInterlockedIncrement( &m_cRef );
+ }
+
+ int Release();
+
+ inline google::protobuf::MessageLite *AccessMsg()
+ {
+ return (google::protobuf::MessageLite *)(((CTSList<void *>::Node_t *)m_pTSListNode)->elem);
+ }
+
+ IProtoBufMsgMemoryPool *m_pMemoryPool;
+ void *m_pTSListNode;
+ void *m_pSelfNode;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName )
+ {
+ VALIDATE_SCOPE();
+
+
+ if ( m_cRef != 0 )
+ {
+ CTSList<void *>::Node_t *pNode = (CTSList<void *>::Node_t *)m_pSelfNode;
+
+ if ( pNode )
+ {
+
+ void *pvMem = MemAlloc_Unalign( pNode );
+ if ( !validator.IsClaimed( pvMem ) )
+ validator.ClaimMemory_Aligned( pNode );
+
+ if ( !validator.IsClaimed( pNode->elem ) )
+ validator.ClaimMemory( pNode->elem );
+ }
+
+ pNode = (CTSList<void *>::Node_t *)m_pTSListNode;
+ if ( pNode )
+ {
+ void *pvMem = MemAlloc_Unalign( pNode );
+ if ( !validator.IsClaimed( pvMem ) )
+ validator.ClaimMemory_Aligned( pNode );
+ }
+ }
+
+ }
+#endif
+
+private:
+
+ friend class CUIProtoBufMsgMemoryPoolMgr;
+
+ volatile int32 m_cRef;
+};
+
+
+//-----------------------------------------------------------------------------
+// CProtoBufMsgMemoryPoolMgr - Manages all the message pools for render messages proto buf objects.
+// Should have one global singleton instance of this which tracks all the pools
+// for individual message types.
+//-----------------------------------------------------------------------------
+class CUIProtoBufMsgMemoryPoolMgr
+{
+public:
+
+ CUIProtoBufMsgMemoryPoolMgr()
+ {
+ m_pTSListMsgLiteRefCount = new CTSList<CMsgLiteRefCount*>;
+ }
+
+ ~CUIProtoBufMsgMemoryPoolMgr()
+ {
+ CTSList<CMsgLiteRefCount*>::Node_t *pNode = m_pTSListMsgLiteRefCount->Pop();
+ while ( pNode )
+ {
+ delete pNode->elem;
+ delete pNode;
+ pNode = m_pTSListMsgLiteRefCount->Pop();
+ }
+
+ FOR_EACH_VEC( m_vecMsgPools, i )
+ {
+ delete m_vecMsgPools[i];
+ }
+ m_vecMsgPools.RemoveAll();
+ }
+
+ CTSList<CMsgLiteRefCount*>::Node_t * AllocMsgLiteRef()
+ {
+ CTSList<CMsgLiteRefCount*>::Node_t *pNode = m_pTSListMsgLiteRefCount->Pop();
+ if ( !pNode )
+ {
+ pNode = new CTSList<CMsgLiteRefCount*>::Node_t;
+ pNode->elem = new CMsgLiteRefCount();
+ return pNode;
+ }
+ else
+ {
+ DbgAssert( pNode->elem->m_cRef == 0 );
+ pNode->elem->m_cRef = 1;
+ }
+ return pNode;
+ }
+
+ void FreeMsgLiteRef( CTSList<CMsgLiteRefCount*>::Node_t * pRef )
+ {
+#if defined(_DEBUG) && !defined(NO_MALLOC_OVERRIDE) && !defined( SOURCE2_PANORAMA )
+ Assert( g_pMemAllocSteam->IsValid( pRef->elem ) );
+#endif
+ m_pTSListMsgLiteRefCount->Push( pRef );
+ }
+
+ void RegisterPool( IProtoBufMsgMemoryPool * pPool )
+ {
+ m_vecMsgPools.AddToTail( pPool );
+ }
+
+ void DumpPoolInfo()
+ {
+ uint32 unTotalSize = 0;
+ Msg( "CRenderMsgMemoryPoolMgr:\n" );
+ Msg( " PoolName Count Est. Size Hit Rate\n" );
+ Msg( " ----------------------------------------- ----------- ----------- -----------\n" );
+ FOR_EACH_VEC( m_vecMsgPools, i )
+ {
+ uint32 unHitCount = m_vecMsgPools[i]->GetAllocHitCount();
+ uint32 unMissCount = m_vecMsgPools[i]->GetAllocMissCount();
+ float flHitRate = 0.0f;
+ if ( unHitCount > 0 || unMissCount > 0 )
+ {
+ flHitRate = (float)unHitCount / (float)(unHitCount+unMissCount);
+ flHitRate *= 100.0f;
+ }
+
+ uint32 unEstimate = m_vecMsgPools[i]->GetEstimatedSize();
+ Msg( "%43s%12d%12s%12s\n", m_vecMsgPools[i]->GetName().String(), m_vecMsgPools[i]->GetCount(), V_pretifymem( (float)unEstimate, 2, true ), CFmtStr( "%f%%", flHitRate ).Access() );
+ unTotalSize += unEstimate;
+ }
+ Msg( " -----------------------------------------------------------------------------\n" );
+ Msg( " Total: %s\n", V_pretifymem( (float)unTotalSize, 2, true ) );
+
+ Msg( " -----------------------------------------------------------------------------\n" );
+ Msg( "TSList for CMsgLiteRef size: %s\n", V_pretifymem( (float)m_pTSListMsgLiteRefCount->Count(), 2, true ) );
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, const char *pchName )
+ {
+ ValidateObj( m_vecMsgPools );
+ FOR_EACH_VEC( m_vecMsgPools, i )
+ {
+ ValidatePtr( m_vecMsgPools[i] );
+ }
+ validator.ClaimMemory_Aligned( m_pTSListMsgLiteRefCount );
+ m_pTSListMsgLiteRefCount->Validate( validator, "m_pTSListMsgLiteRefCount" );
+
+ CUtlVector< CTSList<CMsgLiteRefCount *>::Node_t * > vecTemp;
+
+ CTSList<CMsgLiteRefCount *>::Node_t *pNode = m_pTSListMsgLiteRefCount->Pop();
+ while ( pNode )
+ {
+ ValidatePtrIfNeeded( pNode->elem );
+ vecTemp.AddToTail( pNode );
+ pNode = m_pTSListMsgLiteRefCount->Pop();
+ }
+
+ FOR_EACH_VEC( vecTemp, i )
+ {
+ m_pTSListMsgLiteRefCount->Push( vecTemp[i] );
+ }
+ }
+#endif // DBGFLAG_VALIDATE
+
+private:
+ CUtlVector< IProtoBufMsgMemoryPool * > m_vecMsgPools;
+ CTSList<CMsgLiteRefCount *> *m_pTSListMsgLiteRefCount;
+};
+
+
+// Interface that rendermsgs of all types implement
+class IUIProtoBufMsg
+{
+public:
+ virtual ~IUIProtoBufMsg() {}
+ virtual void SerializeInProc( CUtlBuffer *pBuffer ) const = 0;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Base class for protobuf objects
+//-----------------------------------------------------------------------------
+template< typename PB_OBJECT_TYPE >
+class CUIProtoBufMsg : public IUIProtoBufMsg
+{
+private:
+ static bool s_bRegisteredWithMemoryPoolMgr;
+ static CThreadMutex s_Mutex;
+ static CUIProtoBufMsgMemoryPool< PB_OBJECT_TYPE > *s_pMemoryPool;
+
+public:
+
+ typedef typename CTSList<PB_OBJECT_TYPE *>::Node_t Node;
+
+ // Called on construction of each object of this type, but only does work
+ // once to setup memory pools for the class type.
+ static void OneTimeInit()
+ {
+ // If we haven't done registration do so now
+ if ( !s_bRegisteredWithMemoryPoolMgr )
+ {
+ // Get the lock and make sure we still haven't
+ s_Mutex.Lock();
+ if ( !s_bRegisteredWithMemoryPoolMgr )
+ {
+ s_pMemoryPool = new CUIProtoBufMsgMemoryPool< PB_OBJECT_TYPE >( PBMEM_POOL_LOW_TARGET, PBMEM_POOL_HIGH_TARGET );
+ UIEngine()->MsgMemoryPoolMgr()->RegisterPool( s_pMemoryPool );
+ s_bRegisteredWithMemoryPoolMgr = true;
+ }
+ s_Mutex.Unlock();
+ }
+ }
+
+ CUIProtoBufMsg()
+ {
+ OneTimeInit();
+ CTSList<CMsgLiteRefCount *>::Node_t *pRefCountNode = UIEngine()->MsgMemoryPoolMgr()->AllocMsgLiteRef();
+ m_pMsgRefCount = pRefCountNode->elem;
+ m_pMsgRefCount->m_pSelfNode = pRefCountNode;
+ m_pMsgRefCount->m_pMemoryPool = s_pMemoryPool;
+ Node *pNode = s_pMemoryPool->AllocProtoBuf();
+ m_pMsgRefCount->m_pTSListNode = pNode;
+ m_bIsValid = true;
+ }
+
+ // Expose memory pool for direct allocation of underlying PB msg objects
+ static Node *AllocProtoBufMsgObject()
+ {
+ OneTimeInit();
+ return s_pMemoryPool->AllocProtoBuf();
+ }
+
+ // Expose memory pool for direct allocation of underlying PB msg objects
+ static void FreeProtoBufMsgObject( Node *pMsg )
+ {
+ s_pMemoryPool->Free( pMsg );
+ }
+
+ // Construct and deserialize in one
+ CUIProtoBufMsg( CUtlBuffer *pBuffer )
+ {
+ OneTimeInit();
+ m_pMsgRefCount = NULL;
+ m_bIsValid = BDeserializeInProc( pBuffer );
+ }
+
+ // Destructor
+ virtual ~CUIProtoBufMsg()
+ {
+ CleanupAllocations();
+ }
+
+ bool BIsValid() { return m_bIsValid; }
+
+ inline void SerializeInProc( CUtlBuffer *pBuffer ) const
+ {
+
+ // Ensure enough for type, size, and serialized data
+ pBuffer->EnsureCapacity( pBuffer->TellPut() + sizeof(uint32) + sizeof( uint64 ) );
+
+ m_pMsgRefCount->AddRef();
+ pBuffer->PutUnsignedInt( (int)m_eCmd );
+ pBuffer->PutUnsignedInt64( (uint64)m_pMsgRefCount );
+ }
+
+ inline bool BDeserializeInProc( CUtlBuffer *pBuffer )
+ {
+ if ( pBuffer->GetBytesRemaining() < (int)sizeof(uint64) )
+ return false;
+
+ uint64 ulPtr = pBuffer->GetUnsignedInt64();
+ if ( ulPtr == 0 )
+ return false;
+
+ CleanupAllocations();
+ m_pMsgRefCount = (CMsgLiteRefCount*)ulPtr;
+ m_pMsgRefCount->AddRef();
+ return true;
+ }
+
+ void SerializeCrossProc( CUtlBuffer *pBuffer ) const
+ {
+ VPROF_BUDGET( "CUIProtoBufMsg::SerializeCrossProc", VPROF_BUDGETGROUP_TENFOOT );
+ uint32 unSize = m_pMsgRefCount->AccessMsg()->ByteSize();
+
+ // Ensure enough for type, size, and serialized data
+ pBuffer->EnsureCapacity( pBuffer->TellPut() + sizeof(uint32) * 3 + unSize ); // bugbug cboyd - drop to * 2 whenpassthrough is removed below
+
+ pBuffer->PutUnsignedInt( (int)m_eCmd );
+ pBuffer->PutUnsignedInt( unSize );
+
+ if ( unSize == 0 )
+ return;
+
+ uint8 *pBody = (uint8*)pBuffer->Base()+pBuffer->TellPut();
+ m_pMsgRefCount->AccessMsg()->SerializeWithCachedSizesToArray( pBody );
+ pBuffer->SeekPut( CUtlBuffer::SEEK_CURRENT, unSize );
+ }
+
+ bool BDeserializeCrossProc( CUtlBuffer *pBuffer )
+ {
+ VPROF_BUDGET( "CUIProtoBufMsg::BDeserialize", VPROF_BUDGETGROUP_TENFOOT );
+ if ( pBuffer->GetBytesRemaining() < (int)sizeof(uint32) )
+ return false;
+ uint32 unSize = pBuffer->GetUnsignedInt();
+
+ if ( unSize == 0 )
+ return true;
+
+ if ( pBuffer->GetBytesRemaining() < (int)unSize )
+ return false;
+
+ bool bSucccess = m_pMsgRefCount->AccessMsg()->ParseFromArray( (uint8*)pBuffer->Base()+pBuffer->TellGet(), unSize );
+ pBuffer->SeekGet( CUtlBuffer::SEEK_CURRENT, unSize );
+
+ return bSucccess;
+ }
+
+ // Accessors
+ PB_OBJECT_TYPE &Body() { return *((PB_OBJECT_TYPE*)(m_pMsgRefCount->AccessMsg())); }
+ const PB_OBJECT_TYPE &BodyConst() const { return *((const PB_OBJECT_TYPE*)(m_pMsgRefCount->AccessMsg())); }
+
+protected:
+ CMsgLiteRefCount *m_pMsgRefCount;
+ int m_eCmd;
+ bool m_bIsValid;
+private:
+
+ void CleanupAllocations()
+ {
+ SAFE_RELEASE( m_pMsgRefCount );
+ }
+
+};
+
+
+// Statics
+template< typename PB_OBJECT_TYPE > bool CUIProtoBufMsg< PB_OBJECT_TYPE>::s_bRegisteredWithMemoryPoolMgr = false;
+template< typename PB_OBJECT_TYPE > CThreadMutex CUIProtoBufMsg< PB_OBJECT_TYPE>::s_Mutex;
+template< typename PB_OBJECT_TYPE > CUIProtoBufMsgMemoryPool< PB_OBJECT_TYPE > *CUIProtoBufMsg< PB_OBJECT_TYPE>::s_pMemoryPool = NULL;
+
+} // namespace panorama
+
+#endif //PROTOBUFPOOL_H
diff --git a/public/panorama/uischeduleddel.h b/public/panorama/uischeduleddel.h
new file mode 100644
index 0000000..2103c30
--- /dev/null
+++ b/public/panorama/uischeduleddel.h
@@ -0,0 +1,44 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UISCHEDULEDDEL_H
+#define UISCHEDULEDDEL_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier1/utldelegate.h"
+
+namespace panorama
+{
+
+
+// Panorama wrapper around CUtlSymbol which always creates symbol in panorama.dll module
+class CUIScheduledDel
+{
+public:
+ // constructor, destructor
+ CUIScheduledDel( CUtlDelegate< void() > del );
+ ~CUIScheduledDel();
+
+ void Schedule( double flSecondsToRunIn );
+
+ void Cancel();
+
+ bool BScheduled();
+
+ double GetSecondsUntilScheduled() { return MAX( m_flNextScheduled - UIEngine()->GetCurrentFrameTime(), 0.0 ); }
+
+private:
+
+ double m_flNextScheduled;
+ int m_iScheduledIndex;
+ CUtlDelegate< void() > m_del;
+};
+
+} // namespace panorama
+
+#endif // UISCHEDULEDDEL_H \ No newline at end of file
diff --git a/public/panorama/uisettings.h b/public/panorama/uisettings.h
new file mode 100644
index 0000000..a0ae0dc
--- /dev/null
+++ b/public/panorama/uisettings.h
@@ -0,0 +1,50 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UISETTINGS_H
+#define UISETTINGS_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: interface to query settings for this panorama UI
+//-----------------------------------------------------------------------------
+class IUISettings
+{
+public:
+ virtual const char *GetUILanguage() = 0;
+ virtual void GetPreferredResolution( int &dxPreferred, int &dyPreferred ) = 0;
+ virtual void UpdateGamepadMappingHints( const char *pszConnectedMappings ) = 0;
+ virtual bool BAllowOSModalDialog() = 0;
+
+ virtual void GetDefaultAudioDevice( CUtlString &strDevice ) = 0;
+ virtual void SetDefaultAudioDevice( const char *pchDevice ) = 0;
+
+ // if unset then the default audio device is used for voice output
+ virtual void GetDefaultVoiceDevice( CUtlString &strDevice ) = 0;
+ virtual void SetDefaultVoiceDevice( const char *pchDevice ) = 0;
+
+ virtual bool GetUseSystemAudioForVoice() = 0;
+ virtual void SetUseSystemAudioForVoice( bool bUseSystemAudio ) = 0;
+
+ virtual ETextInputHandlerType_t GetActiveTextInputHandlerType() const = 0;
+ virtual void SetDefaultTextInputHandlerType( ETextInputHandlerType_t eType ) = 0;
+
+ virtual ELanguage GetDefaultInputLanguage() const = 0;
+ virtual void SetDefaultInputLanguage( ELanguage ) = 0;
+
+ // should we show the screen saver?
+ virtual bool GetScreenSaverEnabled() = 0;
+ virtual void SetScreenSaverEnabled( bool bEnabled ) = 0;
+};
+
+} // namespace panorama
+
+#endif // UISETTINGS_H
diff --git a/public/panorama/uitoplevelwindow.h b/public/panorama/uitoplevelwindow.h
new file mode 100644
index 0000000..321b757
--- /dev/null
+++ b/public/panorama/uitoplevelwindow.h
@@ -0,0 +1,299 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UITOPLEVELWINDOW_H
+#define UITOPLEVELWINDOW_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "utlstring.h"
+#include "utlmap.h"
+#include "utllinkedlist.h"
+#if !defined( SOURCE2_PANORAMA )
+#include "constants.h"
+#include "globals.h"
+#endif
+#include "reliabletimer.h"
+#if !defined( SOURCE2_PANORAMA )
+#include "framefunction.h"
+#endif
+#include "input/iuiinput.h"
+#include "input/mousecursors.h"
+#include "iuiengine.h"
+#include "color.h"
+#include "uievent.h"
+#include "iuiwindow.h"
+#include "iuirenderengine.h"
+#include "uipanel.h"
+
+namespace panorama
+{
+
+class CUIRenderEngine;
+class CPanel2D;
+class CUIWindowInput;
+class CUIEngine;
+class CMouseCursorTexture;
+class CImageResourceManager;
+class CFastScrollSoundManager;
+class IUI3DSurface;
+class CMouseCursorRender;
+
+
+//
+// Top level window class
+//
+class CTopLevelWindow : public panorama::IUIWindow
+{
+public:
+ CTopLevelWindow( CUIEngine *pUIEngineParent );
+ virtual ~CTopLevelWindow();
+
+ // Delete the window object
+ virtual void Delete() OVERRIDE{ delete this; }
+
+ // Final step of initialization, post constructor, and post BInitializeSurface() on individidual window type
+ virtual bool FinishInitialization();
+
+ // Run any per window frame func logic
+ virtual void RunPlatformFrame();
+
+ // Set scaling factor that applies to all x/y values in the UI for the window, used so we can
+ // author content at say 1080p but pass 0.6666666f for this to render in 720p on cards with poor
+ // fill rates or TVs without 1080p support.
+ virtual void SetUIScaleFactor( float flScaleFactor ) OVERRIDE;
+ virtual float GetUIScaleFactor() OVERRIDE { return m_flScaleFactor; }
+
+ // Window position/activation management
+ const char * GetTargetMonitor() { return m_strTargetMonitor.String(); }
+ virtual void GetWindowBounds( float &left, float &top, float &right, float &bottom ) = 0;
+ virtual void GetClientDimensions( float &width, float &height ) OVERRIDE = 0;
+
+ virtual bool BAllowInput( InputMessage_t &msg );
+
+ // Access the rendering interface you use to draw onto this window
+ virtual IUIRenderEngine * UIRenderEngine() OVERRIDE{ return (IUIRenderEngine*)m_pRenderEngine; }
+ CUIRenderEngine *GetUIRenderEngine() { return m_pRenderEngine; }
+ virtual bool BIsVisible() { return true; }
+ virtual bool BIsOverlay() OVERRIDE { return UIEngine()->BIsOverlayTarget(m_eRenderTarget); }
+ virtual bool BIsSteamWMOverlay() OVERRIDE { return m_eRenderTarget == IUIEngine::k_ERenderToOverlaySteamWM; }
+
+ virtual bool BIsFullscreen() { return IUIEngine::BIsRenderingToFullScreen( m_eRenderTarget ); }
+ virtual bool BIsFullscreenBorderlessWindow() { return m_eRenderTarget == IUIEngine::k_ERenderBorderlessFullScreenWindow; }
+ bool SetFullscreen( bool bFullscreen );
+ bool BEnforceWindowAspectRatio() { return m_bEnforceWindowAspectRatio; }
+ virtual uint32 GetSurfaceWidth() OVERRIDE { return m_unSurfaceWidth; }
+ virtual uint32 GetSurfaceHeight() OVERRIDE { return m_unSurfaceHeight; }
+ virtual uint32 GetWindowWidth() OVERRIDE { return m_unWindowWidth; }
+ virtual uint32 GetWindowHeight() OVERRIDE { return m_unWindowHeight; }
+ void ConvertClientToSurfaceCoord( float *px, float *py );
+ void GetFPSAverages( float &fpsPaint, float &fpsAnimation, float &fpsRender );
+ virtual void GetSessionFPSAverages( float &fpsPaint, float &fpsAnimation, float &fpsRender ) OVERRIDE;
+ virtual void GetNumPeriodsBelowMinFPS( int &nSlowPeriods ) OVERRIDE;
+
+ // Clear color for the window, normally black, transparent for overlay
+ virtual Color GetClearColor() { return Color( 0, 0, 0, 255 ); }
+
+ // Panel management for the window
+ int AddPanel( CUIPanel *pPanel, bool bVisible );
+ void RemovePanel( int iPanelIndex, bool bVisible );
+ int SetPanelVisible( int iPanelIndex, bool bVisible );
+ virtual void AddClass( const char *pchName ) OVERRIDE;
+ virtual void RemoveClass( const char *pchName ) OVERRIDE;
+
+ // Layout/paint for window
+ virtual void LayoutAndPaintIfNeeded();
+
+ // Paint an empty frame so the animation/render threads will run but do nothing but LRU/clear data
+ virtual void PaintEmptyFrameAndForceLaterRepaint();
+
+ // Layout file auto-reload for windows children panels
+ void ReloadLayoutFile( CPanoramaSymbol symPath );
+ void OnReloadStyleFile( CPanoramaSymbol symPath );
+
+ // Access input engine for window
+ virtual IUIWindowInput *UIWindowInput() OVERRIDE { return (IUIWindowInput *)m_pInputEngine; }
+
+ // custom mouse cursor support, returns true if we want our manually drawn one, false for OS specific ones
+ bool BUseCustomMouseCursor() { return m_bUseCustomMouseCursor; }
+ // used by the os specific case to update the cursor
+ virtual void SetMouseCursor( EMouseCursors eCursor ) = 0;
+ IImageSource *GetMouseCursorTexture( Vector2D *pptHotspot );
+
+ virtual bool BCursorVisible() OVERRIDE;
+ virtual bool BCursorFadingOut() OVERRIDE;
+ virtual void WakeupMouseCursor() OVERRIDE;
+ virtual void FadeOutCursorNow() OVERRIDE;
+
+ // Access image manager for window
+ CImageResourceManager* AccessImageManager() { return m_pImageResourceManager; }
+
+ // Set a context ptr that is attached to the window, just lets other code (panels) that
+ // has access to the window access some shared state across the window.
+ virtual void SetContextPtr( void *pv ) OVERRIDE { m_pContextPtr = pv; }
+
+ // Get the context ptr that is attached to the window
+ virtual void * GetContextPtr() const OVERRIDE { return m_pContextPtr; }
+
+ void ReloadChangedFile( const char *pchFile );
+
+ // Access fast scroll sound manager for the window
+ CFastScrollSoundManager * AccessFastScrollSoundMgr();
+
+ void GetMouseWheelRepeats( bool bScrollUp, int lines, uint8 &unRepeats );
+
+ virtual uint32 GetNumVisibleTopLevelPanels() const OVERRIDE { return (uint32)m_listVisiblePanels.Count(); }
+
+ virtual const CUtlLinkedList< IUIPanel* > &GetTopLevelVisiblePanels() const OVERRIDE { return (CUtlLinkedList< IUIPanel* > &)m_listVisiblePanels; }
+
+ // Get the last time the window layed out and painted
+ float GetLastLayoutAndPaintTime() { return m_flLastLayoutAndPaintTime; }
+
+ // Set max FPS for the window
+ void SetMaxFPS( float flMaxFPS );
+
+ // Set a min FPS for the window, this actually just prevents setting the max lower
+ virtual void SetMinFPS( float flMinFPS ) OVERRIDE { m_flMinFPS = flMinFPS; }
+
+ // access data about how the gamepad was used
+ virtual bool BWasGamepadConnectedThisSession() OVERRIDE;
+ virtual bool BWasGamepadUsedThisSession() OVERRIDE;
+
+ virtual bool BWasSteamControllerConnectedThisSession() OVERRIDE;
+ virtual bool BWasSteamControllerUsedThisSession() OVERRIDE;
+
+ // metrics
+ virtual void RecordDaisyWheelUsage( float flEntryTimeInSeconds, int nWordsEntered, bool bViaKeyboard, bool bViaGamepad ) OVERRIDE;
+ virtual void GetDaisyWheelWPM( int &nWordsTyped, float &flMixedWPM, float &flKeyboardOnlyWPM, float &flGamepadOnlyWPM ) OVERRIDE;
+
+ bool BFinishedInitialization() { return m_bFinishedInitialization; }
+
+ virtual bool BIsWindowInLayoutPass() OVERRIDE { return m_bInLayoutTraverse; }
+
+ virtual void SetInhibitInput( bool bInhibitInput ) OVERRIDE;
+ virtual void SetPreventForceWindowOnTop( bool bPreventForceTopLevel ) OVERRIDE;
+
+ // Access overlay window interface for this window, NULL on non Steam Overlay windows
+ virtual IUIOverlayWindow *GetOverlayInterface() OVERRIDE { return NULL; }
+
+ virtual void SetFocusBehavior( EWindowFocusBehavior eFocusBehavior ) OVERRIDE { m_eFocusBehavior = eFocusBehavior; }
+ virtual EWindowFocusBehavior GetFocusBehavior() OVERRIDE{ return m_eFocusBehavior; }
+
+ virtual void OnDeviceLost() OVERRIDE;
+ virtual void OnDeviceRestored() OVERRIDE;
+ virtual bool BDeviceLost() OVERRIDE;
+
+ // Clears the GPU resources associated with the window before the next render frame
+ virtual void ClearGPUResourcesBeforeNextFrame() OVERRIDE;
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+
+ bool PrepareForValidate();
+ bool ResumeFromValidate();
+#endif
+protected:
+
+ // Perform layout prior to paint
+ void PerformLayout();
+ bool BIsGuideButton( const InputMessage_t &msg );
+
+ // Render engine instance for window
+ CUIRenderEngine *m_pRenderEngine;
+
+ // Do we need to clear gpu resources before repaint
+ uint32 m_unFramesToClearGPUResourcesBeforeRepaint;
+
+ // Image manager for the window
+ CImageResourceManager *m_pImageResourceManager;
+
+ bool m_bDeviceLost;
+ bool m_bAlreadyForcedRepaintAllSinceLastPaint;
+ CUtlString m_strTargetMonitor;
+ uint32 m_unSurfaceWidth, m_unSurfaceHeight;
+ uint32 m_unWindowWidth, m_unWindowHeight;
+ IUIEngine::ERenderTarget m_eRenderTarget;
+ bool m_bFixedSurfaceSize;
+ bool m_bEnforceWindowAspectRatio;
+ bool m_bUseCustomMouseCursor; // true if we draw our tenfoot cursors and not the win32 ones for this panel
+ bool m_bCursorWasVisibleLastFrame;
+ EMouseCursors m_eCursorCurrent; // current cursor to draw
+ CMouseCursorTexture *m_pMouseCursor; // contains the image data for the cursors we can display
+
+ // owner of details about the cursor state
+ CMouseCursorRender *m_pCursorRender;
+
+ // Input engine
+ CUIWindowInput *m_pInputEngine;
+
+ // the ui engine that owns us
+ CUIEngine *m_pUIEngineParent;
+ void *m_pContextPtr;
+
+ // Scale factor for all drawing sizes
+ float m_flScaleFactor;
+
+ // Min fps value the max fps can be set to for this window
+ float m_flMinFPS;
+
+ // Track last layout and paint time
+ double m_flLastLayoutAndPaintTime;
+
+ // Pointer for the surface interface created for the window
+ IUI3DSurface *m_pSurfaceInterface;
+
+ // Panel lists
+ CUtlLinkedList< CUIPanel * > m_listVisiblePanels;
+ CUtlLinkedList< CUIPanel * > m_listInvisiblePanels;
+
+ // Classes to apply to top level panels
+ CUtlVector< CPanoramaSymbol > m_vecStyleClasses;
+
+ // Panels to asynchronously add classes to
+ CUtlVector< CPanelPtr< IUIPanel > > m_vecPanelsAddClasses;
+
+ // Panels to asynchronously remove classes from
+ CUtlVector< CPanelPtr< IUIPanel > > m_vecPanelsRemoveClasses;
+
+ CFastScrollSoundManager *m_pFastScrollSoundManager;
+
+ // Mouse wheel repeat tracking
+ uint8 m_unMouseWheelUpRepeats;
+ uint8 m_unMouseWheelDownRepeats;
+ double m_flLastMouseWheelUp;
+ double m_flLastMouseWheelDown;
+
+ bool m_bInLayoutTraverse;
+ bool m_bInPaintTraverse;
+ bool m_bFinishedInitialization;
+
+ // daisy wheel usage for this window
+ enum EDaisyWheelInputType
+ {
+ eDaisyWheelInputType_KeyboardOnly,
+ eDaisyWheelInputType_GamepadOnly,
+ eDaisyWheelInputType_KeyboardAndGamePad,
+
+ eDaisyWheelInputType_MAX
+ };
+ struct DaisyWheelUsage_t
+ {
+ int nWords;
+ float flTime;
+ };
+ DaisyWheelUsage_t m_flDaisyWheelWPM[eDaisyWheelInputType_MAX];
+
+ virtual void Shutdown();
+
+ bool m_bInhibitInput;
+
+ EWindowFocusBehavior m_eFocusBehavior;
+};
+
+} // namespace panorama
+
+#endif // UITOPLEVELWINDOW_H
diff --git a/public/panorama/uitoplevelwindowopenvroverlay.h b/public/panorama/uitoplevelwindowopenvroverlay.h
new file mode 100644
index 0000000..a4cbe6f
--- /dev/null
+++ b/public/panorama/uitoplevelwindowopenvroverlay.h
@@ -0,0 +1,108 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UITOPLEVELWINDOWOPENVROVERLAY_H
+#define UITOPLEVELWINDOWOPENVROVERLAY_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <openvr.h>
+
+namespace panorama
+{
+class CTopLevelWindowOverlay;
+
+
+class CTopLevelWindowOpenVROverlay : public CTopLevelWindow
+{
+ typedef CTopLevelWindow BaseClass;
+public:
+ CTopLevelWindowOpenVROverlay( CUIEngine *pUIEngineParent );
+ virtual ~CTopLevelWindowOpenVROverlay();
+
+ // Initialize backing surface for window
+ virtual bool BInitializeSurface( int nWidth, int nHeight, vr::VROverlayHandle_t ulOverlayHandle );
+
+ // Run any per window frame func logic
+ virtual void RunPlatformFrame();
+
+ // Resize the window to specified dimensions
+ virtual void OnWindowResize( uint32 nWidth, uint32 nHeight );
+
+ // Window position management
+ virtual void SetWindowPosition( float x, float y );
+ virtual void GetWindowPosition( float &x, float &y );
+ virtual void GetWindowBounds( float &left, float &top, float &right, float &bottom );
+ virtual void GetClientDimensions( float &width, float &height );
+ virtual void Activate( bool bForceful );
+ virtual bool BHasFocus() { return m_bFocus; }
+ virtual bool BIsFullscreen() { return m_bFullScreen; }
+ virtual void* GetNativeWindowHandle() { return 0; }
+
+ virtual bool BAllowInput( InputMessage_t &msg );
+ virtual bool BIsVisible() { return m_bVisible; }
+ virtual void SetVisible( bool bVisible ) { AssertMsg( false, "SetVisible not implemented on CTopLevelWindowOverlay" ); }
+
+ void SetInputEnabled( bool bEnabled ) { m_bInputEnabled = bEnabled; }
+
+ // Clear color for the window, normally black, transparent for overlay
+ virtual Color GetClearColor() { return Color( 0, 0, 0, 0 ); }
+
+ // Necessary for generating mouse enter & leave events on windows
+ bool IsMouseOver() { return m_bMouseOverWindow; }
+ void OnMouseEnter();
+ void OnMouseLeave() { m_bMouseOverWindow = false; }
+
+ void SetMouseCursor( EMouseCursors eCursor );
+
+ bool SetGameProcessInfo( AppId_t nAppId, bool bCanSharedSurfaces, int32 eTextureFormat );
+ void ProcessInputEvents();
+
+ bool BVisiblityChanged() const { return m_bVisibleThisFrame != m_bVisibleLastFrame; }
+
+ void PushOverlayRenderCmdStream( CSharedMemStream *pRenderStream, unsigned long dwPID, float flOpacity, EOverlayWindowAlignment alignment );
+
+ void SetGameWindowSize( uint32 nWidth, uint32 nHeight );
+ void SetFixedSurfaceSize( uint32 unSurfaceWidth, uint32 unSurfaceHeight );
+
+ void OnMouseMove( float x, float y );
+
+ void SetFocus( bool bFocus );
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+protected:
+ virtual void Shutdown();
+
+private:
+
+ IUI3DSurface *m_p3DSurface;
+ bool m_bMouseOverWindow;
+
+ bool m_bInputEnabled;
+ bool m_bFocus;
+ bool m_bCanShareSurfaces;
+
+ bool m_bVisibleThisFrame;
+ bool m_bVisibleLastFrame;
+
+ uint32 m_unGameWidth;
+ uint32 m_unGameHeight;
+
+ bool m_bFullScreen;
+
+ bool m_bVisible;
+
+ vr::VROverlayHandle_t m_ulOverlayHandle;
+};
+
+
+
+} // namespace panorama
+
+#endif // UITOPLEVELWINDOWOPENVROVERLAY_H
diff --git a/public/panorama/uitoplevelwindowoverlay.h b/public/panorama/uitoplevelwindowoverlay.h
new file mode 100644
index 0000000..7218615
--- /dev/null
+++ b/public/panorama/uitoplevelwindowoverlay.h
@@ -0,0 +1,177 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef UITOPLEVELWINDOWOVERLAY_H
+#define UITOPLEVELWINDOWOVERLAY_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+// bad reach
+#include "../../../panorama/input/controller.h"
+
+class CSharedMemStream;
+namespace IPC
+{
+ class IEvent;
+ class ISharedMem;
+}
+
+namespace panorama
+{
+class CTopLevelWindowOverlay;
+class COverlayInterface;
+
+
+class CTopLevelWindowOverlay : public CTopLevelWindow
+{
+ typedef CTopLevelWindow BaseClass;
+public:
+ CTopLevelWindowOverlay( CUIEngine *pUIEngineParent );
+ virtual ~CTopLevelWindowOverlay();
+
+ // Access overlay window interface for this window, NULL on non Steam Overlay windows
+ virtual IUIOverlayWindow *GetOverlayInterface();
+
+ // Initialize backing surface for window
+ virtual bool BInitializeSurface( const char *pchWindowTitle, int nWidth, int nHeight, IUIEngine::ERenderTarget eRenderTarget, bool bFixedSurfaceSize, bool bEnforceWindowAspectRatio, bool bUseCustomMouseCursor, const char *pchTargetMonitor );
+
+ // Run any per window frame func logic
+ virtual void RunPlatformFrame();
+
+ // Resize the window to specified dimensions
+ virtual void OnWindowResize( uint32 nWidth, uint32 nHeight );
+
+ // Window position management
+ virtual void SetWindowPosition( float x, float y );
+ virtual void GetWindowPosition( float &x, float &y );
+ virtual void GetWindowBounds( float &left, float &top, float &right, float &bottom );
+ virtual void GetClientDimensions( float &width, float &height );
+ virtual void Activate( bool bForceful );
+ virtual bool BHasFocus() { return m_bFocus; }
+ virtual bool BIsFullscreen() { return m_bFullScreen; }
+ virtual void* GetNativeWindowHandle() { return 0; }
+
+ virtual bool BAllowInput( InputMessage_t &msg );
+ virtual bool BIsVisible() { return m_bVisible; }
+ virtual void SetVisible( bool bVisible ) { AssertMsg( false, "SetVisible not implemented on CTopLevelWindowOverlay" ); }
+
+ void SetInputEnabled( bool bEnabled ) { m_bInputEnabled = bEnabled; }
+
+ // Clear color for the window, normally black, transparent for overlay
+ virtual Color GetClearColor() { return Color( 0, 0, 0, 0 ); }
+
+ // Necessary for generating mouse enter & leave events on windows
+ bool IsMouseOver() { return m_bMouseOverWindow; }
+ void OnMouseEnter();
+ void OnMouseLeave() { m_bMouseOverWindow = false; }
+
+ void SetMouseCursor( EMouseCursors eCursor );
+
+ bool SetGameProcessInfo( AppId_t nAppId, bool bCanSharedSurfaces, int32 eTextureFormat );
+ void ProcessInputEvents();
+
+ bool BVisiblityChanged() const { return m_bVisibleThisFrame != m_bVisibleLastFrame; }
+
+ void PushOverlayRenderCmdStream( CSharedMemStream *pRenderStream, unsigned long dwPID, float flOpacity, EOverlayWindowAlignment alignment );
+
+ void SetGameWindowSize( uint32 nWidth, uint32 nHeight );
+ void SetFixedSurfaceSize( uint32 unSurfaceWidth, uint32 unSurfaceHeight );
+
+ void OnMouseMove( float x, float y );
+
+ void SetFocus( bool bFocus );
+
+ void SetLetterboxColor( Color c );
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void Validate( CValidator &validator, const tchar *pchName );
+#endif
+protected:
+ virtual void Shutdown();
+
+private:
+
+ COverlayInterface *m_pOverlayInterface;
+ IUI3DSurface *m_p3DSurface;
+ bool m_bMouseOverWindow;
+ AppId_t m_nAppId;
+
+ bool m_bInputEnabled;
+ bool m_bFocus;
+ bool m_bCanShareSurfaces;
+
+ bool m_bVisibleThisFrame;
+ bool m_bVisibleLastFrame;
+
+ uint32 m_unGameWidth;
+ uint32 m_unGameHeight;
+
+ bool m_bFullScreen;
+
+ bool m_bVisible;
+};
+
+class COverlayInterface : public IUIOverlayWindow
+{
+public:
+ COverlayInterface( CTopLevelWindowOverlay *pWindow )
+ {
+ m_pWindow = pWindow;
+ }
+
+ virtual void PushOverlayRenderCmdStream( CSharedMemStream *pRenderStream, unsigned long dwPID, float flOpacity, EOverlayWindowAlignment alignment ) OVERRIDE
+ {
+ return m_pWindow->PushOverlayRenderCmdStream( pRenderStream, dwPID, flOpacity, alignment );
+ }
+
+ virtual void SetFocus( bool bFocus ) OVERRIDE
+ {
+ return m_pWindow->SetFocus( bFocus );
+ }
+
+ virtual bool SetGameProcessInfo( AppId_t nAppId, bool bCanSharedSurfaces, int32 eTextureFormat ) OVERRIDE
+ {
+ return m_pWindow->SetGameProcessInfo( nAppId, bCanSharedSurfaces, eTextureFormat );
+ }
+
+ virtual void SetInputEnabled( bool bEnabled ) OVERRIDE
+ {
+ return m_pWindow->SetInputEnabled( bEnabled );
+ }
+
+ virtual void SetGameWindowSize( uint32 nWidth, uint32 nHeight ) OVERRIDE
+ {
+ return m_pWindow->SetGameWindowSize( nWidth, nHeight );
+ }
+
+ virtual void SetFixedSurfaceSize( uint32 unSurfaceWidth, uint32 unSurfaceHeight ) OVERRIDE
+ {
+ return m_pWindow->SetFixedSurfaceSize( unSurfaceWidth, unSurfaceHeight );
+ }
+
+ virtual void OnMouseMove( float x, float y ) OVERRIDE
+ {
+ return m_pWindow->OnMouseMove( x, y );
+ }
+
+ virtual void OnMouseEnter() OVERRIDE
+ {
+ return m_pWindow->OnMouseEnter();
+ }
+
+ virtual void SetLetterboxColor( Color c ) OVERRIDE
+ {
+ return m_pWindow->SetLetterboxColor( c );
+ }
+private:
+ CTopLevelWindowOverlay *m_pWindow;
+};
+
+
+} // namespace panorama
+
+#endif // UITOPLEVELWINDOWOVERLAY_H
diff --git a/public/panorama/uiwebapiclient.h b/public/panorama/uiwebapiclient.h
new file mode 100644
index 0000000..d4afd89
--- /dev/null
+++ b/public/panorama/uiwebapiclient.h
@@ -0,0 +1,70 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose: Helper classes/functions for performing web api requests from ui code
+//
+//=============================================================================//
+
+#ifndef UIWEBAPICLIENT_H
+#define UIWEBAPICLIENT_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "uievent.h"
+
+
+namespace panorama
+{
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper for performing async webapi requests
+//-----------------------------------------------------------------------------
+inline uint64 MakeAsyncJSONWebAPIRequest( EHTTPMethod eMethod, const char *pchWebAPIURL, CJSONWebAPIParams *pParams, HTTPCookieContainerHandle hCookieContianer, IUIPanel *pCallbackTargetPanel, void *pContext )
+{
+ return UIEngine()->InitiateAsyncJSONWebAPIRequest( eMethod, pchWebAPIURL, pCallbackTargetPanel, pContext, pParams, hCookieContianer );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper for performing async webapi requests
+//-----------------------------------------------------------------------------
+inline uint64 MakeAsyncJSONWebAPIRequest( EHTTPMethod eMethod, const char *pchWebAPIURL, CJSONWebAPIParams *pParams, HTTPCookieContainerHandle hCookieContianer, JSONWebAPIDelegate_t callback, void *pContext )
+{
+ return UIEngine()->InitiateAsyncJSONWebAPIRequest( eMethod, pchWebAPIURL, callback, pContext, pParams, hCookieContianer );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper for performing async webapi requests
+//-----------------------------------------------------------------------------
+inline uint32 MakeAsyncJSONWebAPIRequest( const char *pchWebAPIURL, IUIPanel *pCallbackTargetPanel, void *pContext )
+{
+ return UIEngine()->InitiateAsyncJSONWebAPIRequest( k_EHTTPMethodGET, pchWebAPIURL, pCallbackTargetPanel, pContext );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Helper for performing async webapi requests. When using this version, objects pointed to
+// by the provided delegate must live for the duration of the web request. Before destroying those objects,
+// you must get a completion callback or CancelAsyncJSONWebAPIRequest.
+//
+// Use panel & event versions above if you do not want to manage object & request lifetimes.
+//-----------------------------------------------------------------------------
+inline uint32 MakeAsyncJSONWebAPIRequest( const char *pchWebAPIURL, JSONWebAPIDelegate_t callback, void *pContext )
+{
+ return UIEngine()->InitiateAsyncJSONWebAPIRequest( k_EHTTPMethodGET, pchWebAPIURL, callback, pContext );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Cancels a job request made by MakeAsyncJSONWebAPIRequest
+//-----------------------------------------------------------------------------
+inline void CancelAsyncJSONWebAPIRequest( uint32 requestID )
+{
+ UIEngine()->CancelAsyncJSONWebAPIRequest( requestID );
+}
+
+
+} // namespace panorama
+
+#endif // UIWEBAPICLIENT_H
diff --git a/public/panorama/vrevents.h b/public/panorama/vrevents.h
new file mode 100644
index 0000000..5fab8cf
--- /dev/null
+++ b/public/panorama/vrevents.h
@@ -0,0 +1,28 @@
+//=========== Copyright Valve Corporation, All rights reserved. ===============//
+//
+// Purpose:
+//=============================================================================//
+
+#ifndef VREVENTS_H
+#define VREVENTS_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "uievent.h"
+#include "uieventcodes.h"
+#include "layout/stylesymbol.h"
+#include "localization/ilocalize.h"
+
+
+namespace panorama
+{
+ // dashboard events
+ DECLARE_PANORAMA_EVENT2( VRDashboardRequested, vr::TrackedDeviceIndex_t, vr::VROverlayHandle_t );
+ DECLARE_PANORAMA_EVENT1( VRDashboardThumbSelected, vr::VROverlayHandle_t );
+ DECLARE_PANORAMA_EVENT0( VRResetDashboard );
+ DECLARE_PANORAMA_EVENT1( VRRenderToast, vr::VRNotificationId );
+}
+
+#endif // VREVENTS_H \ No newline at end of file