Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1109 lines
51 KiB

  1. //=========== Copyright Valve Corporation, All rights reserved. ===============//
  2. //
  3. // Purpose:
  4. //=============================================================================//
  5. #ifndef PANEL2D_H
  6. #define PANEL2D_H
  7. #ifdef _WIN32
  8. #pragma once
  9. #endif
  10. #include "../iuiengine.h"
  11. #include "../iuipanel.h"
  12. #include "../iuipanelclient.h"
  13. #include "../iuipanelstyle.h"
  14. #include "panorama/transformations.h"
  15. #include "panorama/input/keycodes.h"
  16. #include "panorama/layout/panel2dfactory.h"
  17. #include "panorama/layout/stylefiletypes.h"
  18. #include "panorama/input/mousecursors.h"
  19. #include "panorama/input/iuiinput.h"
  20. #include "panorama/uieventcodes.h"
  21. #include "panorama/uievent.h"
  22. #include "panorama/iuiwindow.h"
  23. #include "panorama/layout/panel2dfactory.h"
  24. #include "color.h"
  25. #include "utlvector.h"
  26. #include "utlstring.h"
  27. #include "panelptr.h"
  28. #include "steam/steamtypes.h"
  29. #if defined( SOURCE2_PANORAMA )
  30. #include "currencyamount.h"
  31. #else
  32. #include "rtime.h"
  33. #include "amount.h"
  34. #endif
  35. #include "tier1/utlmap.h"
  36. #include "panorama/layout/stylesymbol.h"
  37. namespace panorama
  38. {
  39. #pragma warning(push)
  40. // warning C4251: 'CPanel2D::symbol' : class 'CUtlSymbol' needs to have dll-interface to be used by clients of class 'CPanel2D'
  41. #pragma warning( disable : 4251 )
  42. class CLayoutFile;
  43. class CTopLevelWindow;
  44. class CVerticalScrollBar;
  45. class CHorizontalScrollBar;
  46. struct PanelDescription_t;
  47. class CUIRenderEngine;
  48. class CImageResourceManager;
  49. class CPanelStyle;
  50. class CBackgroundImageLayer;
  51. class CPanel2D;
  52. class CScrollBar;
  53. // Typedefs for getter/setter methods that can be exposed via JS
  54. typedef float(CPanel2D::*PanelFloatGetter_t)() const;
  55. typedef void(CPanel2D::*PanelFloatSetter_t)(float);
  56. typedef const char *(CPanel2D::*PanelStringGetter_t)() const;
  57. typedef void(CPanel2D::*PanelStringSetter_t)(const char *);
  58. typedef bool(CPanel2D::*PanelBoolGetter_t)() const;
  59. typedef void(CPanel2D::*PanelBoolSetter_t)(bool);
  60. typedef CPanoramaSymbol( CPanel2D::*PanelSymbolGetter_t )() const;
  61. typedef void(CPanel2D::*PanelSymbolSetter_t)(CPanoramaSymbol);
  62. inline CPanel2D * ToPanel2D( IUIPanel *pPanel )
  63. {
  64. if( pPanel )
  65. return (CPanel2D*)(pPanel->ClientPtr());
  66. return NULL;
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Purpose: Struct used to perform hit tests
  70. //-----------------------------------------------------------------------------
  71. struct TransformContext_t
  72. {
  73. float m_flPosX;
  74. float m_flPosY;
  75. float m_flPosZ;
  76. VMatrix m_TransformMatrix;
  77. float m_flWidth;
  78. float m_flHeight;
  79. float m_flPerspective;
  80. float m_flPerspectiveOriginX;
  81. float m_flPerspectiveOriginY;
  82. };
  83. //-----------------------------------------------------------------------------
  84. // Purpose: Basic 2D UI panel. These may be transformed in 3D space, but they are
  85. // at a base level 2D rectangular containers for other panels/paint operations.
  86. //-----------------------------------------------------------------------------
  87. class CPanel2D : public panorama::IUIPanelClient
  88. {
  89. DECLARE_PANEL2D_NO_BASE( CPanel2D );
  90. public:
  91. CPanel2D( IUIWindow *parent, const char * pchID );
  92. CPanel2D( CPanel2D *parent, const char * pchID );
  93. CPanel2D( CPanel2D *parent, const char *pchID, uint32 ePanelFlags );
  94. virtual ~CPanel2D();
  95. // Check if the panel has loaded layout
  96. bool IsLoaded() const { return m_pIUIPanel->IsLoaded(); }
  97. virtual void OnDeletePanel() OVERRIDE { delete this; }
  98. // Access the panorama side UI panel interface for the client panel
  99. virtual IUIPanel *UIPanel() const { return m_pIUIPanel; }
  100. void DeleteAsync( float flDelay = 0.0f );
  101. // Set the panel visible
  102. void SetVisible( bool bVisible ) { m_pIUIPanel->SetVisible( bVisible ); }
  103. bool BIsVisible() const { return m_pIUIPanel->BIsVisible(); }
  104. // Get the base position for the panel
  105. void GetPosition( CUILength &x, CUILength &y, CUILength &z, bool bIncludeUIScaleFactor = true );
  106. // Set the base position for the panel
  107. void SetPosition( CUILength x, CUILength y, CUILength z, bool bPreScaledByUIScaleFactor = false );
  108. void SetPositionWithoutTransition( CUILength x, CUILength y, CUILength z, bool bPreScaledByUIScaleFactor = false );
  109. void SetTransform3D( const CUtlVector<CTransform3D *> &vecTransforms );
  110. void SetOpacity( float flOpacity );
  111. bool BIsTransparent() { return m_pIUIPanel->BIsTransparent(); }
  112. void SetPreTransformScale2D( float flX, float flY );
  113. // Set the base width/height for the panel
  114. CUILength GetStyleWidth();
  115. CUILength GetStyleHeight();
  116. void SetSize( CUILength width, CUILength height );
  117. // The the bounds that should be used for placing a tooltip, returning false means "use the entire panel"
  118. virtual bool GetContextUIBounds( float *pflX, float *pflY, float *pflWidth, float *pflHeight ) { return false; }
  119. // Set the animation style for the panel
  120. void SetAnimation( const char *pchAnimationName, float flDuration, float flDelay, EAnimationTimingFunction eTimingFunc, EAnimationDirection eDirection, float flIterations ) { m_pIUIPanel->SetAnimation( pchAnimationName, flDuration, flDelay, eTimingFunc, eDirection, flIterations ); }
  121. // Returns the layout file for this panel
  122. CPanoramaSymbol GetLayoutFile() const { return m_pIUIPanel->GetLayoutFile(); }
  123. // Returns define from layout file for this panel
  124. char const * GetLayoutFileDefine( char const *szDefineName );
  125. int GetLayoutFileDefineInt( const char *szDefineName, int defaultValue );
  126. float GetLayoutFileDefineFloat( const char *szDefineName, float defaultValue );
  127. // Style access
  128. panorama::IUIPanelStyle *AccessStyle() const { return m_pIUIPanel->AccessIUIStyle(); }
  129. // Style access
  130. panorama::IUIPanelStyle *AccessStyleDirty() const { return m_pIUIPanel->AccessIUIStyleDirty(); }
  131. void ApplyStyles( bool bTraverse ) { return m_pIUIPanel->ApplyStyles( bTraverse ); }
  132. // Mark styles dirty for the panel
  133. void MarkStylesDirty( bool bIncludeChildren ) { m_pIUIPanel->MarkStylesDirty( bIncludeChildren ); }
  134. void ClearPropertyFromCode( panorama::CStyleSymbol symProperty );
  135. // Virtual called on scale factor for panel changing
  136. virtual void OnUIScaleFactorChanged( float flScaleFactor ) OVERRIDE { }
  137. // Paint the panel and it's children, called by the rendering layer when it's time to paint.
  138. void PaintTraverse() { m_pIUIPanel->PaintTraverse(); }
  139. // Paint the panels contents
  140. virtual void Paint() OVERRIDE;
  141. // Invalidates painting and tells the panel it must repaint next frame
  142. void SetRepaint( EPanelRepaint eRepaintNeeded );
  143. // sets & loads the layout file for this panel
  144. bool BLoadLayout( const char *pchFile, bool bOverrideExisting = false, bool bPartialLayout = false ) { return m_pIUIPanel->BLoadLayout( pchFile, bOverrideExisting, bPartialLayout ); }
  145. // sets & loads the layout for this panel
  146. bool BLoadLayoutFromString( const char *pchXMLString, bool bOverrideExisting = false, bool bPartialLayout = false ) { return m_pIUIPanel->BLoadLayoutFromString( pchXMLString, bOverrideExisting, bPartialLayout ); }
  147. // sets loads the layout file for this panel, asynchronously supporting remote http:// paths
  148. void LoadLayoutAsync( const char *pchFile, bool bOverrideExisting = false, bool bPartialLayout = false ) { return m_pIUIPanel->LoadLayoutAsync( pchFile, bOverrideExisting, bPartialLayout ); }
  149. // loads the layout file for this panel, asynchronously supporting remote http:// paths in css within
  150. void LoadLayoutFromStringAsync( const char *pchXMLString, bool bOverrideExisting, bool bPartialLayout = false ) { return m_pIUIPanel->LoadLayoutFromStringAsync( pchXMLString, bOverrideExisting, bPartialLayout ); }
  151. // Measure self and children. First pass of layout
  152. void DesiredLayoutSizeTraverse( float flMaxWidth, float flMaxHeight ) { m_pIUIPanel->DesiredLayoutSizeTraverse( flMaxWidth, flMaxHeight ); }
  153. void DesiredLayoutSizeTraverse( float *pflDesiredWidth, float *pflDesiredHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions ) { m_pIUIPanel->DesiredLayoutSizeTraverse( pflDesiredWidth, pflDesiredHeight, flMaxWidth, flMaxHeight, bFinalDimensions ); }
  154. // Arrange children. Second pass of layout
  155. void LayoutTraverse( float x, float y, float flFinalWidth, float flFinalHeight ) { m_pIUIPanel->LayoutTraverse( x, y, flFinalWidth, flFinalHeight ); }
  156. // methods to invalid certain parts of layout
  157. void InvalidateSizeAndPosition() { m_pIUIPanel->InvalidateSizeAndPosition(); }
  158. void InvalidatePosition() { m_pIUIPanel->InvalidatePosition(); }
  159. bool IsSizeValid() { return m_pIUIPanel->IsSizeValid(); }
  160. bool IsPositionValid() { return m_pIUIPanel->IsPositionValid(); }
  161. bool IsChildSizeValid() { return m_pIUIPanel->IsChildSizeValid(); }
  162. bool IsChildPositionValid() { return m_pIUIPanel->IsChildPositionValid(); }
  163. bool IsSizeTransitioning() { return m_pIUIPanel->IsSizeTransitioning(); }
  164. bool IsPositionTransitioning() { return m_pIUIPanel->IsPositionTransitioning(); }
  165. bool IsChildPositionTransitioning() { return m_pIUIPanel->IsChildPositionTransitioning(); }
  166. bool IsChildSizeTransitioning() { return m_pIUIPanel->IsChildSizeTransitioning(); }
  167. // size getters
  168. float GetDesiredLayoutWidth() const { return m_pIUIPanel->GetDesiredLayoutWidth(); }
  169. float GetDesiredLayoutHeight() const { return m_pIUIPanel->GetDesiredLayoutHeight(); }
  170. // Content size is what our contents actually take up, not accounting for fixed/relative
  171. // size set on us in styles which affect desired layout size
  172. float GetContentWidth() const { return m_pIUIPanel->GetContentWidth(); }
  173. float GetContentHeight() const { return m_pIUIPanel->GetContentHeight(); }
  174. // Actual size is the size given to the panel after layout, hopefully as big as its desired size.
  175. // Actual size does NOT include margins (which are really in the parent).
  176. float GetActualLayoutWidth() const { return m_pIUIPanel->GetActualLayoutWidth(); }
  177. float GetActualLayoutHeight() const { return m_pIUIPanel->GetActualLayoutHeight(); }
  178. // Render size is the size of the content for rendering, this is either the actual layout size, or if
  179. // that is smaller than the content size + padding then it's the content size + padding.
  180. float GetActualRenderWidth() { return m_pIUIPanel->GetActualRenderWidth(); }
  181. float GetActualRenderHeight() { return m_pIUIPanel->GetActualRenderHeight(); }
  182. // Offset will include position, alignment, and margin adjustments
  183. float GetActualXOffset() const { return m_pIUIPanel->GetActualXOffset(); }
  184. float GetActualYOffset() const { return m_pIUIPanel->GetActualYOffset(); }
  185. // Offset to apply to contents for scrolling
  186. float GetContentsYScrollOffset() const { return m_pIUIPanel->GetContentsYScrollOffset(); }
  187. float GetContentsXScrollOffset() const { return m_pIUIPanel->GetContentsXScrollOffset(); }
  188. float GetContentsYScrollOffsetTarget() const { return m_pIUIPanel->GetContentsYScrollOffsetTarget(); }
  189. float GetContentsXScrollOffsetTarget() const { return m_pIUIPanel->GetContentsXScrollOffsetTarget(); }
  190. double GetContentsXScrollTransitionStart() const { return m_pIUIPanel->GetContentsXScrollTransitionStart(); }
  191. double GetContentsYScrollTransitionStart() const { return m_pIUIPanel->GetContentsYScrollTransitionStart(); }
  192. float GetInterpolatedXScrollOffset() { return m_pIUIPanel->GetInterpolatedXScrollOffset(); }
  193. float GetInterpolatedYScrollOffset() { return m_pIUIPanel->GetInterpolatedYScrollOffset(); }
  194. // Can the panel scroll further?
  195. bool BCanScrollUp() { return m_pIUIPanel->BCanScrollUp(); }
  196. bool BCanScrollDown() { return m_pIUIPanel->BCanScrollDown(); }
  197. bool BCanScrollLeft() { return m_pIUIPanel->BCanScrollLeft(); }
  198. bool BCanScrollRight() { return m_pIUIPanel->BCanScrollRight(); }
  199. // style class management
  200. void AddClass( const char *pchName ) { m_pIUIPanel->AddClass( pchName ); }
  201. void AddClass( CPanoramaSymbol symbol ) { m_pIUIPanel->AddClass( symbol ); }
  202. void AddClasses( const char *pchName ) { m_pIUIPanel->AddClasses( pchName ); }
  203. void AddClasses( CPanoramaSymbol *pSymbols, uint cSymbols ) { m_pIUIPanel->AddClasses( pSymbols, cSymbols ); }
  204. void RemoveClass( const char *pchName ) { m_pIUIPanel->RemoveClass( pchName ); }
  205. void RemoveClass( CPanoramaSymbol symName ) { m_pIUIPanel->RemoveClass( symName ); }
  206. void RemoveClasses( const CPanoramaSymbol *pSymbols, uint cSymbols ) { m_pIUIPanel->RemoveClasses( pSymbols, cSymbols ); }
  207. void RemoveClasses( const char *pchName ) { m_pIUIPanel->RemoveClasses( pchName ); }
  208. void RemoveAllClasses() { m_pIUIPanel->RemoveAllClasses(); }
  209. // bugbug jmccaskey - dangerous cross dll interface signature? Is CUtlVector the same in debug/release?
  210. const CUtlVector< CPanoramaSymbol > &GetClasses() const { return m_pIUIPanel->GetClasses(); }
  211. bool BHasClass( const char *pchName ) const { return m_pIUIPanel->BHasClass( pchName ); }
  212. bool BHasClass( CPanoramaSymbol symName ) const { return m_pIUIPanel->BHasClass( symName ); }
  213. bool BAscendantHasClass( const char *pchName ) const { return m_pIUIPanel->BAscendantHasClass( pchName ); }
  214. bool BAscendantHasClass( CPanoramaSymbol symName ) const { return m_pIUIPanel->BAscendantHasClass( symName ); }
  215. void ToggleClass( const char *pchName ) { m_pIUIPanel->ToggleClass( pchName ); }
  216. void ToggleClass( CPanoramaSymbol symName ) { m_pIUIPanel->ToggleClass( symName ); }
  217. void SetHasClass( const char *pchName, bool bHasClass ) { m_pIUIPanel->SetHasClass( pchName, bHasClass ); }
  218. void SetHasClass( CPanoramaSymbol symName, bool bHasClass ) { m_pIUIPanel->SetHasClass( symName, bHasClass ); }
  219. void SwitchClass( const char *pchAttribute, const char *pchName ) { m_pIUIPanel->SwitchClass( pchAttribute, pchName ); }
  220. void SwitchClass( const char *pchAttribute, CPanoramaSymbol symName ) { m_pIUIPanel->SwitchClass( pchAttribute, symName ); }
  221. const char *GetID() const { return m_pIUIPanel->GetID(); }
  222. bool BHasID() const { return m_pIUIPanel->GetID()[0] != '0'; }
  223. void SetTabIndex( float flTabIndex ) { m_pIUIPanel->SetTabIndex( flTabIndex ); }
  224. void SetSelectionPosition( float flXPos, float flYPos ) { m_pIUIPanel->SetSelectionPosition( flXPos, flYPos ); }
  225. void SetSelectionPositionX( float flXPos ) { m_pIUIPanel->SetSelectionPositionX( flXPos ); }
  226. void SetSelectionPositionY( float flYPos ) { m_pIUIPanel->SetSelectionPositionY( flYPos ); }
  227. float GetSelectionPositionX() const { return m_pIUIPanel->GetSelectionPositionX(); }
  228. float GetSelectionPositionY() const { return m_pIUIPanel->GetSelectionPositionY(); }
  229. float GetTabIndex() const { return m_pIUIPanel->GetTabIndex(); }
  230. //
  231. // Implementation of functions that panorama calls back on UI control classes
  232. //
  233. // kb/mouse management
  234. virtual bool OnKeyDown( const KeyData_t &code ) OVERRIDE;
  235. virtual bool OnKeyUp( const KeyData_t & code ) OVERRIDE;
  236. virtual bool OnKeyTyped( const KeyData_t &unichar ) OVERRIDE;
  237. virtual bool OnGamePadDown( const GamePadData_t &code ) OVERRIDE;
  238. virtual bool OnGamePadUp( const GamePadData_t &code ) OVERRIDE;
  239. virtual bool OnGamePadAnalog( const GamePadData_t &code ) OVERRIDE;
  240. virtual bool OnMouseButtonDown( const MouseData_t &code ) OVERRIDE;
  241. virtual bool OnMouseButtonUp( const MouseData_t &code ) OVERRIDE;
  242. virtual bool OnMouseButtonDoubleClick( const MouseData_t &code ) OVERRIDE;
  243. virtual bool OnMouseButtonTripleClick( const MouseData_t &code ) OVERRIDE;
  244. virtual bool OnMouseWheel( const MouseData_t &code ) OVERRIDE;
  245. virtual void OnMouseMove( float flMouseX, float flMouseY ) OVERRIDE;
  246. virtual bool OnClick( IUIPanel *pPanel, const MouseData_t &code ) OVERRIDE;
  247. // events
  248. bool OnScrollDirection( IUIScrollBar *pScrollBar, bool bIncreasePosition, float flDelta );
  249. bool OnScrollUp();
  250. bool OnScrollDown();
  251. bool OnScrollLeft();
  252. bool OnScrollRight();
  253. bool OnPageDirection( IUIScrollBar *pScrollBar, bool bIncreasePosition );
  254. bool OnPageUp();
  255. bool OnPageDown();
  256. bool OnPageLeft();
  257. bool OnPageRight();
  258. // Scrolling
  259. void ScrollVertically( float flScrollDelta, bool bImmediateMove = false );
  260. void ScrollHorizontally( float flScrollDelta, bool bImmediateMove = false );
  261. void ScrollToShowVerticalRange( float flRangeStart, float flRangeEnd );
  262. virtual void ScrollToXPercent( float flXPercent );
  263. virtual void ScrollToYPercent( float flXPercent );
  264. // navigation events, override these in children if you want special navigation handling,
  265. // shouldn't be needed often though, use tabindex/selectionpos in xml layout files!
  266. virtual bool OnMoveUp( int nRepeats );
  267. virtual bool OnMoveDown( int nRepeats );
  268. virtual bool OnMoveLeft( int nRepeats );
  269. virtual bool OnMoveRight( int nRepeats );
  270. virtual bool OnTabForward( int nRepeats );
  271. virtual bool OnTabBackward( int nRepeats );
  272. // child iteration
  273. int GetChildCount() const { return m_pIUIPanel->GetChildCount(); }
  274. CPanel2D *GetChild( int i ) const { return ToPanel2D( m_pIUIPanel->GetChild( i ) ); }
  275. CPanel2D *GetFirstChild() const { return ToPanel2D( m_pIUIPanel->GetFirstChild() ); }
  276. CPanel2D *GetLastChild() const { return ToPanel2D( m_pIUIPanel->GetLastChild() ); }
  277. // Return index of child in creation/panel vector order (also default tab order)
  278. int GetChildIndex( const CPanel2D *pChild ) const { if( !pChild ) return -1; else return m_pIUIPanel->GetChildIndex( pChild->UIPanel() ); }
  279. int GetHiddenChildCount() const { return m_pIUIPanel->GetHiddenChildCount(); }
  280. CPanel2D *GetHiddenChild( int i ) const { return ToPanel2D( m_pIUIPanel->GetHiddenChild( i ) ); }
  281. // Gets immediate ancestor of this panel in panel hierarchy
  282. CPanel2D *GetParent() const { return ToPanel2D( m_pIUIPanel->GetParent() ); }
  283. // searches only immediate children
  284. CPanel2D *FindChild( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindChild( pchID ) ); }
  285. // searches all children even outside layout file scope
  286. CPanel2D *FindChildTraverse( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindChildTraverse( pchID ) ); }
  287. // searches any children created from our layout file
  288. CPanel2D *FindChildInLayoutFile( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindChildInLayoutFile( pchID ) ); }
  289. // searches any panel created from our layout file (so parents or children!)
  290. CPanel2D *FindPanelInLayoutFile( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindPanelInLayoutFile( pchID ) ); }
  291. void MoveChildAfter( CPanel2D *pChildToMove, CPanel2D *pBefore ) { return m_pIUIPanel->MoveChildAfter( pChildToMove->UIPanel(), pBefore->UIPanel() ); }
  292. void MoveChildBefore( CPanel2D *pChildToMove, CPanel2D *pAfter ) { return m_pIUIPanel->MoveChildBefore( pChildToMove->UIPanel(), pAfter->UIPanel() ); }
  293. // window management
  294. IUIWindow *GetParentWindow() const { return m_pIUIPanel->GetParentWindow(); }
  295. // input & focus
  296. bool BAcceptsInput() { return m_pIUIPanel->BAcceptsInput(); }
  297. void SetAcceptsInput( bool bAllowInput ) { m_pIUIPanel->SetAcceptsInput( bAllowInput ); }
  298. bool BAcceptsFocus() const { return m_pIUIPanel->BAcceptsFocus(); }
  299. void SetAcceptsFocus( bool bAllowFocus ) { m_pIUIPanel->SetAcceptsFocus( bAllowFocus ); }
  300. bool BCanAcceptInput() { return m_pIUIPanel->BCanAcceptInput(); }
  301. void SetDefaultFocus( const char *pchChildID ) { m_pIUIPanel->SetDefaultFocus( pchChildID ); }
  302. const char *GetDefaultFocus() const { return m_pIUIPanel->GetDefaultFocus(); }
  303. void SetDisableFocusOnMouseDown( bool bDisable ) { m_pIUIPanel->SetDisableFocusOnMouseDown( bDisable ); }
  304. bool BFocusOnMouseDown() { return m_pIUIPanel->BFocusOnMouseDown(); }
  305. virtual bool BRequiresFocus() { return false; } // Override if your control requires taking focus in order to operate (e.g. TextEntry)
  306. // 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
  307. // other hierarchy changes focus? Use this for panels that are peers like friends vs browser vs mainmenu in tenfoot
  308. bool BTopOfInputContext() { return m_pIUIPanel->BTopOfInputContext(); }
  309. void SetTopOfInputContext( bool bIsTopOfInputContext ) { return m_pIUIPanel->SetTopOfInputContext( bIsTopOfInputContext ); }
  310. CPanel2D *GetParentInputContext() { return ToPanel2D( m_pIUIPanel->GetParentInputContext() ); }
  311. // Get the default input focus child within this panel, may be null
  312. CPanel2D *GetDefaultInputFocus() { return ToPanel2D( m_pIUIPanel->GetDefaultInputFocus() ); }
  313. // Override behavior for getting default input focus, callback from framework
  314. virtual IUIPanel *OnGetDefaultInputFocus() OVERRIDE { return NULL; }
  315. // Set focus to this panel, which will auto-scroll it into full view as well if parent has overflow: scroll
  316. bool SetFocus() { return m_pIUIPanel->SetFocus(); }
  317. // Set the focus to this panel in it's input context, but do not make the context change if some other context currently
  318. // has focus
  319. bool UpdateFocusInContext() { return m_pIUIPanel->UpdateFocusInContext(); }
  320. // Set the focus in response to receiving hover (on panels that a parent sets childfocusonhover), this will
  321. // never scroll the parent.
  322. bool SetFocusDueToHover() { return m_pIUIPanel->SetFocusDueToHover(); }
  323. void SetInputContextFocus() { m_pIUIPanel->SetInputContextFocus(); }
  324. // retrieve the style flags (map to CSS psuedo-classes) for this panel
  325. uint GetStyleFlags() const { return m_pIUIPanel->GetStyleFlags(); }
  326. void AddStyleFlag( EStyleFlags eStyleFlag ) { m_pIUIPanel->AddStyleFlag( eStyleFlag ); }
  327. void RemoveStyleFlag( EStyleFlags eStyleFlag ) { m_pIUIPanel->RemoveStyleFlag( eStyleFlag ); }
  328. bool IsInspected() const { return m_pIUIPanel->IsInspected(); }
  329. bool BHasHoverStyle() const { return m_pIUIPanel->BHasHoverStyle(); }
  330. void SetSelected( bool bSelected ) { m_pIUIPanel->SetSelected( bSelected ); }
  331. bool IsSelected() const { return m_pIUIPanel->IsSelected(); }
  332. bool BHasKeyFocus() const { return m_pIUIPanel->BHasKeyFocus(); }
  333. bool BHasDescendantKeyFocus() const { return m_pIUIPanel->BHasDescendantKeyFocus(); }
  334. bool IsLayoutLoading() const { return m_pIUIPanel->IsLayoutLoading(); }
  335. // enable/disable
  336. void SetEnabled( bool bEnabled ) { m_pIUIPanel->SetEnabled( bEnabled ); }
  337. bool IsEnabled() const { return m_pIUIPanel->IsEnabled(); }
  338. bool IsActivationEnabled() { return m_pIUIPanel->IsActivationEnabled(); }
  339. // Set activation disabled on this panel, input/focus still generally work, but Activate events won't be handled, useful to prevent a button
  340. // being clicked when out of focus, but leave it able to be focused for later activation or such
  341. void SetActivationEnabled( bool bEnabled ) { m_pIUIPanel->SetActivationEnabled( bEnabled ); }
  342. // Set all our immediate children enabled/disabled
  343. void SetAllChildrenActivationEnabled( bool bEnabled ) { m_pIUIPanel->SetAllChildrenActivationEnabled( bEnabled ); }
  344. // Enable/disable hit testing of this panel, you may want a parent that is never hit test that has a large region, but clicks
  345. // just pass through to other things behind it. Children may still hit test.
  346. void SetHitTestEnabled( bool bEnabled ) { m_pIUIPanel->SetHitTestEnabled( bEnabled ); }
  347. bool BHitTestEnabled() const { return m_pIUIPanel->BHitTestEnabled(); }
  348. void SetHitTestEnabledTraverse( bool bEnabled ) { m_pIUIPanel->SetHitTestEnabledTraverse( bEnabled ); }
  349. void SetOnActivateEvent( IUIEvent *pEvent );
  350. void SetOnActivateEvent( const char *pchEventString );
  351. void SetOnFocusEvent( IUIEvent *pEvent );
  352. void SetOnCancelEvent( IUIEvent *pEvent );
  353. void SetOnContextMenuEvent( IUIEvent *pEvent );
  354. void SetOnLoadEvent( IUIEvent *pEvent );
  355. void SetOnMouseActivateEvent( IUIEvent *pEvent );
  356. void SetOnMouseOverEvent( IUIEvent *pEvent );
  357. void SetOnMouseOutEvent( IUIEvent *pEvent );
  358. void SetOnDblClickEvent( IUIEvent *pEvent );
  359. void SetOnTabForwardEvent( IUIEvent *pEvent );
  360. void SetOnTabBackwardEvent( IUIEvent *pEvent );
  361. // bugbug jmccaskey - DELETE ME
  362. // bugbug jmccaskey - both of the next two functions need to be deleted, we should
  363. // not expose panel event internals like this, but parental button needs some refactoring
  364. // first. That refactoring must happen to work at all with javascript panel events anyway.
  365. VecUIEvents_t * GetPanelEvents( CPanoramaSymbol symEvent ) { return m_pIUIPanel->GetPanelEvents( symEvent ); }
  366. virtual void OnPanelEventSet( CPanoramaSymbol symEvent ) OVERRIDE { }
  367. bool BHasOnActivateEvent() { return m_pIUIPanel->BHasOnActivateEvent(); }
  368. bool BHasOnMouseActivateEvent() { return m_pIUIPanel->BHasOnMouseActivateEvent(); }
  369. void ClearOnActivateEvent();
  370. // Dialog variables
  371. void SetDialogVariable( const char *pchKey, const char *pchValue );
  372. void SetDialogVariable( const char *pchKey, int iVal );
  373. // We do NOT have a uint32 type here by design, to prevent you accidenatlly using a RTime32
  374. // and getting a number value. Either cast to int for a number or construct a CRTime
  375. #if defined (SOURCE2_PANORAMA )
  376. void SetDialogVariable( const char *pchKey, time_t timeVal );
  377. void SetDialogVariable( const char *pchKey, CCurrencyAmount amount );
  378. #else
  379. void SetDialogVariable( const char *pchKey, CAmount amount );
  380. void SetDialogVariable( const char *pchKey, CRTime timeVal );
  381. #endif
  382. void SetDialogVariable( const char *varName, const CUtlString &value );
  383. void SetDialogVariableLocString( const char *varName, const char *pchValue );
  384. // Scrolling controls
  385. void ScrollToTop() { m_pIUIPanel->ScrollToTop(); }
  386. void ScrollToBottom() { m_pIUIPanel->ScrollToBottom(); }
  387. void ScrollToLeftEdge() { m_pIUIPanel->ScrollToLeftEdge(); }
  388. void ScrollToRightEdge() { m_pIUIPanel->ScrollToRightEdge(); }
  389. void ScrollParentToMakePanelFit( ScrollBehavior_t behavior = SCROLL_BEHAVIOR_DEFAULT, bool bImmediateScroll = false ) { m_pIUIPanel->ScrollParentToMakePanelFit( behavior, bImmediateScroll ); }
  390. 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 ); }
  391. bool BCanSeeInParentScroll() { return m_pIUIPanel->BCanSeeInParentScroll(); }
  392. void OnScrollPositionChanged() { m_pIUIPanel->OnScrollPositionChanged(); }
  393. 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
  394. void FireScrolledIntoViewEvent() { m_pIUIPanel->FireScrolledIntoViewEvent(); }
  395. void FireScrolledOutOfViewEvent() { m_pIUIPanel->FireScrolledOutOfViewEvent(); }
  396. bool IsScrolledIntoView() const { return m_pIUIPanel->IsScrolledIntoView(); }
  397. bool BSelectionPosVerticalBoundary() { return m_pIUIPanel->BSelectionPosVerticalBoundary(); }
  398. bool BSelectionPosHorizontalBoundary() { return m_pIUIPanel->BSelectionPosHorizontalBoundary(); }
  399. // Tell panel to set focus to next panel in specified movement direction/type
  400. 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 ); }
  401. virtual bool OnSetFocusToNextPanel( int nRepeats, EFocusMoveDirection moveType, bool bAllowWrap, float flTabIndexCurrent, float flXPosCurrent, float flYPosCurrent, float flXStart, float flYStart ) OVERRIDE{ return false; }
  402. bool SetInputFocusToFirstOrLastChildInFocusOrder( EFocusMoveDirection moveType, float flXStart, float flYStart ) { return m_pIUIPanel->SetInputFocusToFirstOrLastChildInFocusOrder( moveType, flXStart, flYStart ); }
  403. // hierarchy
  404. void SetParent( CPanel2D *pParent ) { m_pIUIPanel->SetParent( pParent ? pParent->UIPanel() : NULL ); }
  405. void RemoveAndDeleteChildren() { m_pIUIPanel->RemoveAndDeleteChildren(); }
  406. void RemoveAndDeleteChildrenOfType( CPanoramaSymbol symPanelType ) { m_pIUIPanel->RemoveAndDeleteChildrenOfType( symPanelType ); }
  407. uint32 GetChildCountOfType( CPanoramaSymbol symPanelType ) { return m_pIUIPanel->GetChildCountOfType( symPanelType ); }
  408. bool IsDescendantOf( const CPanel2D *pPanel ) const { return m_pIUIPanel->IsDescendantOf( pPanel ? pPanel->m_pIUIPanel : NULL ); }
  409. CPanel2D *FindAncestor( const char *pchID ) { return ToPanel2D( m_pIUIPanel->FindAncestor( pchID ) ); }
  410. // layout file
  411. CPanoramaSymbol GetLayoutFileLoadedFrom() const { return m_pIUIPanel->GetLayoutFileLoadedFrom(); }
  412. // Override this and return true if you know your panel will never draw outside it's bounds,
  413. // thus allowing an optimization to skip pushing clipping layers.
  414. virtual bool BRequiresContentClipLayer() OVERRIDE { return false; }
  415. // debug
  416. virtual void GetDebugPropertyInfo( CUtlVector< DebugPropertyOutput_t *> *pvecProperties );
  417. void SetTooltip( CPanel2D *pPanel );
  418. // Panel events
  419. bool DispatchPanelEvent( CPanoramaSymbol symPanelEvent ) { return m_pIUIPanel->DispatchPanelEvent( symPanelEvent ); }
  420. bool BParsePanelEvent( CPanoramaSymbol symPanelEvent, const char *pchValue ) { return m_pIUIPanel->BParsePanelEvent( symPanelEvent, pchValue ); }
  421. bool BIsPanelEventSet( CPanoramaSymbol symPanelEvent ) { return m_pIUIPanel->BIsPanelEventSet( symPanelEvent ); }
  422. bool BIsPanelEvent( CPanoramaSymbol symProperty ) { return m_pIUIPanel->BIsPanelEvent( symProperty ); }
  423. // the input namespace to use for this panel
  424. const char *GetInputNamespace() const { return m_pIUIPanel->GetInputNamespace(); }
  425. // the mouse cursor to display when hovered
  426. virtual EMouseCursors GetMouseCursor() OVERRIDE { return eMouseCursor_Arrow; }
  427. // controls if clicking on an unfocused panel should set focus
  428. void SetMouseCanActivate( EMouseCanActivate eMouseCanActivate, const char *pchOptionalParent = NULL ) { m_pIUIPanel->SetMouseCanActivate( eMouseCanActivate, pchOptionalParent ); }
  429. EMouseCanActivate GetMouseCanActivate() { return m_pIUIPanel->GetMouseCanActivate(); }
  430. CPanel2D *FindParentForMouseCanActivate() { return ToPanel2D( m_pIUIPanel->FindParentForMouseCanActivate() ); }
  431. // controls if clicking on an unfocused panel should set focus
  432. void SetChildFocusOnHover( bool bEnable ) { m_pIUIPanel->SetChildFocusOnHover( bEnable ); }
  433. bool GetChildFocusOnHover() { return m_pIUIPanel->GetChildFocusOnHover(); }
  434. // Set background images for the panel
  435. void SetBackgroundImages( const CUtlVector< CBackgroundImageLayer * > &vecLayers );
  436. CUtlVector< CBackgroundImageLayer * > *GetBackgroundImages();
  437. // called once after registering with UIEngine::CallBeforeStyleAndLayout()
  438. virtual void OnCallBeforeStyleAndLayout() OVERRIDE {}
  439. // clone
  440. virtual bool IsClonable();
  441. virtual CPanel2D *Clone();
  442. // sort children
  443. void SortChildren( int( __cdecl *pfnCompare )(const ClientPanelPtr_t *, const ClientPanelPtr_t *) ) { m_pIUIPanel->SortChildren( pfnCompare ); }
  444. // set the namespace to use for input
  445. void SetInputNamespace( const char *pchNamespace ) { m_pIUIPanel->SetInputNamespace( pchNamespace ); }
  446. // override this if you need to have the loc system consider an alternate panel hierarchy for resolving dialog variables
  447. virtual IUIPanel *GetLocalizationParent() const OVERRIDE { return GetParent() ? GetParent()->m_pIUIPanel : NULL; }
  448. // child management, use with caution! normally always managed internally.
  449. void AddChild( CPanel2D *pChild ) { m_pIUIPanel->AddChild( pChild->UIPanel() ); }
  450. // child management, use with caution! normally always managed internally. Returns child index we inserted at.
  451. int AddChildSorted( bool( __cdecl *pfnLessFunc )(ClientPanelPtr_t const &p1, ClientPanelPtr_t const &p2), CPanel2D *pChild ) { return m_pIUIPanel->AddChildSorted( pfnLessFunc, pChild->UIPanel() ); }
  452. // child management, use with caution! normally always managed internally.
  453. void RemoveChild( CPanel2D *pChild ) { m_pIUIPanel->RemoveChild( pChild->UIPanel() ); }
  454. // Check if styles are dirty for the panel
  455. bool BStylesDirty() const { return m_pIUIPanel->BStylesDirty(); }
  456. // Check if styles are possibly dirty for any of our children
  457. bool BChildStylesDirty() { return m_pIUIPanel->BChildStylesDirty(); }
  458. // Set that we need an on styles changed call when styles become non-dirty, even if there is no actual change.
  459. void SetOnStylesChangedNeeded() { m_pIUIPanel->SetOnStylesChangedNeeded(); }
  460. // Getter for panel attributes
  461. int GetAttribute( const char *pchAttrName, int nDefaultValue ) { return m_pIUIPanel->GetAttribute( pchAttrName, nDefaultValue ); }
  462. // Getter for panel attributes
  463. const char *GetAttribute( const char *pchAttrName, const char * pchDefaultValue ) { return m_pIUIPanel->GetAttribute( pchAttrName, pchDefaultValue ); }
  464. // Getter for panel attributes
  465. uint32 GetAttribute( const char *pchAttrName, uint32 unDefaultValue ) { return m_pIUIPanel->GetAttribute( pchAttrName, unDefaultValue ); }
  466. // Getter for panel attributes
  467. uint64 GetAttribute( const char *pchAttrName, uint64 unDefaultValue ) { return m_pIUIPanel->GetAttribute( pchAttrName, unDefaultValue ); }
  468. // Setter for panel attributes
  469. void SetAttribute( const char *pchAttrName, int nValue ) { m_pIUIPanel->SetAttribute( pchAttrName, nValue ); }
  470. // Setter for panel attributes
  471. void SetAttribute( const char *pchAttrName, const char * pchValue ) { m_pIUIPanel->SetAttribute( pchAttrName, pchValue ); }
  472. // Setter for panel attributes
  473. void SetAttribute( const char *pchAttrName, uint32 unValue ) { m_pIUIPanel->SetAttribute( pchAttrName, unValue ); }
  474. // Setter for panel attributes
  475. void SetAttribute( const char *pchAttrName, uint64 unValue ) { m_pIUIPanel->SetAttribute( pchAttrName, unValue ); }
  476. // walks parents calculating the top left corner relative to window space
  477. void GetPositionWithinWindow( float *pflX, float *pflY );
  478. // walks parents calculating the top left corner relative to the ancestor's space. If
  479. // the passed in panel is NULL or not an ancestor, this will end up being relative to the window space
  480. virtual void GetPositionWithinAncestor( CPanel2D *pAncestor, float *pflX, float *pflY ) OVERRIDE;
  481. bool BHasAnyActiveTransitions();
  482. // Get the nearest parent that establishes a javascript context, or return ourself if we ourselves create one
  483. panorama::CPanel2D *GetJavaScriptContextParent() const { return (CPanel2D*)(m_pIUIPanel->GetJavaScriptContextParent()->ClientPtr()); }
  484. // Called to ask us to setup object template for Javascript, you can implement this in a child class and then call
  485. // the base method (so all the normal panel2d stuff gets exposed), plus call the various RegisterJS helpers yourself
  486. // to expose additional panel type specific data/methods.
  487. virtual void SetupJavascriptObjectTemplate() OVERRIDE;
  488. // Callback to client panel to create a scrollbar
  489. virtual IUIScrollBar *CreateNewVerticalScrollBar( float flInitialScrollPos ) OVERRIDE;
  490. // Callback to client panel to create a scrollbar
  491. virtual IUIScrollBar *CreateNewHorizontalScrollBar( float flInitialScrollPos ) OVERRIDE;
  492. // Callback to hide tooltip if it's visible
  493. virtual void HideTooltip() OVERRIDE;
  494. // Has this panel ever been layed out
  495. virtual bool BHasBeenLayedOut() const { return m_pIUIPanel->BHasBeenLayedOut(); }
  496. #ifdef DBGFLAG_VALIDATE
  497. virtual void ValidateClientPanel( CValidator &validator, const tchar *pchName ) OVERRIDE;
  498. void Validate( CValidator &validator, const tchar *pchName );
  499. static void ValidateStatics( CValidator &validator, const char *pchName );
  500. #endif
  501. void SetLayoutLoadedFromParent( CPanel2D *pParent ) { m_pIUIPanel->SetLayoutLoadedFromParent( pParent ? pParent->UIPanel() : NULL ); }
  502. IUIImageManager *UIImageManager() { return m_pIUIPanel->UIImageManager(); }
  503. protected:
  504. friend class CPanelStyle;
  505. friend class CStyleFileSet;
  506. friend class CVerticalScrollBar;
  507. friend class CHorizontalScrollBar;
  508. virtual IUIRenderEngine *AccessRenderEngine() { return m_pIUIPanel->GetParentWindow()->UIRenderEngine(); }
  509. void FirePanelLoadedEvent() { m_pIUIPanel->FirePanelLoadedEvent(); }
  510. // override to change how this panel is measured
  511. virtual void OnContentSizeTraverse( float *pflContentWidth, float *pflContentHeight, float flMaxWidth, float flMaxHeight, bool bFinalDimensions ) OVERRIDE
  512. {
  513. m_pIUIPanel->OnContentSizeTraverse( pflContentWidth, pflContentHeight, flMaxWidth, flMaxHeight, bFinalDimensions );
  514. }
  515. // override to add additional panel events
  516. virtual bool BIsClientPanelEvent( CPanoramaSymbol symProperty ) OVERRIDE;
  517. // override to change how this panel arranges its children
  518. virtual void OnLayoutTraverse( float flFinalWidth, float flFinalHeight ) OVERRIDE { m_pIUIPanel->OnLayoutTraverse( flFinalWidth, flFinalHeight ); }
  519. virtual void OnStylesChanged() OVERRIDE { if ( m_pIUIPanel->GetParent() ) { m_pIUIPanel->GetParent()->ClientPtr()->OnChildStylesChanged(); } }
  520. virtual void OnVisibilityChanged() OVERRIDE {}
  521. virtual void OnChildStylesChanged() OVERRIDE { }
  522. // methods for setting properties from a layout file. Default BSetProperties calls BSetProperty on each element.
  523. virtual bool BSetProperties( const CUtlVector< ParsedPanelProperty_t > &vecProperties ) OVERRIDE;
  524. virtual bool BSetProperty( CPanoramaSymbol symName, const char *pchValue ) OVERRIDE;
  525. virtual void OnBeforeChildrenChanged() OVERRIDE {}
  526. virtual void OnAfterChildrenChanged() OVERRIDE {}
  527. virtual void OnRemoveChild( IUIPanel *pChild ) OVERRIDE {}
  528. virtual void OnInitializedFromLayout() OVERRIDE {}
  529. void SetLayoutFile( CPanoramaSymbol symLayoutFile ) { m_pIUIPanel->SetLayoutFile( symLayoutFile ); }
  530. void SetLayoutFileTraverse( CPanoramaSymbol symLayoutFile );
  531. void SetMouseTracking( bool bState ) { m_pIUIPanel->SetMouseTracking( bState ); }
  532. // for cloning
  533. bool AreChildrenClonable();
  534. virtual void InitClonedPanel( CPanel2D *pPanel );
  535. // for setting parent disabled style flag
  536. //bugbug jmccaskey - these are broken... would like to fix so they are uneeded
  537. virtual void AddDisabledFlagToChildren() { }
  538. virtual void RemoveDisabledFlagFromChildren() { }
  539. // Pointer to basic IUIPanel interface from panorama
  540. IUIPanel *m_pIUIPanel;
  541. private:
  542. // we by design don't have a uint32 overload of this, use this function here to enforce it
  543. void SetDialogVariable( const char *pchKey, uint32 nInvalid ) { Assert( !"Invalid call" ); }
  544. CUtlVector<IUIPanel *> const &AccessChildren() { return m_pIUIPanel->AccessChildren(); }
  545. CUtlVector<IUIPanel *> const &JSFindChildrenWithClassTraverse( const char *pchClass );
  546. // event handler functions, these CANNOT be virtual, if you need to override then
  547. // have this function call into another helper that is virtual to override behavior
  548. bool EventAppendChildrenFromLayoutFileAsync( const CPanelPtr< IUIPanel > &pPanel, const char *pchLayoutFile );
  549. bool EventAddStyleClass( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
  550. bool EventRemoveStyleClass( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
  551. bool EventToggleStyleClass( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
  552. bool EventAddStyleClassToEachChild( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
  553. bool EventRemoveStyleClassFromEachChild( const CPanelPtr< IUIPanel > &pPanel, const char *pchName );
  554. bool EventPanelActivated( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
  555. bool EventPanelCancelled( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
  556. bool EventPanelContextMenu( const CPanelPtr< IUIPanel > &pPanel, EPanelEventSource_t eSource );
  557. bool EventPanelLoaded( const CPanelPtr< IUIPanel > &pPanel );
  558. bool EventShowTooltip( const CPanelPtr< IUIPanel > &pPanel );
  559. bool EventScrollUp() { return OnScrollUp(); }
  560. bool EventScrollDown() { return OnScrollDown(); }
  561. bool EventScrollLeft() { return OnScrollLeft(); }
  562. bool EventScrollRight() { return OnScrollRight(); }
  563. bool EventScrollPanelUp( const CPanelPtr< IUIPanel > &pPanel ) { return OnScrollUp(); }
  564. bool EventScrollPanelDown( const CPanelPtr< IUIPanel > &pPanel ) { return OnScrollDown(); }
  565. bool EventScrollPanelLeft( const CPanelPtr< IUIPanel > &pPanel ) { return OnScrollLeft(); }
  566. bool EventScrollPanelRight( const CPanelPtr< IUIPanel > &pPanel ) { return OnScrollRight(); }
  567. bool EventPageUp() { return OnPageUp(); }
  568. bool EventPageDown() { return OnPageDown(); }
  569. bool EventPageLeft() { return OnPageLeft(); }
  570. bool EventPageRight() { return OnPageRight(); }
  571. bool EventPagePanelUp( const CPanelPtr< IUIPanel > &pPanel ) { return OnPageUp(); }
  572. bool EventPagePanelDown( const CPanelPtr< IUIPanel > &pPanel ) { return OnPageDown(); }
  573. bool EventPagePanelLeft( const CPanelPtr< IUIPanel > &pPanel ) { return OnPageLeft(); }
  574. bool EventPagePanelRight( const CPanelPtr< IUIPanel > &pPanel ) { return OnPageRight(); }
  575. bool EventScrollToTop( const CPanelPtr< IUIPanel > &pPanel );
  576. bool EventScrollToBottom( const CPanelPtr< IUIPanel > &pPanel );
  577. bool EventMoveUp( int nRepeats ) { return OnMoveUp( nRepeats ); }
  578. bool EventMoveDown( int nRepeats ) { return OnMoveDown( nRepeats ); }
  579. bool EventMoveLeft( int nRepeats ) { return OnMoveLeft( nRepeats ); }
  580. bool EventMoveRight( int nRepeats ) { return OnMoveRight( nRepeats ); }
  581. bool EventTabForward( int nRepeats ) { return OnTabForward( nRepeats ); }
  582. bool EventTabBackward( int nRepeats ) { return OnTabBackward( nRepeats ); }
  583. bool EventImageLoaded( const CPanelPtr< IUIPanel > &pPanel, IImageSource *pImage );
  584. bool EventImageFailedLoad( const CPanelPtr< IUIPanel > &pPanel, IImageSource *pImage );
  585. bool EventSetPanelEvent( const CPanelPtr< IUIPanel > &pPanel, const char *pchPanelEventName, const char *pchPanelEventAction );
  586. bool EventClearPanelEvent( const CPanelPtr< IUIPanel > &pPanel, const char *pchPanelEventName );
  587. bool EventIfHasClassEvent( const CPanelPtr< IUIPanel > &pPanel, const char * pchClassName, IUIEvent * pEventToFire );
  588. bool EventIfNotHasClassEvent( const CPanelPtr< IUIPanel > &pPanel, const char * pchClassName, IUIEvent * pEventToFire );
  589. bool EventIfHoverOtherEvent( const CPanelPtr< IUIPanel > &pPanel, const char *pchOtherPanelID, IUIEvent * pEventToFire );
  590. bool EventIfNotHoverOtherEvent( const CPanelPtr< IUIPanel > &pPanel, const char *pchOtherPanelID, IUIEvent * pEventToFire );
  591. bool EventIfHoverOverEventInternal( const CPanelPtr< IUIPanel > &pPanel, const char *pchOtherPanelID, IUIEvent * pEventToFire, bool bFireIfHovered );
  592. bool EventCheckChildrenScrolledIntoView( const CPanelPtr< IUIPanel > &pPanel ) { return m_pIUIPanel->OnCheckChildrenScrolledIntoView(); }
  593. bool EventScrollPanelIntoView( const CPanelPtr< IUIPanel > &pPanel, ScrollBehavior_t behavior, bool bImmediate );
  594. void Initialize( IUIWindow *window, CPanel2D *parent, const char *pchID, uint32 ePanelFlags );
  595. bool BAppyLayoutFile( CLayoutFile *pLayoutFile, CUtlVector< CPanel2D * > *pvecExistingPanels );
  596. void DeletePanelsForReloadTraverse( CPanoramaSymbol symPath, CUtlVector< CPanel2D * > *pvecPanelsWithID );
  597. // Is this a property we must create our children before applying during layout file application?
  598. virtual bool BIsDelayedProperty( CPanoramaSymbol symProperty ) OVERRIDE;
  599. void ClearPanelEventJS( CPanoramaSymbol symPanelEvent ) { m_pIUIPanel->ClearPanelEvents( symPanelEvent ); }
  600. // Private helper for JS attribute registration
  601. void RegisterJSFloatTabIndexSelectionPos( const char *pchjsMemberName, PanelFloatGetter_t pGetFunc, PanelFloatSetter_t pSetFunc );
  602. void SetDefaultFocusOnMouseDownBehavior();
  603. // tooltip for panel. Need to keep a safe pointer as the tooltip is a top level window and will be deleted at shutdown automatically
  604. CPanelPtr< CPanel2D > m_pTooltip;
  605. static CUtlVector<IUIPanel *> s_vecMatchingChildren;
  606. };
  607. class CUIScrollBar;
  608. //-----------------------------------------------------------------------------
  609. // Purpose: Base class for all types of scroll bars
  610. //-----------------------------------------------------------------------------
  611. class CBaseScrollBar : public CPanel2D
  612. {
  613. DECLARE_PANEL2D( CBaseScrollBar, CPanel2D );
  614. public:
  615. CBaseScrollBar( CPanel2D *parent, const char * pchPanelID );
  616. virtual ~CBaseScrollBar();
  617. IUIScrollBar *Interface();
  618. // Normalizes the position to be within range min/max
  619. void Normalize( bool bImmediateThumbUpdate = false )
  620. {
  621. if ( m_flWindowStart < m_flRangeMin )
  622. m_flWindowStart = m_flRangeMin;
  623. if ( m_flWindowStart + m_flWindowSize > m_flRangeMax )
  624. {
  625. m_flWindowStart = m_flRangeMax - m_flWindowSize;
  626. m_flWindowStart = RoundFloatToInt( m_flWindowStart );
  627. }
  628. else
  629. {
  630. m_flWindowStart = RoundFloatToInt( m_flWindowStart );
  631. }
  632. UpdateLayout( bImmediateThumbUpdate );
  633. }
  634. // Set the scroll range
  635. void SetRangeMinMax( float flRangeMin, float flRangeMax )
  636. {
  637. if ( m_flRangeMin != flRangeMin || m_flRangeMax != flRangeMax )
  638. {
  639. m_flRangeMin = flRangeMin;
  640. m_flRangeMax = flRangeMax;
  641. if ( GetParent() )
  642. GetParent()->InvalidatePosition();
  643. Normalize( false );
  644. }
  645. }
  646. // return the size of the range we have
  647. float GetRangeSize() const { return m_flRangeMax - m_flRangeMin; }
  648. float GetRangeMin() const { return m_flRangeMin; }
  649. float GetRangeMax() const { return m_flRangeMax; }
  650. // Set the window size
  651. void SetScrollWindowSize( float flWindowSize )
  652. {
  653. if ( m_flWindowSize != flWindowSize )
  654. {
  655. m_flWindowSize = flWindowSize;
  656. if ( GetParent() )
  657. GetParent()->InvalidatePosition();
  658. Normalize( false );
  659. }
  660. }
  661. // Get scroll window size
  662. float GetScrollWindowSize() { return m_flWindowSize; }
  663. // Set the current window position
  664. void SetScrollWindowPosition( float flWindowPos, bool bImmediateMove = false )
  665. {
  666. m_flWindowStart = flWindowPos;
  667. m_flLastScrollTime = UIEngine()->GetCurrentFrameTime();
  668. if ( GetParent() )
  669. {
  670. if ( GetParent()->IsChildPositionValid() && GetParent()->IsPositionValid() )
  671. Normalize( bImmediateMove );
  672. GetParent()->InvalidatePosition();
  673. GetParent()->OnScrollPositionChanged();
  674. }
  675. }
  676. double GetLastScrollTime() { return m_flLastScrollTime; }
  677. // Get scroll window position
  678. float GetScrollWindowPosition() { return m_flWindowStart; }
  679. bool BLastMoveImmediate() { return m_bLastMoveImmediate; }
  680. protected:
  681. friend class CUIScrollBar;
  682. CUIScrollBar *m_pScrollBarInterface;
  683. virtual void UpdateLayout( bool bImmediateMove ) = 0;
  684. bool m_bLastMoveImmediate;
  685. double m_flLastScrollTime;
  686. float m_flRangeMin;
  687. float m_flRangeMax;
  688. float m_flWindowSize;
  689. float m_flWindowStart;
  690. };
  691. //-----------------------------------------------------------------------------
  692. // Purpose: Default Scrollbar
  693. //-----------------------------------------------------------------------------
  694. class CScrollBar : public CBaseScrollBar
  695. {
  696. DECLARE_PANEL2D( CScrollBar, CBaseScrollBar );
  697. public:
  698. CScrollBar( CPanel2D *parent, const char * pchPanelID );
  699. virtual ~CScrollBar();
  700. virtual void ScrollToMousePos() = 0;
  701. virtual void OnMouseMove( float flMouseX, float flMouseY )
  702. {
  703. // If there's a transform set on the parent, adjust the input as appropriate.
  704. Vector vMousePosition( flMouseX, flMouseY, 0.0f );
  705. if ( GetParent() )
  706. {
  707. VMatrix matParentTransform = GetParent()->AccessStyle()->GetTransform3DMatrix();
  708. vMousePosition = matParentTransform * vMousePosition;
  709. }
  710. m_flMouseX = vMousePosition.x;
  711. m_flMouseY = vMousePosition.y;
  712. if ( m_bMouseDown )
  713. ScrollToMousePos();
  714. }
  715. virtual bool OnMouseButtonDown( const MouseData_t &code )
  716. {
  717. // Only interested in left clicks
  718. if ( code.m_MouseCode != MOUSE_LEFT )
  719. return BaseClass::OnMouseButtonDown( code );
  720. AddClass( "MouseDown" );
  721. if ( m_pScrollThumb->BHasHoverStyle() )
  722. m_bMouseWentDownOnThumb = true;
  723. else
  724. m_bMouseWentDownOnThumb = false;
  725. m_bMouseDown = true;
  726. m_flMouseStartX = m_flMouseX;
  727. m_flMouseStartY = m_flMouseY;
  728. m_flScrollStartPosition = GetScrollWindowPosition();
  729. ScrollToMousePos();
  730. return true;
  731. }
  732. virtual bool OnMouseButtonUp( const MouseData_t &code )
  733. {
  734. // Only interested in left clicks
  735. if ( code.m_MouseCode != MOUSE_LEFT )
  736. return BaseClass::OnMouseButtonDown( code );
  737. m_bMouseDown = false;
  738. ScrollToMousePos();
  739. RemoveClass( "MouseDown" );
  740. return true;
  741. }
  742. protected:
  743. CPanel2D *m_pScrollThumb;
  744. bool m_bMouseDown;
  745. bool m_bMouseWentDownOnThumb;
  746. float m_flMouseX;
  747. float m_flMouseY;
  748. float m_flMouseStartX;
  749. float m_flMouseStartY;
  750. float m_flScrollStartPosition;
  751. };
  752. class CUIScrollBar : public IUIScrollBar
  753. {
  754. public:
  755. CUIScrollBar( CBaseScrollBar *pParent ) { m_pParent = pParent; }
  756. virtual IUIPanel* UIPanel() OVERRIDE { return m_pParent->UIPanel(); }
  757. virtual IUIPanelClient* ClientPtr() OVERRIDE { return m_pParent; }
  758. virtual void Normalize( bool bImmediateThumbUpdate ) OVERRIDE { return m_pParent->Normalize( bImmediateThumbUpdate ); }
  759. virtual void SetRangeMinMax( float flRangeMin, float flRangeMax ) OVERRIDE { return m_pParent->SetRangeMinMax( flRangeMin, flRangeMax ); }
  760. virtual float GetRangeSize() const OVERRIDE { return m_pParent->GetRangeSize(); }
  761. virtual float GetRangeMin() const OVERRIDE { return m_pParent->GetRangeMin(); }
  762. virtual float GetRangeMax() const OVERRIDE { return m_pParent->GetRangeMax(); }
  763. // Set the window size
  764. virtual void SetScrollWindowSize( float flWindowSize ) OVERRIDE { return m_pParent->SetScrollWindowSize( flWindowSize ); }
  765. // Get scroll window size
  766. virtual float GetScrollWindowSize() OVERRIDE { return m_pParent->GetScrollWindowSize(); }
  767. // Set the current window position
  768. virtual void SetScrollWindowPosition( float flWindowPos, bool bImmediateMove = false ) OVERRIDE { return m_pParent->SetScrollWindowPosition( flWindowPos, bImmediateMove ); }
  769. virtual float GetLastScrollTime() OVERRIDE { return m_pParent->GetLastScrollTime(); }
  770. // Get scroll window position
  771. virtual float GetScrollWindowPosition() OVERRIDE { return m_pParent->GetScrollWindowPosition(); }
  772. // Return true if the user is manually dragging the scrollbar with the mouse
  773. virtual bool BLastMoveImmediate() OVERRIDE { return m_pParent->BLastMoveImmediate(); }
  774. private:
  775. CBaseScrollBar *m_pParent;
  776. };
  777. //-----------------------------------------------------------------------------
  778. // Purpose: Vertical scroll bar
  779. //-----------------------------------------------------------------------------
  780. class CVerticalScrollBar : public CScrollBar
  781. {
  782. DECLARE_PANEL2D( CVerticalScrollBar, CScrollBar );
  783. public:
  784. CVerticalScrollBar( CPanel2D *parent, const char * pchPanelID ) : CScrollBar( parent, pchPanelID )
  785. {
  786. m_pScrollThumb->AddClass( "VerticalScrollThumb" );
  787. }
  788. void ScrollToMousePos()
  789. {
  790. CPanel2D *pPanel = GetParent();
  791. if ( pPanel )
  792. {
  793. float flHeight = GetActualLayoutHeight();
  794. if ( flHeight > 0.00001f )
  795. {
  796. if ( m_bMouseWentDownOnThumb )
  797. {
  798. float flPercentDiff = (m_flMouseY - m_flMouseStartY) / flHeight;
  799. float flPositionOffset = flPercentDiff * pPanel->GetContentHeight();
  800. float flPosition = m_flScrollStartPosition + flPositionOffset;
  801. SetScrollWindowPosition( clamp( flPosition, 0.0f, pPanel->GetContentHeight() - GetScrollWindowSize() ), true );
  802. }
  803. else
  804. {
  805. float flPercent = m_flMouseY / flHeight;
  806. float flPos = pPanel->GetContentHeight() * flPercent;
  807. SetScrollWindowPosition( clamp( flPos, 0.0f, pPanel->GetContentHeight() - GetScrollWindowSize() ), true );
  808. }
  809. }
  810. }
  811. }
  812. virtual ~CVerticalScrollBar() {}
  813. protected:
  814. virtual void UpdateLayout( bool bImmediateMove );
  815. };
  816. //-----------------------------------------------------------------------------
  817. // Purpose: Horizontal scroll bar
  818. //-----------------------------------------------------------------------------
  819. class CHorizontalScrollBar : public CScrollBar
  820. {
  821. DECLARE_PANEL2D( CHorizontalScrollBar, CScrollBar );
  822. public:
  823. CHorizontalScrollBar( CPanel2D *parent, const char * pchPanelID ) : CScrollBar( parent, pchPanelID )
  824. {
  825. m_pScrollThumb->AddClass( "HorizontalScrollThumb" );
  826. }
  827. void ScrollToMousePos()
  828. {
  829. CPanel2D *pPanel = GetParent();
  830. if ( pPanel )
  831. {
  832. float flWidth = GetActualLayoutWidth();
  833. if ( flWidth > 0.00001f )
  834. {
  835. if ( m_bMouseWentDownOnThumb )
  836. {
  837. float flPercentDiff = ( m_flMouseX - m_flMouseStartX ) / flWidth;
  838. float flPositionOffset = flPercentDiff * pPanel->GetContentWidth();
  839. float flPosition = m_flScrollStartPosition + flPositionOffset;
  840. SetScrollWindowPosition( clamp( flPosition, 0.0f, pPanel->GetContentWidth() - GetScrollWindowSize() ), true );
  841. }
  842. else
  843. {
  844. float flPercent = m_flMouseX / flWidth;
  845. float flPos = pPanel->GetContentWidth() * flPercent;
  846. SetScrollWindowPosition( clamp( flPos, 0.0f, pPanel->GetContentWidth() - GetScrollWindowSize() ), true );
  847. }
  848. }
  849. }
  850. }
  851. virtual ~CHorizontalScrollBar() {}
  852. protected:
  853. virtual void UpdateLayout( bool bImmediateMove );
  854. };
  855. #pragma warning(pop)
  856. } // namespace panorama
  857. #endif // PANEL2D_H