Counter Strike : Global Offensive Source Code
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.

302 lines
6.5 KiB

  1. //===== Copyright � 1996-2007, 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. #include "toolutils/enginetools_int.h"
  20. #include "toolframework/ienginetool.h"
  21. #include "ienginevgui.h"
  22. IMPLEMENT_DYNCREATE(CVGuiPanelWnd, CWnd)
  23. #define REPAINT_TIMER_ID 1042 //random value, hopfully no collisions
  24. class CBaseMainPanel : public vgui::EditablePanel
  25. {
  26. public:
  27. CBaseMainPanel(Panel *parent, const char *panelName) : vgui::EditablePanel( parent, panelName ) {};
  28. virtual void OnSizeChanged(int newWide, int newTall)
  29. {
  30. // call Panel and not EditablePanel OnSizeChanged.
  31. Panel::OnSizeChanged(newWide, newTall);
  32. }
  33. };
  34. LRESULT CVGuiPanelWnd::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
  35. {
  36. if ( !WindowProcVGui( message, wParam, lParam ) )
  37. {
  38. return CWnd::WindowProc( message, wParam, lParam ) ;
  39. }
  40. return 1;
  41. }
  42. BOOL CVGuiPanelWnd::OnEraseBkgnd(CDC* pDC)
  43. {
  44. return TRUE;
  45. }
  46. BEGIN_MESSAGE_MAP(CVGuiPanelWnd, CWnd)
  47. ON_WM_ERASEBKGND()
  48. END_MESSAGE_MAP()
  49. CVGuiWnd::CVGuiWnd(void)
  50. {
  51. m_pMainPanel = NULL;
  52. m_pParentWnd = NULL;
  53. m_hVGuiContext = vgui::DEFAULT_VGUI_CONTEXT;
  54. m_bIsDrawing = false;
  55. m_ClearColor.SetColor( 0,0,0,255 );
  56. m_bClearZBuffer = true;
  57. }
  58. CVGuiWnd::~CVGuiWnd(void)
  59. {
  60. if ( HammerVGui()->HasFocus( this ) )
  61. {
  62. HammerVGui()->SetFocus( NULL );
  63. }
  64. if ( m_hVGuiContext != vgui::DEFAULT_VGUI_CONTEXT )
  65. {
  66. vgui::ivgui()->DestroyContext( m_hVGuiContext );
  67. m_hVGuiContext = vgui::DEFAULT_VGUI_CONTEXT;
  68. }
  69. // kill the timer if any
  70. ::KillTimer( m_pParentWnd->GetSafeHwnd(), REPAINT_TIMER_ID );
  71. if ( m_pMainPanel )
  72. m_pMainPanel->MarkForDeletion();
  73. }
  74. void CVGuiWnd::SetParentWindow(CWnd *pParent)
  75. {
  76. m_pParentWnd = pParent;
  77. m_pParentWnd->EnableWindow( true );
  78. m_pParentWnd->SetFocus();
  79. }
  80. int CVGuiWnd::GetVGuiContext()
  81. {
  82. return m_hVGuiContext;
  83. }
  84. void CVGuiWnd::SetCursor(vgui::HCursor cursor)
  85. {
  86. if ( m_pMainPanel )
  87. {
  88. m_pMainPanel->SetCursor( cursor );
  89. }
  90. }
  91. void CVGuiWnd::SetCursor(const char *filename)
  92. {
  93. vgui::HCursor hCursor = vgui::surface()->CreateCursorFromFile( filename );
  94. m_pMainPanel->SetCursor( hCursor );
  95. }
  96. void CVGuiWnd::SetMainPanel( vgui::EditablePanel * pPanel )
  97. {
  98. Assert( m_pMainPanel == NULL );
  99. Assert( m_hVGuiContext == vgui::DEFAULT_VGUI_CONTEXT );
  100. m_pMainPanel = pPanel;
  101. m_pMainPanel->SetParent( vgui::surface()->GetEmbeddedPanel() );
  102. m_pMainPanel->SetVisible( true );
  103. m_pMainPanel->SetPaintBackgroundEnabled( false );
  104. m_pMainPanel->SetCursor( vgui::dc_arrow );
  105. // Initially, don't trap mouse input in case the engine is around (if we have this set to true and they go to the engine,
  106. // it'll hog mouse input that the engine should get).
  107. m_pMainPanel->SetMouseInputEnabled( false );
  108. m_hVGuiContext = vgui::ivgui()->CreateContext();
  109. vgui::ivgui()->AssociatePanelWithContext( m_hVGuiContext, m_pMainPanel->GetVPanel() );
  110. }
  111. vgui::EditablePanel *CVGuiWnd::CreateDefaultPanel()
  112. {
  113. return new CBaseMainPanel( NULL, "mainpanel" );
  114. }
  115. vgui::EditablePanel *CVGuiWnd::GetMainPanel()
  116. {
  117. return m_pMainPanel;
  118. }
  119. CWnd *CVGuiWnd::GetParentWnd()
  120. {
  121. return m_pParentWnd;
  122. }
  123. void CVGuiWnd::SetRepaintInterval( int msecs )
  124. {
  125. ::SetTimer( m_pParentWnd->GetSafeHwnd(), REPAINT_TIMER_ID, msecs, NULL );
  126. }
  127. void CVGuiWnd::DrawVGuiPanel()
  128. {
  129. if ( !m_pMainPanel || !m_pParentWnd || m_bIsDrawing )
  130. return;
  131. m_bIsDrawing = true; // avoid recursion
  132. HWND hWnd = m_pParentWnd->GetSafeHwnd();
  133. int w,h;
  134. RECT rect; ::GetClientRect(hWnd, &rect);
  135. CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
  136. MaterialSystemInterface()->SetView( hWnd );
  137. pRenderContext->Viewport( 0, 0, rect.right, rect.bottom );
  138. pRenderContext->ClearColor4ub( m_ClearColor.r(), m_ClearColor.g(), m_ClearColor.b(), m_ClearColor.a() );
  139. pRenderContext->ClearBuffers( true, m_bClearZBuffer );
  140. MaterialSystemInterface()->BeginFrame( 0 );
  141. g_pStudioRender->BeginFrame();
  142. // draw from the main panel down
  143. m_pMainPanel->GetSize( w , h );
  144. if ( w != rect.right || h != rect.bottom )
  145. {
  146. m_pMainPanel->SetBounds(0, 0, rect.right, rect.bottom );
  147. m_pMainPanel->Repaint();
  148. }
  149. HammerVGui()->Simulate();
  150. // Don't draw the engine's vgui stuff when in .
  151. int iWasVisible = -1;
  152. vgui::VPANEL hRoot = NULL;
  153. if ( APP()->IsFoundryMode() && enginevgui )
  154. {
  155. hRoot = enginevgui->GetPanel( PANEL_ROOT );
  156. iWasVisible = g_pVGuiPanel->IsVisible( hRoot );
  157. g_pVGuiPanel->SetVisible( hRoot, false );
  158. }
  159. vgui::surface()->RestrictPaintToSinglePanel( m_pMainPanel->GetVPanel(), true );
  160. vgui::surface()->PaintTraverseEx( m_pMainPanel->GetVPanel(), true );
  161. vgui::surface()->RestrictPaintToSinglePanel( NULL );
  162. if ( iWasVisible != -1 )
  163. {
  164. g_pVGuiPanel->SetVisible( hRoot, (iWasVisible != 0) );
  165. }
  166. g_pStudioRender->EndFrame();
  167. MaterialSystemInterface()->EndFrame();
  168. MaterialSystemInterface()->SwapBuffers();
  169. if ( enginetools )
  170. {
  171. MaterialSystemInterface()->SetView( enginetools->GetEngineHwnd() );
  172. }
  173. m_bIsDrawing = false;
  174. }
  175. LRESULT CVGuiWnd::WindowProcVGui( UINT uMsg, WPARAM wParam, LPARAM lParam )
  176. {
  177. switch(uMsg)
  178. {
  179. case WM_GETDLGCODE :
  180. {
  181. // forward all keyboard into to vgui panel
  182. return DLGC_WANTALLKEYS|DLGC_WANTCHARS;
  183. }
  184. case WM_PAINT :
  185. {
  186. // draw the VGUI panel now
  187. DrawVGuiPanel();
  188. break;
  189. }
  190. case WM_TIMER :
  191. {
  192. if ( wParam == REPAINT_TIMER_ID )
  193. {
  194. m_pParentWnd->Invalidate();
  195. }
  196. break;
  197. }
  198. case WM_SETCURSOR:
  199. return 1; // don't pass WM_SETCURSOR
  200. case WM_LBUTTONDOWN:
  201. case WM_RBUTTONDOWN:
  202. case WM_MBUTTONDOWN:
  203. case WM_MOUSEMOVE:
  204. {
  205. // switch vgui focus to this panel
  206. HammerVGui()->SetFocus( this );
  207. // request keyboard focus too on mouse down
  208. if ( uMsg != WM_MOUSEMOVE)
  209. {
  210. m_pParentWnd->Invalidate();
  211. m_pParentWnd->SetFocus();
  212. }
  213. break;
  214. }
  215. case WM_KILLFOCUS:
  216. {
  217. // restore normal arrow cursor when mouse leaves VGUI panel
  218. SetCursor( vgui::dc_arrow );
  219. break;
  220. }
  221. case WM_LBUTTONUP:
  222. case WM_RBUTTONUP:
  223. case WM_MBUTTONUP:
  224. case WM_LBUTTONDBLCLK:
  225. case WM_RBUTTONDBLCLK:
  226. case WM_MBUTTONDBLCLK:
  227. case WM_MOUSEWHEEL:
  228. case WM_KEYDOWN:
  229. case WM_SYSKEYDOWN:
  230. case WM_SYSCHAR:
  231. case WM_CHAR:
  232. case WM_KEYUP:
  233. case WM_SYSKEYUP:
  234. {
  235. // redraw window
  236. if ( m_pParentWnd )
  237. {
  238. m_pParentWnd->Invalidate();
  239. }
  240. break;
  241. }
  242. }
  243. return 0;
  244. }