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.

264 lines
5.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //===========================================================================//
  9. #include "stdafx.h"
  10. #include "vguiwnd.h"
  11. #include <vgui_controls/EditablePanel.h>
  12. #include "vgui/ISurface.h"
  13. #include "vgui/IVGui.h"
  14. #include "VGuiMatSurface/IMatSystemSurface.h"
  15. #include "HammerVGui.h"
  16. #include "material.h"
  17. #include "istudiorender.h"
  18. #include "hammer.h"
  19. IMPLEMENT_DYNCREATE(CVGuiPanelWnd, CWnd)
  20. #define REPAINT_TIMER_ID 1042 //random value, hopfully no collisions
  21. class CBaseMainPanel : public vgui::EditablePanel
  22. {
  23. public:
  24. CBaseMainPanel(Panel *parent, const char *panelName) : vgui::EditablePanel( parent, panelName ) {};
  25. virtual void OnSizeChanged(int newWide, int newTall)
  26. {
  27. // call Panel and not EditablePanel OnSizeChanged.
  28. Panel::OnSizeChanged(newWide, newTall);
  29. }
  30. };
  31. LRESULT CVGuiPanelWnd::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
  32. {
  33. if ( !WindowProcVGui( message, wParam, lParam ) )
  34. {
  35. return CWnd::WindowProc( message, wParam, lParam ) ;
  36. }
  37. return 1;
  38. }
  39. BEGIN_MESSAGE_MAP(CVGuiPanelWnd, CWnd)
  40. END_MESSAGE_MAP()
  41. CVGuiWnd::CVGuiWnd(void)
  42. {
  43. m_pMainPanel = NULL;
  44. m_pParentWnd = NULL;
  45. m_hVGuiContext = vgui::DEFAULT_VGUI_CONTEXT;
  46. m_bIsDrawing = false;
  47. m_ClearColor.SetColor( 0,0,0,255 );
  48. m_bClearZBuffer = true;
  49. }
  50. CVGuiWnd::~CVGuiWnd(void)
  51. {
  52. if ( HammerVGui()->HasFocus( this ) )
  53. {
  54. HammerVGui()->SetFocus( NULL );
  55. }
  56. if ( m_hVGuiContext != vgui::DEFAULT_VGUI_CONTEXT )
  57. {
  58. vgui::ivgui()->DestroyContext( m_hVGuiContext );
  59. m_hVGuiContext = vgui::DEFAULT_VGUI_CONTEXT;
  60. }
  61. // kill the timer if any
  62. ::KillTimer( m_pParentWnd->GetSafeHwnd(), REPAINT_TIMER_ID );
  63. if ( m_pMainPanel )
  64. m_pMainPanel->MarkForDeletion();
  65. }
  66. void CVGuiWnd::SetParentWindow(CWnd *pParent)
  67. {
  68. m_pParentWnd = pParent;
  69. m_pParentWnd->EnableWindow( true );
  70. m_pParentWnd->SetFocus();
  71. }
  72. int CVGuiWnd::GetVGuiContext()
  73. {
  74. return m_hVGuiContext;
  75. }
  76. void CVGuiWnd::SetCursor(vgui::HCursor cursor)
  77. {
  78. if ( m_pMainPanel )
  79. {
  80. m_pMainPanel->SetCursor( cursor );
  81. }
  82. }
  83. void CVGuiWnd::SetCursor(const char *filename)
  84. {
  85. vgui::HCursor hCursor = vgui::surface()->CreateCursorFromFile( filename );
  86. m_pMainPanel->SetCursor( hCursor );
  87. }
  88. void CVGuiWnd::SetMainPanel( vgui::EditablePanel * pPanel )
  89. {
  90. Assert( m_pMainPanel == NULL );
  91. Assert( m_hVGuiContext == vgui::DEFAULT_VGUI_CONTEXT );
  92. m_pMainPanel = pPanel;
  93. m_pMainPanel->SetParent( vgui::surface()->GetEmbeddedPanel() );
  94. m_pMainPanel->SetVisible( true );
  95. m_pMainPanel->SetPaintBackgroundEnabled( false );
  96. m_pMainPanel->SetCursor( vgui::dc_arrow );
  97. m_hVGuiContext = vgui::ivgui()->CreateContext();
  98. vgui::ivgui()->AssociatePanelWithContext( m_hVGuiContext, m_pMainPanel->GetVPanel() );
  99. }
  100. vgui::EditablePanel *CVGuiWnd::CreateDefaultPanel()
  101. {
  102. return new CBaseMainPanel( NULL, "mainpanel" );
  103. }
  104. vgui::EditablePanel *CVGuiWnd::GetMainPanel()
  105. {
  106. return m_pMainPanel;
  107. }
  108. CWnd *CVGuiWnd::GetParentWnd()
  109. {
  110. return m_pParentWnd;
  111. }
  112. void CVGuiWnd::SetRepaintInterval( int msecs )
  113. {
  114. ::SetTimer( m_pParentWnd->GetSafeHwnd(), REPAINT_TIMER_ID, msecs, NULL );
  115. }
  116. void CVGuiWnd::DrawVGuiPanel()
  117. {
  118. if ( !m_pMainPanel || !m_pParentWnd || m_bIsDrawing )
  119. return;
  120. m_bIsDrawing = true; // avoid recursion
  121. HWND hWnd = m_pParentWnd->GetSafeHwnd();
  122. int w,h;
  123. RECT rect; ::GetClientRect(hWnd, &rect);
  124. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  125. MaterialSystemInterface()->SetView( hWnd );
  126. pRenderContext->Viewport( 0, 0, rect.right, rect.bottom );
  127. pRenderContext->ClearColor4ub( m_ClearColor.r(), m_ClearColor.g(), m_ClearColor.b(), m_ClearColor.a() );
  128. pRenderContext->ClearBuffers( true, m_bClearZBuffer );
  129. MaterialSystemInterface()->BeginFrame( 0 );
  130. g_pStudioRender->BeginFrame();
  131. // draw from the main panel down
  132. m_pMainPanel->GetSize( w , h );
  133. if ( w != rect.right || h != rect.bottom )
  134. {
  135. m_pMainPanel->SetBounds(0, 0, rect.right, rect.bottom );
  136. m_pMainPanel->Repaint();
  137. }
  138. HammerVGui()->Simulate();
  139. vgui::surface()->PaintTraverseEx( m_pMainPanel->GetVPanel(), true );
  140. g_pStudioRender->EndFrame();
  141. MaterialSystemInterface()->EndFrame();
  142. MaterialSystemInterface()->SwapBuffers();
  143. m_bIsDrawing = false;
  144. }
  145. LRESULT CVGuiWnd::WindowProcVGui( UINT uMsg, WPARAM wParam, LPARAM lParam )
  146. {
  147. switch(uMsg)
  148. {
  149. case WM_GETDLGCODE :
  150. {
  151. // forward all keyboard into to vgui panel
  152. return DLGC_WANTALLKEYS|DLGC_WANTCHARS;
  153. }
  154. case WM_PAINT :
  155. {
  156. // draw the VGUI panel now
  157. DrawVGuiPanel();
  158. break;
  159. }
  160. case WM_TIMER :
  161. {
  162. if ( wParam == REPAINT_TIMER_ID )
  163. {
  164. m_pParentWnd->Invalidate();
  165. }
  166. break;
  167. }
  168. case WM_SETCURSOR:
  169. return 1; // don't pass WM_SETCURSOR
  170. case WM_LBUTTONDOWN:
  171. case WM_RBUTTONDOWN:
  172. case WM_MBUTTONDOWN:
  173. case WM_MOUSEMOVE:
  174. {
  175. // switch vgui focus to this panel
  176. HammerVGui()->SetFocus( this );
  177. // request keyboard focus too on mouse down
  178. if ( uMsg != WM_MOUSEMOVE)
  179. {
  180. m_pParentWnd->Invalidate();
  181. m_pParentWnd->SetFocus();
  182. }
  183. break;
  184. }
  185. case WM_KILLFOCUS:
  186. {
  187. // restore normal arrow cursor when mouse leaves VGUI panel
  188. SetCursor( vgui::dc_arrow );
  189. break;
  190. }
  191. case WM_LBUTTONUP:
  192. case WM_RBUTTONUP:
  193. case WM_MBUTTONUP:
  194. case WM_LBUTTONDBLCLK:
  195. case WM_RBUTTONDBLCLK:
  196. case WM_MBUTTONDBLCLK:
  197. case WM_MOUSEWHEEL:
  198. case WM_KEYDOWN:
  199. case WM_SYSKEYDOWN:
  200. case WM_SYSCHAR:
  201. case WM_CHAR:
  202. case WM_KEYUP:
  203. case WM_SYSKEYUP:
  204. {
  205. // redraw window
  206. m_pParentWnd->Invalidate();
  207. break;
  208. }
  209. }
  210. return 0;
  211. }