diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /public/panorama/controls | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'public/panorama/controls')
25 files changed, 4900 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 + + |