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.

1975 lines
61 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. // This class is a message box that has two buttons, ok and cancel instead of
  5. // just the ok button of a message box. We use a message box class for the ok button
  6. // and implement another button here.
  7. //
  8. // $NoKeywords: $ƒ
  9. //=============================================================================//
  10. #include "vgui_controls/pch_vgui_controls.h"
  11. #include <vgui_controls/EditablePanel.h>
  12. #include <vgui_controls/Menu.h>
  13. #include <vgui_controls/MessageBox.h>
  14. #include <tier0/memdbgoff.h>
  15. #include <tier0/memdbgon.h>
  16. #include "filesystem.h"
  17. #include "../vgui2/src/vgui_key_translation.h"
  18. #include "../public/input/mousecursors.h"
  19. #undef schema
  20. #undef PostMessage
  21. #undef MessageBox
  22. #include "tier0/vprof.h"
  23. #include "OfflineMode.h"
  24. #ifdef _X360
  25. #include "xbox/xbox_win32stubs.h"
  26. #endif
  27. // memdbgon must be the last include file in a .cpp file
  28. #include "tier0/memdbgon.h"
  29. using namespace vgui;
  30. // This isn't preferable, would likely work better to have only one system receiving the callbacks and dispatching them properly
  31. #define CHECK_BROWSER_HANDLE() do { if ( pCmd->unBrowserHandle != m_unBrowserHandle ) return; } while ( false )
  32. const int k_nMaxCustomCursors = 2; // the max number of custom cursors we keep cached PER html control
  33. bool gScaleformBrowserActive = false;
  34. // Workaround to only allow one popup window to be visible
  35. // Try to avoid malicious server from opening multiple window on the client side
  36. static bool gMOTDPopupWindowActive = false;
  37. //-----------------------------------------------------------------------------
  38. // Purpose: A simple passthrough panel to render the border onto the HTML widget
  39. //-----------------------------------------------------------------------------
  40. class HTMLInterior : public Panel
  41. {
  42. DECLARE_CLASS_SIMPLE( HTMLInterior, Panel );
  43. public:
  44. HTMLInterior( HTML *parent ) : BaseClass( parent, "HTMLInterior" )
  45. {
  46. m_pHTML = parent;
  47. SetPaintBackgroundEnabled( false );
  48. // TODO::STYLE
  49. //SetPaintAppearanceEnabled( true );
  50. SetKeyBoardInputEnabled( false );
  51. SetMouseInputEnabled( false );
  52. }
  53. // TODO::STYLE
  54. /*
  55. virtual int GetStyleFlags()
  56. {
  57. int nStyleFlags = BaseClass::GetStyleFlags();
  58. if ( m_pHTML->IsScrollbarVisible() )
  59. nStyleFlags |= k_EStyleFlagScrollbarVisible;
  60. return nStyleFlags;
  61. }
  62. */
  63. /*
  64. virtual void Paint()
  65. {
  66. // super-hacky paint
  67. // TODO::STYLE
  68. PaintAppearanceBackground();
  69. PaintAppearance();
  70. }*/
  71. private:
  72. HTML *m_pHTML;
  73. };
  74. //-----------------------------------------------------------------------------
  75. // Purpose: container class for any external popup windows the browser requests
  76. //-----------------------------------------------------------------------------
  77. class HTMLPopup : public vgui::Frame
  78. {
  79. DECLARE_CLASS_SIMPLE( HTMLPopup, vgui::Frame );
  80. class PopupHTML : public vgui::HTML
  81. {
  82. DECLARE_CLASS_SIMPLE( PopupHTML, vgui::HTML );
  83. public:
  84. PopupHTML( Frame *parent, const char *pchName, bool allowJavaScript , bool bPopupWindow, HHTMLBrowser unBrowserHandleToDelete ) : HTML( parent, pchName, allowJavaScript, bPopupWindow, unBrowserHandleToDelete ) { m_pParent = parent; }
  85. virtual void OnSetHTMLTitle( const char *pchTitle )
  86. {
  87. BaseClass::OnSetHTMLTitle( pchTitle );
  88. m_pParent->SetTitle( pchTitle, true );
  89. }
  90. private:
  91. Frame *m_pParent;
  92. };
  93. public:
  94. HTMLPopup( Panel *parent, HHTMLBrowser unBrowserHandleToDelete, const char *pchURL, const char *pchTitle ) : Frame( NULL, "HtmlPopup", true )
  95. {
  96. m_pHTML = new PopupHTML( this, "htmlpopupchild", true, true, unBrowserHandleToDelete );
  97. m_pHTML->OpenURL( pchURL, NULL );
  98. SetTitle( pchTitle, true );
  99. // Workaround to only allow one popup window to be visible
  100. // Try to avoid malicious server from opening multiple window on the client side
  101. gMOTDPopupWindowActive = true;
  102. }
  103. ~HTMLPopup()
  104. {
  105. gMOTDPopupWindowActive = false;
  106. }
  107. enum
  108. {
  109. vert_inset = 40,
  110. horiz_inset = 6
  111. };
  112. void PerformLayout()
  113. {
  114. BaseClass::PerformLayout();
  115. int wide, tall;
  116. GetSize( wide, tall );
  117. m_pHTML->SetPos( horiz_inset, vert_inset );
  118. m_pHTML->SetSize( wide - horiz_inset*2, tall - vert_inset*2 );
  119. }
  120. void SetBounds( int x, int y, int wide, int tall )
  121. {
  122. BaseClass::SetBounds( x, y, wide + horiz_inset*2, tall + vert_inset*2 );
  123. }
  124. MESSAGE_FUNC( OnCloseWindow, "OnCloseWindow" )
  125. {
  126. Close();
  127. }
  128. private:
  129. PopupHTML *m_pHTML;
  130. };
  131. //-----------------------------------------------------------------------------
  132. // Purpose: Constructor
  133. //-----------------------------------------------------------------------------
  134. HTML::HTML( Panel *parent, const char *name, bool allowJavaScript /*= false*/, bool bPopupWindow /*= false*/, HHTMLBrowser unBrowserHandleToDelete /*= INVALID_HTMLBROWSER*/ )
  135. :
  136. Panel( parent, name ),
  137. m_unBrowserHandle( INVALID_HTMLBROWSER ),
  138. m_unBrowserHandleToDelete( unBrowserHandleToDelete ),
  139. m_bPopupWindow( bPopupWindow ),
  140. m_NeedsPaint( this, &HTML::BrowserNeedsPaint ),
  141. m_StartRequest( this, &HTML::BrowserStartRequest ),
  142. m_URLChanged( this, &HTML::BrowserURLChanged ),
  143. m_FinishedRequest( this, &HTML::BrowserFinishedRequest ),
  144. m_HorizScroll( this, &HTML::BrowserHorizontalScrollBarSizeResponse ),
  145. m_VertScroll( this, &HTML::BrowserVerticalScrollBarSizeResponse ),
  146. m_CanGoBackForward( this, &HTML::BrowserCanGoBackandForward ),
  147. m_SetCursor( this, &HTML::BrowserSetCursor ),
  148. m_Close( this, &HTML::BrowserClose ),
  149. m_FileOpenDialog( this, &HTML::BrowserFileOpenDialog ),
  150. m_ShowToolTip( this, &HTML::BrowserShowToolTip ),
  151. m_UpdateToolTip( this, &HTML::BrowserUpdateToolTip ),
  152. m_HideToolTip( this, &HTML::BrowserHideToolTip ),
  153. m_SearchResults( this, &HTML::BrowserSearchResults ),
  154. m_LinkAtPositionResponse( this, &HTML::BrowserLinkAtPositionResponse ),
  155. m_JSAlert( this, &HTML::BrowserJSAlert ),
  156. m_JSConfirm( this, &HTML::BrowserJSConfirm ),
  157. m_NewWindow( this, &HTML::BrowserPopupHTMLWindow )
  158. {
  159. m_iHTMLTextureID = 0;
  160. m_iComboBoxTextureID = 0;
  161. m_bCanGoBack = false;
  162. m_bCanGoForward = false;
  163. m_bInFind = false;
  164. m_bRequestingDragURL = false;
  165. m_bRequestingCopyLink = false;
  166. m_flZoom = 100.0f;
  167. m_iBrowser = -1;
  168. m_pInteriorPanel = new HTMLInterior( this );
  169. SetPostChildPaintEnabled( true );
  170. // Initialize the HTML surface and create the browser instance
  171. m_SteamAPIContext.Init();
  172. if ( m_SteamAPIContext.SteamHTMLSurface() )
  173. {
  174. m_SteamAPIContext.SteamHTMLSurface()->Init();
  175. SteamAPICall_t hSteamAPICall = m_SteamAPIContext.SteamHTMLSurface()->CreateBrowser( surface()->GetWebkitHTMLUserAgentString(), "::-webkit-scrollbar { background-color: #000000; } ::-webkit-scrollbar-track { border: 1px solid #7f7f7f; background: #000000; } ::-webkit-scrollbar-thumb{ border: 1px solid #7f7f7f; background: #000000; } ::-webkit-scrollbar-button{ border: 1px solid #7f7f7f; background: #000000; }" );
  176. m_SteamCallResultBrowserReady.Set( hSteamAPICall, this, &HTML::OnBrowserReady );
  177. }
  178. else
  179. {
  180. Warning( "Unable to access SteamHTMLSurface" );
  181. }
  182. m_iScrollBorderX=m_iScrollBorderY=0;
  183. // webkit handling the scrollbars
  184. m_bScrollBarEnabled = false;
  185. m_bContextMenuEnabled = true;
  186. m_bNewWindowsOnly = false;
  187. m_iMouseX = m_iMouseY = 0;
  188. m_iDragStartX = m_iDragStartY = 0;
  189. m_nViewSourceAllowedIndex = -1;
  190. m_iWideLastHTMLSize = m_iTalLastHTMLSize = 0;
  191. _hbar = new ScrollBar(this, "HorizScrollBar", false);
  192. _hbar->SetVisible(false);
  193. _hbar->AddActionSignalTarget(this);
  194. _vbar = new ScrollBar(this, "VertScrollBar", true);
  195. _vbar->SetVisible(false);
  196. _vbar->AddActionSignalTarget(this);
  197. m_pFindBar = new HTML::CHTMLFindBar( this );
  198. m_pFindBar->SetZPos( 2 );
  199. m_pFindBar->SetVisible( false );
  200. // TODO::STYLE
  201. //m_pFindBar->SetStyle( "html-findbar" );
  202. m_pContextMenu = new Menu( this, "contextmenu" );
  203. m_pContextMenu->AddMenuItem( "#vgui_HTMLBack", new KeyValues( "Command", "command", "back" ), this );
  204. m_pContextMenu->AddMenuItem( "#vgui_HTMLForward", new KeyValues( "Command", "command", "forward" ), this );
  205. m_pContextMenu->AddMenuItem( "#vgui_HTMLReload", new KeyValues( "Command", "command", "reload" ), this );
  206. m_pContextMenu->AddMenuItem( "#vgui_HTMLStop", new KeyValues( "Command", "command", "stop" ), this );
  207. m_pContextMenu->AddSeparator();
  208. m_pContextMenu->AddMenuItem( "#vgui_HTMLCopyUrl", new KeyValues( "Command", "command", "copyurl" ), this );
  209. m_iCopyLinkMenuItemID = m_pContextMenu->AddMenuItem( "#vgui_HTMLCopyLink", new KeyValues( "Command", "command", "copylink" ), this );
  210. m_pContextMenu->AddMenuItem( "#TextEntry_Copy", new KeyValues( "Command", "command", "copy" ), this );
  211. m_pContextMenu->AddMenuItem( "#TextEntry_Paste", new KeyValues( "Command", "command", "paste" ), this );
  212. m_pContextMenu->AddSeparator();
  213. m_nViewSourceAllowedIndex = m_pContextMenu->AddMenuItem( "#vgui_HTMLViewSource", new KeyValues( "Command", "command", "viewsource" ), this );
  214. }
  215. //-----------------------------------------------------------------------------
  216. // Purpose: Destructor
  217. //-----------------------------------------------------------------------------
  218. HTML::~HTML()
  219. {
  220. m_pContextMenu->MarkForDeletion();
  221. if ( m_SteamAPIContext.SteamHTMLSurface() )
  222. {
  223. m_SteamAPIContext.SteamHTMLSurface()->RemoveBrowser ( m_unBrowserHandle );
  224. }
  225. FOR_EACH_VEC( m_vecHCursor, i )
  226. {
  227. // BR FIXME!
  228. // surface()->DeleteCursor( m_vecHCursor[i].m_Cursor );
  229. }
  230. m_vecHCursor.RemoveAll();
  231. }
  232. //-----------------------------------------------------------------------------
  233. // Purpose: Handle message to change our cursor
  234. //-----------------------------------------------------------------------------
  235. void HTML::OnSetCursorVGUI( int cursor )
  236. {
  237. SetCursor( (HCursor)cursor );
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose: sets up colors/fonts/borders
  241. //-----------------------------------------------------------------------------
  242. void HTML::ApplySchemeSettings(IScheme *pScheme)
  243. {
  244. BaseClass::ApplySchemeSettings(pScheme);
  245. BrowserResize();
  246. }
  247. //-----------------------------------------------------------------------------
  248. // Purpose: overrides panel class, paints a texture of the HTML window as a background
  249. //-----------------------------------------------------------------------------
  250. void HTML::Paint()
  251. {
  252. //VPROF_BUDGET( "HTML::Paint()", VPROF_BUDGETGROUP_OTHER_VGUI );
  253. BaseClass::Paint();
  254. if ( m_iHTMLTextureID != 0 )
  255. {
  256. surface()->DrawSetTexture( m_iHTMLTextureID );
  257. int tw = 0, tt = 0;
  258. surface()->DrawSetColor( Color( 255, 255, 255, 255 ) );
  259. int vbarInset = _vbar->IsVisible() ? _vbar->GetWide() : 0;
  260. GetSize( tw, tt );
  261. surface()->DrawTexturedRect( 0, 0, tw-vbarInset, tt );
  262. }
  263. // If we have scrollbars, we need to draw the bg color under them, since the browser
  264. // bitmap is a checkerboard under them, and they are transparent in the in-game client
  265. if ( m_iScrollBorderX > 0 || m_iScrollBorderY > 0 )
  266. {
  267. int w, h;
  268. GetSize( w, h );
  269. IBorder *border = GetBorder();
  270. int left = 0, top = 0, right = 0, bottom = 0;
  271. if ( border )
  272. {
  273. border->GetInset( left, top, right, bottom );
  274. }
  275. surface()->DrawSetColor( Color( 0, 0, 0, 255 ) );
  276. if ( m_iScrollBorderX )
  277. {
  278. surface()->DrawFilledRect( w - _vbar->GetWide(), top, w, h - bottom );
  279. }
  280. if ( m_iScrollBorderY )
  281. {
  282. surface()->DrawFilledRect( left, h-m_iScrollBorderY - bottom, w-m_iScrollBorderX - right, h );
  283. }
  284. }
  285. }
  286. //-----------------------------------------------------------------------------
  287. // Purpose: paint the combo box texture if we have one
  288. //-----------------------------------------------------------------------------
  289. void HTML::PaintComboBox()
  290. {
  291. BaseClass::Paint();
  292. if ( m_iComboBoxTextureID != 0 )
  293. {
  294. surface()->DrawSetTexture( m_iComboBoxTextureID );
  295. surface()->DrawSetColor( Color( 255, 255, 255, 255 ) );
  296. int tw = m_allocedComboBoxWidth;
  297. int tt = m_allocedComboBoxHeight;
  298. surface()->DrawTexturedRect( 0, 0, tw, tt );
  299. }
  300. }
  301. //-----------------------------------------------------------------------------
  302. // Purpose: causes a repaint when the layout changes
  303. //-----------------------------------------------------------------------------
  304. void HTML::PerformLayout()
  305. {
  306. BaseClass::PerformLayout();
  307. Repaint();
  308. int vbarInset = _vbar->IsVisible() ? _vbar->GetWide() : 0;
  309. int maxw = GetWide() - vbarInset;
  310. m_pInteriorPanel->SetBounds( 0, 0, maxw-32, GetTall() );
  311. IScheme *pClientScheme = vgui::scheme()->GetIScheme( vgui::scheme()->GetScheme( "ClientScheme" ) );
  312. int iSearchInsetY = 5;
  313. int iSearchInsetX = 5;
  314. int iSearchTall = 24;
  315. int iSearchWide = 150;
  316. const char *resourceString = pClientScheme->GetResourceString( "HTML.SearchInsetY");
  317. if ( resourceString )
  318. {
  319. iSearchInsetY = atoi(resourceString);
  320. }
  321. resourceString = pClientScheme->GetResourceString( "HTML.SearchInsetX");
  322. if ( resourceString )
  323. {
  324. iSearchInsetX = atoi(resourceString);
  325. }
  326. resourceString = pClientScheme->GetResourceString( "HTML.SearchTall");
  327. if ( resourceString )
  328. {
  329. iSearchTall = atoi(resourceString);
  330. }
  331. resourceString = pClientScheme->GetResourceString( "HTML.SearchWide");
  332. if ( resourceString )
  333. {
  334. iSearchWide = atoi(resourceString);
  335. }
  336. m_pFindBar->SetBounds( GetWide() - iSearchWide - iSearchInsetX - vbarInset, m_pFindBar->BIsHidden() ? -1*iSearchTall-5: iSearchInsetY, iSearchWide, iSearchTall );
  337. }
  338. //-----------------------------------------------------------------------------
  339. // Purpose: updates the underlying HTML surface widgets position
  340. //-----------------------------------------------------------------------------
  341. void HTML::OnMove()
  342. {
  343. BaseClass::OnMove();
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Purpose: calculates the need for and position of both horizontal and vertical scroll bars
  347. //-----------------------------------------------------------------------------
  348. void HTML::CalcScrollBars(int w, int h)
  349. {
  350. bool bScrollbarVisible = _vbar->IsVisible();
  351. if ( m_bScrollBarEnabled )
  352. {
  353. for ( int i = 0; i < 2; i++ )
  354. {
  355. int scrollx, scrolly, scrollwide, scrolltall;
  356. bool bVisible = false;
  357. if ( i==0 )
  358. {
  359. scrollx = m_scrollHorizontal.m_nX;
  360. scrolly = m_scrollHorizontal.m_nY;
  361. scrollwide = m_scrollHorizontal.m_nWide;
  362. scrolltall = m_scrollHorizontal.m_nTall;
  363. bVisible = m_scrollHorizontal.m_bVisible;
  364. // scrollbar positioning tweaks - should be moved into a resource file
  365. scrollwide += 14;
  366. scrolltall += 5;
  367. }
  368. else
  369. {
  370. scrollx = m_scrollVertical.m_nX;
  371. scrolly = m_scrollVertical.m_nY;
  372. scrollwide = m_scrollVertical.m_nWide;
  373. scrolltall = m_scrollVertical.m_nTall;
  374. bVisible = m_scrollVertical.m_bVisible;
  375. // scrollbar positioning tweaks - should be moved into a resource file
  376. //scrollx -= 3;
  377. if ( m_scrollHorizontal.m_bVisible )
  378. scrolltall += 16;
  379. else
  380. scrolltall -= 2;
  381. scrollwide += 5;
  382. }
  383. if ( bVisible && scrollwide && scrolltall )
  384. {
  385. int panelWide, panelTall;
  386. GetSize( panelWide, panelTall );
  387. ScrollBar *bar = _vbar;
  388. if ( i == 0 )
  389. bar = _hbar;
  390. if (!bar->IsVisible())
  391. {
  392. bar->SetVisible(true);
  393. // displayable area has changed, need to force an update
  394. PostMessage(this, new KeyValues("OnSliderMoved"), 0.02f);
  395. }
  396. int rangeWindow = panelTall - scrollwide;
  397. if ( i==0 )
  398. rangeWindow = panelWide - scrolltall;
  399. int range = m_scrollVertical.m_nMax + m_scrollVertical.m_nTall;
  400. if ( i == 0 )
  401. range = m_scrollHorizontal.m_nMax + m_scrollVertical.m_nWide;
  402. int curValue = m_scrollVertical.m_nScroll;
  403. if ( i == 0 )
  404. curValue = m_scrollHorizontal.m_nScroll;
  405. bar->SetEnabled(false);
  406. bar->SetRangeWindow( rangeWindow );
  407. bar->SetRange( 0, range ); // we want the range [0.. (img_h - h)], but the scrollbar actually returns [0..(range-rangeWindow)] so make sure -h gets deducted from the max range value
  408. bar->SetButtonPressedScrollValue( 5 );
  409. if ( curValue > ( bar->GetValue() + 5 ) || curValue < (bar->GetValue() - 5 ) )
  410. bar->SetValue( curValue );
  411. if ( i == 0 )
  412. {
  413. bar->SetPos( 0, h - scrolltall - 1 );
  414. bar->SetWide( scrollwide );
  415. bar->SetTall( scrolltall );
  416. }
  417. else
  418. {
  419. bar->SetPos( w - scrollwide, 0 );
  420. bar->SetTall( scrolltall );
  421. bar->SetWide( scrollwide );
  422. }
  423. if ( i == 0 )
  424. m_iScrollBorderY=scrolltall;
  425. else
  426. m_iScrollBorderX=scrollwide;
  427. }
  428. else
  429. {
  430. if ( i == 0 )
  431. {
  432. m_iScrollBorderY=0;
  433. _hbar->SetVisible( false );
  434. }
  435. else
  436. {
  437. m_iScrollBorderX=0;
  438. _vbar->SetVisible( false );
  439. }
  440. }
  441. }
  442. }
  443. else
  444. {
  445. m_iScrollBorderX = 0;
  446. m_iScrollBorderY=0;
  447. _vbar->SetVisible(false);
  448. _hbar->SetVisible(false);
  449. }
  450. if ( bScrollbarVisible != _vbar->IsVisible() )
  451. InvalidateLayout();
  452. }
  453. //-----------------------------------------------------------------------------
  454. // Purpose: opens the URL, will accept any URL that IE accepts
  455. //-----------------------------------------------------------------------------
  456. void HTML::OpenURL(const char *URL, const char *postData )
  457. {
  458. PostURL( URL, postData );
  459. }
  460. //-----------------------------------------------------------------------------
  461. // Purpose: opens the URL, will accept any URL that IE accepts
  462. //-----------------------------------------------------------------------------
  463. void HTML::PostURL(const char *URL, const char *pchPostData )
  464. {
  465. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  466. {
  467. m_sPendingURLLoad = URL;
  468. m_sPendingPostData = pchPostData;
  469. return;
  470. }
  471. if ( pchPostData && Q_strlen( pchPostData ) > 0 )
  472. m_SteamAPIContext.SteamHTMLSurface()->LoadURL( m_unBrowserHandle, URL, pchPostData );
  473. else
  474. m_SteamAPIContext.SteamHTMLSurface()->LoadURL( m_unBrowserHandle, URL, NULL );
  475. }
  476. //-----------------------------------------------------------------------------
  477. // Purpose: opens the URL, will accept any URL that IE accepts
  478. //-----------------------------------------------------------------------------
  479. bool HTML::StopLoading()
  480. {
  481. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  482. return false;
  483. m_SteamAPIContext.SteamHTMLSurface()->StopLoad( m_unBrowserHandle );
  484. return true;
  485. }
  486. //-----------------------------------------------------------------------------
  487. // Purpose: refreshes the current page
  488. //-----------------------------------------------------------------------------
  489. bool HTML::Refresh()
  490. {
  491. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  492. return false;
  493. m_SteamAPIContext.SteamHTMLSurface()->Reload( m_unBrowserHandle );
  494. return true;
  495. }
  496. //-----------------------------------------------------------------------------
  497. // Purpose: Tells the browser control to go back
  498. //-----------------------------------------------------------------------------
  499. void HTML::GoBack()
  500. {
  501. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  502. return;
  503. m_SteamAPIContext.SteamHTMLSurface()->GoBack( m_unBrowserHandle );
  504. }
  505. //-----------------------------------------------------------------------------
  506. // Purpose: Tells the browser control to go forward
  507. //-----------------------------------------------------------------------------
  508. void HTML::GoForward()
  509. {
  510. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  511. return;
  512. m_SteamAPIContext.SteamHTMLSurface()->GoForward( m_unBrowserHandle );
  513. }
  514. //-----------------------------------------------------------------------------
  515. // Purpose: Checks if the browser can go back further
  516. //-----------------------------------------------------------------------------
  517. bool HTML::BCanGoBack()
  518. {
  519. return m_bCanGoBack;
  520. }
  521. //-----------------------------------------------------------------------------
  522. // Purpose: Checks if the browser can go forward further
  523. //-----------------------------------------------------------------------------
  524. bool HTML::BCanGoFoward()
  525. {
  526. return m_bCanGoForward;
  527. }
  528. //-----------------------------------------------------------------------------
  529. // Purpose: handle resizing
  530. //-----------------------------------------------------------------------------
  531. void HTML::OnSizeChanged( int wide,int tall )
  532. {
  533. BaseClass::OnSizeChanged(wide,tall);
  534. UpdateSizeAndScrollBars();
  535. BrowserResize();
  536. }
  537. //-----------------------------------------------------------------------------
  538. // Purpose: Run javascript in the page
  539. //-----------------------------------------------------------------------------
  540. void HTML::RunJavascript( const char *pchScript )
  541. {
  542. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  543. return;
  544. m_SteamAPIContext.SteamHTMLSurface()->ExecuteJavascript( m_unBrowserHandle, pchScript );
  545. }
  546. //-----------------------------------------------------------------------------
  547. // Purpose: helper to convert UI mouse codes to CEF ones
  548. //-----------------------------------------------------------------------------
  549. int HTML::ConvertMouseCodeToCEFCode( MouseCode code )
  550. {
  551. switch ( code )
  552. {
  553. default:
  554. case MOUSE_LEFT:
  555. return ISteamHTMLSurface::eHTMLMouseButton_Left;
  556. case MOUSE_RIGHT:
  557. return ISteamHTMLSurface::eHTMLMouseButton_Right;
  558. case MOUSE_MIDDLE:
  559. return ISteamHTMLSurface::eHTMLMouseButton_Middle;
  560. }
  561. }
  562. //-----------------------------------------------------------------------------
  563. // Purpose: passes mouse clicks to the control
  564. //-----------------------------------------------------------------------------
  565. void HTML::OnMousePressed( MouseCode code )
  566. {
  567. m_sDragURL = NULL;
  568. // mouse4 = back button
  569. if ( code == MOUSE_4 )
  570. {
  571. PostActionSignal( new KeyValues( "HTMLBackRequested" ) );
  572. return;
  573. }
  574. if ( code == MOUSE_5 )
  575. {
  576. PostActionSignal( new KeyValues( "HTMLForwardRequested" ) );
  577. return;
  578. }
  579. if ( code == MOUSE_RIGHT && m_bContextMenuEnabled )
  580. {
  581. // Disable right click menu until it looks better/works!
  582. // GetLinkAtPosition( m_iMouseX, m_iMouseY );
  583. // Menu::PlaceContextMenu( this, m_pContextMenu );
  584. // return;
  585. }
  586. // ask for the focus to come to this window
  587. RequestFocus();
  588. // now tell the browser about the click
  589. // ignore right clicks if context menu has been disabled
  590. if ( code != MOUSE_RIGHT )
  591. {
  592. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  593. return;
  594. m_SteamAPIContext.SteamHTMLSurface()->MouseDown( m_unBrowserHandle, (ISteamHTMLSurface::EHTMLMouseButton)ConvertMouseCodeToCEFCode( code ) );
  595. }
  596. if ( code == MOUSE_LEFT )
  597. {
  598. input()->GetCursorPos( m_iDragStartX, m_iDragStartY );
  599. int htmlx, htmly;
  600. ipanel()->GetAbsPos( GetVPanel(), htmlx, htmly );
  601. GetLinkAtPosition( m_iDragStartX - htmlx, m_iDragStartY - htmly );
  602. m_bRequestingDragURL = true;
  603. // make sure we get notified when the mouse gets released
  604. if ( !m_sDragURL.IsEmpty() )
  605. {
  606. input()->SetMouseCapture( GetVPanel() );
  607. }
  608. }
  609. }
  610. //-----------------------------------------------------------------------------
  611. // Purpose: passes mouse up events
  612. //-----------------------------------------------------------------------------
  613. void HTML::OnMouseReleased( MouseCode code )
  614. {
  615. if ( code == MOUSE_LEFT )
  616. {
  617. input()->SetMouseCapture( NULL );
  618. input()->SetCursorOveride( 0 );
  619. if ( !m_sDragURL.IsEmpty() && input()->GetMouseOver() != GetVPanel() && input()->GetMouseOver() != NULL )
  620. {
  621. // post the text as a drag drop to the target panel
  622. KeyValuesAD kv( "DragDrop" );
  623. if ( ipanel()->RequestInfo( input()->GetMouseOver(), kv )
  624. && kv->GetPtr( "AcceptPanel" ) != NULL )
  625. {
  626. VPANEL vpanel = (VPANEL)kv->GetPtr( "AcceptPanel" );
  627. ivgui()->PostMessage( vpanel, new KeyValues( "DragDrop", "text", m_sDragURL.Get() ), GetVPanel() );
  628. }
  629. }
  630. m_sDragURL = NULL;
  631. }
  632. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  633. return;
  634. m_SteamAPIContext.SteamHTMLSurface()->MouseUp( m_unBrowserHandle, (ISteamHTMLSurface::EHTMLMouseButton)ConvertMouseCodeToCEFCode( code ) );
  635. }
  636. //-----------------------------------------------------------------------------
  637. // Purpose: keeps track of where the cursor is
  638. //-----------------------------------------------------------------------------
  639. void HTML::OnCursorMoved(int x,int y)
  640. {
  641. // Only do this when we are over the current panel
  642. if ( vgui::input()->GetMouseOver() == GetVPanel() )
  643. {
  644. m_iMouseX = x;
  645. m_iMouseY = y;
  646. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  647. return;
  648. m_SteamAPIContext.SteamHTMLSurface()->MouseMove( m_unBrowserHandle, m_iMouseX, m_iMouseY );
  649. }
  650. else if ( !m_sDragURL.IsEmpty() )
  651. {
  652. if ( input()->GetMouseOver() == NULL )
  653. {
  654. // we're not over any vgui window, switch to the OS implementation of drag/drop
  655. // BR FIXME
  656. // surface()->StartDragDropText( m_sDragURL );
  657. m_sDragURL = NULL;
  658. }
  659. }
  660. if ( !m_sDragURL.IsEmpty() && !input()->GetCursorOveride() )
  661. {
  662. // if we've dragged far enough (in global coordinates), set to use the drag cursor
  663. int gx, gy;
  664. input()->GetCursorPos( gx, gy );
  665. if ( abs(m_iDragStartX-gx) + abs(m_iDragStartY-gy) > 3 )
  666. {
  667. // input()->SetCursorOveride( dc_alias );
  668. }
  669. }
  670. }
  671. //-----------------------------------------------------------------------------
  672. // Purpose: passes double click events to the browser
  673. //-----------------------------------------------------------------------------
  674. void HTML::OnMouseDoublePressed( MouseCode code )
  675. {
  676. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  677. return;
  678. m_SteamAPIContext.SteamHTMLSurface()->MouseDoubleClick( m_unBrowserHandle, (ISteamHTMLSurface::EHTMLMouseButton)ConvertMouseCodeToCEFCode( code ) );
  679. }
  680. //-----------------------------------------------------------------------------
  681. // Purpose: return the bitmask of any modifier keys that are currently down
  682. //-----------------------------------------------------------------------------
  683. int HTML::TranslateKeyModifiers()
  684. {
  685. bool bControl = false;
  686. bool bAlt = false;
  687. bool bShift = false;
  688. if ( vgui::input()->IsKeyDown( KEY_LCONTROL ) || vgui::input()->IsKeyDown( KEY_RCONTROL ) )
  689. bControl = true;
  690. if ( vgui::input()->IsKeyDown( KEY_LALT ) || vgui::input()->IsKeyDown( KEY_RALT ) )
  691. bAlt = true;
  692. if ( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) )
  693. bShift = true;
  694. #ifdef OSX
  695. // for now pipe through the cmd-key to be like the control key so we get copy/paste
  696. if ( vgui::input()->IsKeyDown( KEY_LWIN ) || vgui::input()->IsKeyDown( KEY_RWIN ) )
  697. bControl = true;
  698. #endif
  699. int nModifierCodes = 0;
  700. if ( bControl )
  701. nModifierCodes |= ISteamHTMLSurface::k_eHTMLKeyModifier_CtrlDown;
  702. if ( bAlt )
  703. nModifierCodes |= ISteamHTMLSurface::k_eHTMLKeyModifier_AltDown;
  704. if ( bShift )
  705. nModifierCodes |= ISteamHTMLSurface::k_eHTMLKeyModifier_ShiftDown;
  706. return (ISteamHTMLSurface::EHTMLKeyModifiers)nModifierCodes;
  707. }
  708. //-----------------------------------------------------------------------------
  709. // Purpose: passes key presses to the browser (we don't current do this)
  710. //-----------------------------------------------------------------------------
  711. void HTML::OnKeyTyped(wchar_t unichar)
  712. {
  713. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  714. return;
  715. m_SteamAPIContext.SteamHTMLSurface()->KeyChar( m_unBrowserHandle, unichar, (ISteamHTMLSurface::EHTMLKeyModifiers)TranslateKeyModifiers() );
  716. }
  717. //-----------------------------------------------------------------------------
  718. // Purpose: pop up the find dialog
  719. //-----------------------------------------------------------------------------
  720. void HTML::ShowFindDialog()
  721. {
  722. IScheme *pClientScheme = vgui::scheme()->GetIScheme( vgui::scheme()->GetScheme( "ClientScheme" ) );
  723. if ( !pClientScheme )
  724. return;
  725. m_pFindBar->SetVisible( true );
  726. m_pFindBar->RequestFocus();
  727. m_pFindBar->SetText( "" );
  728. m_pFindBar->HideCountLabel();
  729. m_pFindBar->SetHidden( false );
  730. int x = 0, y = 0, h = 0, w = 0;
  731. m_pFindBar->GetBounds( x, y, w, h );
  732. m_pFindBar->SetPos( x, -1*h );
  733. int iSearchInsetY = 0;
  734. const char *resourceString = pClientScheme->GetResourceString( "HTML.SearchInsetY");
  735. if ( resourceString )
  736. {
  737. iSearchInsetY = atoi(resourceString);
  738. }
  739. float flAnimationTime = 0.0f;
  740. resourceString = pClientScheme->GetResourceString( "HTML.SearchAnimationTime");
  741. if ( resourceString )
  742. {
  743. flAnimationTime = atof(resourceString);
  744. }
  745. GetAnimationController()->RunAnimationCommand( m_pFindBar, "ypos", iSearchInsetY, 0.0f, flAnimationTime, AnimationController::INTERPOLATOR_LINEAR );
  746. }
  747. //-----------------------------------------------------------------------------
  748. // Purpose: hide the find dialog
  749. //-----------------------------------------------------------------------------
  750. void HTML::HideFindDialog()
  751. {
  752. IScheme *pClientScheme = vgui::scheme()->GetIScheme( vgui::scheme()->GetScheme( "ClientScheme" ) );
  753. if ( !pClientScheme )
  754. return;
  755. int x = 0, y = 0, h = 0, w = 0;
  756. m_pFindBar->GetBounds( x, y, w, h );
  757. float flAnimationTime = 0.0f;
  758. const char *resourceString = pClientScheme->GetResourceString( "HTML.SearchAnimationTime");
  759. if ( resourceString )
  760. {
  761. flAnimationTime = atof(resourceString);
  762. }
  763. GetAnimationController()->RunAnimationCommand( m_pFindBar, "ypos", -1*h-5, 0.0f, flAnimationTime, AnimationController::INTERPOLATOR_LINEAR );
  764. m_pFindBar->SetHidden( true );
  765. StopFind();
  766. }
  767. //-----------------------------------------------------------------------------
  768. // Purpose: is the find dialog visible?
  769. //-----------------------------------------------------------------------------
  770. bool HTML::FindDialogVisible()
  771. {
  772. return m_pFindBar->IsVisible() && !m_pFindBar->BIsHidden();
  773. }
  774. //-----------------------------------------------------------------------------
  775. // Purpose: return the bitmask of any modifier keys that are currently down
  776. //-----------------------------------------------------------------------------
  777. int GetKeyModifiers()
  778. {
  779. // Any time a key is pressed reset modifier list as well
  780. int nModifierCodes = 0;
  781. if( vgui::input()->IsKeyDown( KEY_LCONTROL ) || vgui::input()->IsKeyDown( KEY_RCONTROL ) )
  782. nModifierCodes |= ISteamHTMLSurface::k_eHTMLKeyModifier_CtrlDown;
  783. if( vgui::input()->IsKeyDown( KEY_LALT ) || vgui::input()->IsKeyDown( KEY_RALT ) )
  784. nModifierCodes |= ISteamHTMLSurface::k_eHTMLKeyModifier_AltDown;
  785. if( vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT ) )
  786. nModifierCodes |= ISteamHTMLSurface::k_eHTMLKeyModifier_ShiftDown;
  787. #ifdef OSX
  788. // for now pipe through the cmd-key to be like the control key so we get copy/paste
  789. if( vgui::input()->IsKeyDown( KEY_LWIN ) || vgui::input()->IsKeyDown( KEY_RWIN ) )
  790. nModifierCodes |= ISteamHTMLSurface::k_eHTMLKeyModifier_CtrlDown;
  791. #endif
  792. return nModifierCodes;
  793. }
  794. //-----------------------------------------------------------------------------
  795. // Purpose: passes key presses to the browser
  796. //-----------------------------------------------------------------------------
  797. void HTML::OnKeyCodeTyped(KeyCode code)
  798. {
  799. switch( code )
  800. {
  801. case KEY_PAGEDOWN:
  802. {
  803. int val = _vbar->GetValue();
  804. val += 200;
  805. _vbar->SetValue(val);
  806. break;
  807. }
  808. case KEY_PAGEUP:
  809. {
  810. int val = _vbar->GetValue();
  811. val -= 200;
  812. _vbar->SetValue(val);
  813. break;
  814. }
  815. case KEY_F5:
  816. {
  817. Refresh();
  818. break;
  819. }
  820. case KEY_F:
  821. {
  822. if ( (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) )
  823. || ( IsOSX() && ( input()->IsKeyDown(KEY_LWIN) || input()->IsKeyDown(KEY_RWIN) ) ) )
  824. {
  825. if ( !FindDialogVisible() )
  826. {
  827. ShowFindDialog();
  828. }
  829. else
  830. {
  831. HideFindDialog();
  832. }
  833. break;
  834. }
  835. }
  836. case KEY_ESCAPE:
  837. {
  838. if ( FindDialogVisible() )
  839. {
  840. HideFindDialog();
  841. break;
  842. }
  843. }
  844. case KEY_TAB:
  845. {
  846. if ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) )
  847. {
  848. // pass control-tab to parent (through baseclass)
  849. BaseClass::OnKeyTyped( code );
  850. return;
  851. }
  852. break;
  853. }
  854. }
  855. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  856. return;
  857. m_SteamAPIContext.SteamHTMLSurface()->KeyDown( m_unBrowserHandle, KeyCode_VGUIToVirtualKey( code ), (ISteamHTMLSurface::EHTMLKeyModifiers)GetKeyModifiers() );
  858. }
  859. //-----------------------------------------------------------------------------
  860. // Purpose:
  861. //-----------------------------------------------------------------------------
  862. void HTML::OnKeyCodeReleased(KeyCode code)
  863. {
  864. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  865. return;
  866. m_SteamAPIContext.SteamHTMLSurface()->KeyUp( m_unBrowserHandle, KeyCode_VGUIToVirtualKey( code ), (ISteamHTMLSurface::EHTMLKeyModifiers)GetKeyModifiers() );
  867. }
  868. //-----------------------------------------------------------------------------
  869. // Purpose: scrolls the vertical scroll bar on a web page
  870. //-----------------------------------------------------------------------------
  871. void HTML::OnMouseWheeled(int delta)
  872. {
  873. if ( _vbar )
  874. {
  875. int val = _vbar->GetValue();
  876. val -= (delta * 100.0/3.0 ); // 100 for every 3 lines matches chromes code
  877. _vbar->SetValue(val);
  878. }
  879. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  880. return;
  881. m_SteamAPIContext.SteamHTMLSurface()->MouseWheel( m_unBrowserHandle, delta );
  882. }
  883. //-----------------------------------------------------------------------------
  884. // Purpose: Inserts a custom URL handler
  885. //-----------------------------------------------------------------------------
  886. void HTML::AddCustomURLHandler(const char *customProtocolName, vgui::Panel *target)
  887. {
  888. int index = m_CustomURLHandlers.AddToTail();
  889. m_CustomURLHandlers[index].hPanel = target;
  890. Q_strncpy(m_CustomURLHandlers[index].url, customProtocolName, sizeof(m_CustomURLHandlers[index].url));
  891. }
  892. //-----------------------------------------------------------------------------
  893. // Purpose: shared code for sizing the HTML surface window
  894. //-----------------------------------------------------------------------------
  895. void HTML::BrowserResize()
  896. {
  897. int w,h;
  898. GetSize( w, h );
  899. int right = 0, bottom = 0;
  900. // TODO::STYLE
  901. /*
  902. IAppearance *pAppearance = GetAppearance();
  903. int left = 0, top = 0;
  904. if ( pAppearance )
  905. {
  906. pAppearance->GetInset( left, top, right, bottom );
  907. }
  908. */
  909. if ( ( m_unBrowserHandle != INVALID_HTMLBROWSER ) && ( m_iWideLastHTMLSize != ( w - m_iScrollBorderX - right ) || m_iTalLastHTMLSize != ( h - m_iScrollBorderY - bottom ) ) )
  910. {
  911. m_iWideLastHTMLSize = w - m_iScrollBorderX - right;
  912. m_iTalLastHTMLSize = h - m_iScrollBorderY - bottom;
  913. if ( m_iTalLastHTMLSize <= 0 )
  914. {
  915. SetTall( 64 );
  916. m_iTalLastHTMLSize = 64 - bottom;
  917. }
  918. m_SteamAPIContext.SteamHTMLSurface()->SetSize( m_unBrowserHandle, m_iWideLastHTMLSize, m_iTalLastHTMLSize );
  919. // webkit forgets the scroll offset when you resize (it saves the scroll in a DC and a resize throws away the DC)
  920. // so just tell it after the resize
  921. int scrollV = _vbar->GetValue();
  922. int scrollH = _hbar->GetValue();
  923. m_SteamAPIContext.SteamHTMLSurface()->SetHorizontalScroll( m_unBrowserHandle, scrollH );
  924. m_SteamAPIContext.SteamHTMLSurface()->SetVerticalScroll( m_unBrowserHandle, scrollV );
  925. }
  926. }
  927. //-----------------------------------------------------------------------------
  928. // Purpose: when a slider moves causes the IE images to re-render itself
  929. //-----------------------------------------------------------------------------
  930. void HTML::OnSliderMoved()
  931. {
  932. if(_hbar->IsVisible())
  933. {
  934. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  935. return;
  936. int scrollX =_hbar->GetValue();
  937. m_SteamAPIContext.SteamHTMLSurface()->SetHorizontalScroll( m_unBrowserHandle, scrollX );
  938. }
  939. if(_vbar->IsVisible())
  940. {
  941. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  942. return;
  943. int scrollY=_vbar->GetValue();
  944. m_SteamAPIContext.SteamHTMLSurface()->SetVerticalScroll( m_unBrowserHandle, scrollY );
  945. }
  946. // post a message that the slider has moved
  947. PostActionSignal( new KeyValues( "HTMLSliderMoved" ) );
  948. }
  949. //-----------------------------------------------------------------------------
  950. // Purpose: data accessor
  951. //-----------------------------------------------------------------------------
  952. bool HTML::IsScrolledToBottom()
  953. {
  954. if ( !_vbar->IsVisible() )
  955. return true;
  956. return m_scrollVertical.m_nScroll >= m_scrollVertical.m_nMax;
  957. }
  958. //-----------------------------------------------------------------------------
  959. // Purpose: data accessor
  960. //-----------------------------------------------------------------------------
  961. bool HTML::IsScrollbarVisible()
  962. {
  963. return _vbar->IsVisible();
  964. }
  965. //-----------------------------------------------------------------------------
  966. // Purpose: data accessor
  967. //-----------------------------------------------------------------------------
  968. void HTML::SetScrollbarsEnabled(bool state)
  969. {
  970. m_bScrollBarEnabled = state;
  971. }
  972. //-----------------------------------------------------------------------------
  973. // Purpose: data accessor
  974. //-----------------------------------------------------------------------------
  975. void HTML::SetContextMenuEnabled(bool state)
  976. {
  977. m_bContextMenuEnabled = state;
  978. }
  979. //-----------------------------------------------------------------------------
  980. // Purpose: data accessor
  981. //-----------------------------------------------------------------------------
  982. void HTML::SetViewSourceEnabled(bool state)
  983. {
  984. m_pContextMenu->SetItemVisible( m_nViewSourceAllowedIndex, state );
  985. }
  986. //-----------------------------------------------------------------------------
  987. // Purpose: data accessor
  988. //-----------------------------------------------------------------------------
  989. void HTML::NewWindowsOnly( bool state )
  990. {
  991. m_bNewWindowsOnly = state;
  992. }
  993. //-----------------------------------------------------------------------------
  994. // Purpose: called when our children have finished painting
  995. //-----------------------------------------------------------------------------
  996. void HTML::PostChildPaint()
  997. {
  998. BaseClass::PostChildPaint();
  999. // TODO::STYLE
  1000. //m_pInteriorPanel->SetPaintAppearanceEnabled( true ); // turn painting back on so the IE hwnd can render this border
  1001. }
  1002. //-----------------------------------------------------------------------------
  1003. // Purpose: Adds a custom header to all requests
  1004. //-----------------------------------------------------------------------------
  1005. void HTML::AddHeader( const char *pchHeader, const char *pchValue )
  1006. {
  1007. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1008. return;
  1009. m_SteamAPIContext.SteamHTMLSurface()->AddHeader( m_unBrowserHandle, pchHeader, pchValue );
  1010. }
  1011. //-----------------------------------------------------------------------------
  1012. // Purpose:
  1013. //-----------------------------------------------------------------------------
  1014. void HTML::OnSetFocus()
  1015. {
  1016. BaseClass::OnSetFocus();
  1017. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1018. return;
  1019. m_SteamAPIContext.SteamHTMLSurface()->SetKeyFocus( m_unBrowserHandle, true );
  1020. }
  1021. //-----------------------------------------------------------------------------
  1022. // Purpose:
  1023. //-----------------------------------------------------------------------------
  1024. void HTML::OnKillFocus()
  1025. {
  1026. BaseClass::OnKillFocus();
  1027. // Don't clear the actual html focus if a context menu is what took focus
  1028. if ( m_pContextMenu->HasFocus() )
  1029. return;
  1030. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1031. return;
  1032. m_SteamAPIContext.SteamHTMLSurface()->SetKeyFocus( m_unBrowserHandle, false );
  1033. }
  1034. //-----------------------------------------------------------------------------
  1035. // Purpose: webkit is telling us to use this cursor type
  1036. //-----------------------------------------------------------------------------
  1037. void HTML::OnCommand( const char *pchCommand )
  1038. {
  1039. if ( !Q_stricmp( pchCommand, "back" ) )
  1040. {
  1041. PostActionSignal( new KeyValues( "HTMLBackRequested" ) );
  1042. }
  1043. else if ( !Q_stricmp( pchCommand, "forward" ) )
  1044. {
  1045. PostActionSignal( new KeyValues( "HTMLForwardRequested" ) );
  1046. }
  1047. else if ( !Q_stricmp( pchCommand, "reload" ) )
  1048. {
  1049. Refresh();
  1050. }
  1051. else if ( !Q_stricmp( pchCommand, "stop" ) )
  1052. {
  1053. StopLoading();
  1054. }
  1055. else if ( !Q_stricmp( pchCommand, "viewsource" ) )
  1056. {
  1057. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1058. return;
  1059. m_SteamAPIContext.SteamHTMLSurface()->ViewSource( m_unBrowserHandle );
  1060. }
  1061. else if ( !Q_stricmp( pchCommand, "copy" ) )
  1062. {
  1063. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1064. return;
  1065. m_SteamAPIContext.SteamHTMLSurface()->CopyToClipboard( m_unBrowserHandle );
  1066. }
  1067. else if ( !Q_stricmp( pchCommand, "paste" ) )
  1068. {
  1069. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1070. return;
  1071. m_SteamAPIContext.SteamHTMLSurface()->PasteFromClipboard( m_unBrowserHandle );
  1072. }
  1073. else if ( !Q_stricmp( pchCommand, "copyurl" ) )
  1074. {
  1075. system()->SetClipboardText( m_sCurrentURL, m_sCurrentURL.Length() );
  1076. }
  1077. else if ( !Q_stricmp( pchCommand, "copylink" ) )
  1078. {
  1079. int x, y;
  1080. m_pContextMenu->GetPos( x, y );
  1081. int htmlx, htmly;
  1082. ipanel()->GetAbsPos( GetVPanel(), htmlx, htmly );
  1083. m_bRequestingCopyLink = true;
  1084. GetLinkAtPosition( x - htmlx, y - htmly );
  1085. }
  1086. else
  1087. BaseClass::OnCommand( pchCommand );
  1088. }
  1089. //-----------------------------------------------------------------------------
  1090. // Purpose: the control wants us to ask the user what file to load
  1091. //-----------------------------------------------------------------------------
  1092. void HTML::OnFileSelected( const char *pchSelectedFile )
  1093. {
  1094. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1095. return;
  1096. m_SteamAPIContext.SteamHTMLSurface()->FileLoadDialogResponse( m_unBrowserHandle, &pchSelectedFile );
  1097. m_hFileOpenDialog->Close();
  1098. }
  1099. //-----------------------------------------------------------------------------
  1100. // Purpose: called when the user dismissed the file dialog with no selection
  1101. //-----------------------------------------------------------------------------
  1102. void HTML::OnFileSelectionCancelled()
  1103. {
  1104. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1105. return;
  1106. m_SteamAPIContext.SteamHTMLSurface()->FileLoadDialogResponse( m_unBrowserHandle, NULL );
  1107. m_hFileOpenDialog->Close();
  1108. }
  1109. //-----------------------------------------------------------------------------
  1110. // Purpose: find any text on the html page with this sub string
  1111. //-----------------------------------------------------------------------------
  1112. void HTML::Find( const char *pchSubStr )
  1113. {
  1114. m_bInFind = false;
  1115. if ( m_sLastSearchString == pchSubStr ) // same string as last time, lets fine next
  1116. m_bInFind = true;
  1117. m_sLastSearchString = pchSubStr;
  1118. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1119. return;
  1120. m_SteamAPIContext.SteamHTMLSurface()->Find( m_unBrowserHandle, pchSubStr, m_bInFind, false );
  1121. }
  1122. //-----------------------------------------------------------------------------
  1123. // Purpose: find any text on the html page with this sub string
  1124. //-----------------------------------------------------------------------------
  1125. void HTML::FindPrevious()
  1126. {
  1127. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1128. return;
  1129. m_SteamAPIContext.SteamHTMLSurface()->Find( m_unBrowserHandle, m_sLastSearchString, m_bInFind, true );
  1130. }
  1131. //-----------------------------------------------------------------------------
  1132. // Purpose: find any text on the html page with this sub string
  1133. //-----------------------------------------------------------------------------
  1134. void HTML::FindNext()
  1135. {
  1136. Find( m_sLastSearchString );
  1137. }
  1138. //-----------------------------------------------------------------------------
  1139. // Purpose: stop an outstanding find request
  1140. //-----------------------------------------------------------------------------
  1141. void HTML::StopFind( )
  1142. {
  1143. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1144. return;
  1145. m_SteamAPIContext.SteamHTMLSurface()->StopFind( m_unBrowserHandle );
  1146. m_bInFind = false;
  1147. }
  1148. //-----------------------------------------------------------------------------
  1149. // Purpose: input handler
  1150. //-----------------------------------------------------------------------------
  1151. void HTML::OnEditNewLine( Panel *pPanel )
  1152. {
  1153. OnTextChanged( pPanel );
  1154. }
  1155. //-----------------------h------------------------------------------------------
  1156. // Purpose: input handler
  1157. //-----------------------------------------------------------------------------
  1158. void HTML::OnTextChanged( Panel *pPanel )
  1159. {
  1160. char rgchText[2048];
  1161. m_pFindBar->GetText( rgchText, sizeof( rgchText ) );
  1162. Find( rgchText );
  1163. }
  1164. //-----------------------------------------------------------------------------
  1165. // Purpose: helper class for the find bar
  1166. //-----------------------------------------------------------------------------
  1167. HTML::CHTMLFindBar::CHTMLFindBar( HTML *parent ) : EditablePanel( parent, "FindBar" )
  1168. {
  1169. m_pParent = parent;
  1170. m_bHidden = false;
  1171. m_pFindBar = new TextEntry( this, "FindEntry" );
  1172. m_pFindBar->AddActionSignalTarget( parent );
  1173. m_pFindBar->SendNewLine( true );
  1174. m_pFindCountLabel = new Label( this, "FindCount", "" );
  1175. m_pFindCountLabel->SetVisible( false );
  1176. LoadControlSettings( "resource/layout/htmlfindbar.layout" );
  1177. }
  1178. //-----------------------------------------------------------------------------
  1179. // Purpose: button input into the find bar
  1180. //-----------------------------------------------------------------------------
  1181. void HTML::CHTMLFindBar::OnCommand( const char *pchCmd )
  1182. {
  1183. if ( !Q_stricmp( pchCmd, "close" ) )
  1184. {
  1185. m_pParent->HideFindDialog();
  1186. }
  1187. else if ( !Q_stricmp( pchCmd, "previous" ) )
  1188. {
  1189. m_pParent->FindPrevious();
  1190. }
  1191. else if ( !Q_stricmp( pchCmd, "next" ) )
  1192. {
  1193. m_pParent->FindNext();
  1194. }
  1195. else
  1196. BaseClass::OnCommand( pchCmd );
  1197. }
  1198. //-----------------------------------------------------------------------------
  1199. // Purpose: browser is fully created and ready to use
  1200. //-----------------------------------------------------------------------------
  1201. void HTML::OnBrowserReady( HTML_BrowserReady_t *pBrowserReady, bool bIOFailure )
  1202. {
  1203. m_unBrowserHandle = pBrowserReady->unBrowserHandle;
  1204. BrowserResize();
  1205. // Only post the pending URL if we have set our OAuth token
  1206. if ( !m_sPendingURLLoad.IsEmpty() )
  1207. {
  1208. PostURL( m_sPendingURLLoad, m_sPendingPostData );
  1209. m_sPendingURLLoad.Clear();
  1210. }
  1211. // Remove browser corresponding to BrowserPopupHTMLWindow (cf BrowserPopupHTMLWindow)
  1212. if ( m_SteamAPIContext.SteamHTMLSurface() && ( m_unBrowserHandleToDelete != INVALID_HTMLBROWSER ) )
  1213. {
  1214. Assert( m_unBrowserHandleToDelete != m_unBrowserHandle );
  1215. m_SteamAPIContext.SteamHTMLSurface()->RemoveBrowser( m_unBrowserHandleToDelete );
  1216. m_unBrowserHandleToDelete = INVALID_HTMLBROWSER;
  1217. }
  1218. }
  1219. //-----------------------------------------------------------------------------
  1220. // Purpose: we have a new texture to update
  1221. //-----------------------------------------------------------------------------
  1222. void HTML::BrowserNeedsPaint( HTML_NeedsPaint_t *pCmd )
  1223. {
  1224. CHECK_BROWSER_HANDLE();
  1225. if ( !pCmd->pBGRA )
  1226. return;
  1227. int tw = 0, tt = 0;
  1228. if ( m_iHTMLTextureID != 0 )
  1229. {
  1230. tw = m_allocedTextureWidth;
  1231. tt = m_allocedTextureHeight;
  1232. }
  1233. // update the vgui texture
  1234. if ( m_iHTMLTextureID == 0 || tw != (int)pCmd->unWide || tt != (int)pCmd->unTall )
  1235. {
  1236. if ( m_iHTMLTextureID != 0 )
  1237. surface()->DeleteTextureByID( m_iHTMLTextureID );
  1238. // if the dimensions changed we also need to re-create the texture ID to support the overlay properly (it won't resize a texture on the fly, this is the only control that needs
  1239. // to so lets have a tiny bit more code here to support that)
  1240. m_iHTMLTextureID = surface()->CreateNewTextureID( true );
  1241. surface()->DrawSetTextureRGBAEx( m_iHTMLTextureID, (const unsigned char *)pCmd->pBGRA, pCmd->unWide, pCmd->unTall, IMAGE_FORMAT_BGRA8888 );// BR FIXME - this call seems to shift by some number of pixels?
  1242. m_allocedTextureWidth = pCmd->unWide;
  1243. m_allocedTextureHeight = pCmd->unTall;
  1244. }
  1245. else if ( (int)pCmd->unUpdateWide > 0 && (int)pCmd->unUpdateTall > 0 )
  1246. {
  1247. // same size texture, just bits changing in it, lets twiddle
  1248. surface()->DrawUpdateRegionTextureRGBA( m_iHTMLTextureID, pCmd->unUpdateX, pCmd->unUpdateY, (const unsigned char *)pCmd->pBGRA, pCmd->unUpdateWide, pCmd->unUpdateTall, IMAGE_FORMAT_BGRA8888 );
  1249. }
  1250. else
  1251. {
  1252. surface()->DrawSetTextureRGBAEx( m_iHTMLTextureID, (const unsigned char *)pCmd->pBGRA, pCmd->unWide, pCmd->unTall, IMAGE_FORMAT_BGRA8888 );
  1253. }
  1254. // need a paint next time
  1255. Repaint();
  1256. }
  1257. //-----------------------------------------------------------------------------
  1258. // Purpose: browser wants to start loading this url, do we let it?
  1259. //-----------------------------------------------------------------------------
  1260. bool HTML::OnStartRequest( const char *url, const char *target, const char *pchPostData, bool bIsRedirect )
  1261. {
  1262. if ( !url || !Q_stricmp( url, "about:blank") )
  1263. return true ; // this is just webkit loading a new frames contents inside an existing page
  1264. HideFindDialog();
  1265. // see if we have a custom handler for this
  1266. bool bURLHandled = false;
  1267. for (int i = 0; i < m_CustomURLHandlers.Count(); i++)
  1268. {
  1269. if (!Q_strnicmp(m_CustomURLHandlers[i].url,url, Q_strlen(m_CustomURLHandlers[i].url)))
  1270. {
  1271. // we have a custom handler
  1272. Panel *targetPanel = m_CustomURLHandlers[i].hPanel;
  1273. if (targetPanel)
  1274. {
  1275. PostMessage(targetPanel, new KeyValues("CustomURL", "url", m_CustomURLHandlers[i].url ) );
  1276. }
  1277. bURLHandled = true;
  1278. }
  1279. }
  1280. if (bURLHandled)
  1281. return false;
  1282. if ( m_bNewWindowsOnly && bIsRedirect )
  1283. {
  1284. if ( target && ( !Q_stricmp( target, "_blank" ) || !Q_stricmp( target, "_new" ) ) ) // only allow NEW windows (_blank ones)
  1285. {
  1286. return true;
  1287. }
  1288. else
  1289. {
  1290. return false;
  1291. }
  1292. }
  1293. if ( target && !Q_strlen( target ) )
  1294. {
  1295. m_sCurrentURL = url;
  1296. KeyValues *pMessage = new KeyValues( "OnURLChanged" );
  1297. pMessage->SetString( "url", url );
  1298. pMessage->SetString( "postdata", pchPostData );
  1299. pMessage->SetInt( "isredirect", bIsRedirect ? 1 : 0 );
  1300. PostActionSignal( pMessage );
  1301. }
  1302. return true;
  1303. }
  1304. //-----------------------------------------------------------------------------
  1305. // Purpose: callback from cef thread, load a url please
  1306. //-----------------------------------------------------------------------------
  1307. void HTML::BrowserStartRequest( HTML_StartRequest_t *pCmd )
  1308. {
  1309. // In the case of a popup, CEF will create a new browser handle that we will manually remove
  1310. // (cf HTML::BrowserPopupHTMLWindow). However we must still reply to the HTML_StartRequest_t callback
  1311. // in order not to hang the browser.
  1312. if ( m_unBrowserHandleToDelete && ( pCmd->unBrowserHandle == m_unBrowserHandleToDelete ) )
  1313. {
  1314. m_SteamAPIContext.SteamHTMLSurface()->AllowStartRequest( pCmd->unBrowserHandle, false );
  1315. }
  1316. else if ( pCmd->unBrowserHandle == m_unBrowserHandle )
  1317. {
  1318. bool bRes = OnStartRequest( pCmd->pchURL, pCmd->pchTarget, pCmd->pchPostData, pCmd->bIsRedirect );
  1319. m_SteamAPIContext.SteamHTMLSurface()->AllowStartRequest( m_unBrowserHandle, bRes );
  1320. }
  1321. }
  1322. //-----------------------------------------------------------------------------
  1323. // Purpose: browser went to a new url
  1324. //-----------------------------------------------------------------------------
  1325. void HTML::BrowserURLChanged( HTML_URLChanged_t *pCmd )
  1326. {
  1327. CHECK_BROWSER_HANDLE();
  1328. m_sCurrentURL = pCmd->pchURL;
  1329. KeyValues *pMessage = new KeyValues( "OnURLChanged" );
  1330. pMessage->SetString( "url", pCmd->pchURL );
  1331. pMessage->SetString( "postdata", pCmd->pchPostData );
  1332. pMessage->SetInt( "isredirect", pCmd->bIsRedirect ? 1 : 0 );
  1333. PostActionSignal( pMessage );
  1334. OnURLChanged( m_sCurrentURL, pCmd->pchPostData, pCmd->bIsRedirect );
  1335. }
  1336. //-----------------------------------------------------------------------------
  1337. // Purpose: finished loading this page
  1338. //-----------------------------------------------------------------------------
  1339. void HTML::BrowserFinishedRequest( HTML_FinishedRequest_t *pCmd )
  1340. {
  1341. CHECK_BROWSER_HANDLE();
  1342. PostActionSignal( new KeyValues( "OnFinishRequest", "url", pCmd->pchURL ) );
  1343. if ( strlen( pCmd->pchPageTitle ) )
  1344. PostActionSignal( new KeyValues( "PageTitleChange", "title", pCmd->pchPageTitle ) );
  1345. KeyValues *pKVSecure = new KeyValues( "SecurityStatus" );
  1346. pKVSecure->SetString( "url", pCmd->pchURL );
  1347. OnFinishRequest( pCmd->pchURL, pCmd->pchPageTitle );
  1348. }
  1349. //-----------------------------------------------------------------------------
  1350. // Purpose: display a new html window
  1351. //-----------------------------------------------------------------------------
  1352. void HTML::BrowserPopupHTMLWindow( HTML_NewWindow_t *pCmd )
  1353. {
  1354. CHECK_BROWSER_HANDLE();
  1355. // Do not open a popup from a popup window
  1356. if (m_bPopupWindow)
  1357. {
  1358. if (m_SteamAPIContext.SteamHTMLSurface())
  1359. {
  1360. Assert( pCmd->unNewWindow_BrowserHandle != m_unBrowserHandle );
  1361. m_SteamAPIContext.SteamHTMLSurface()->RemoveBrowser( pCmd->unNewWindow_BrowserHandle );
  1362. }
  1363. return;
  1364. }
  1365. // Allow more than one popup to be active for now. For some reason, we are not getting HTML_NewWindow_t
  1366. // messages after trying to have more than one popup active. (Suspect that the browser is not getting destroyed on the Steam side,
  1367. // even though we request it via m_SteamAPIContext.SteamHTMLSurface()->RemoveBrowser( pCmd->unNewWindow_BrowserHandle )
  1368. /*
  1369. if ( gMOTDPopupWindowActive )
  1370. {
  1371. // Only allow one popup to be active at any time
  1372. // Destroy the browser created by steamapi/cef
  1373. Msg( "Only one popup active at any time. Dropping request to open a new window for %s\n", pCmd->pchURL );
  1374. if ( m_SteamAPIContext.SteamHTMLSurface() )
  1375. {
  1376. m_SteamAPIContext.SteamHTMLSurface()->RemoveBrowser( pCmd->unNewWindow_BrowserHandle );
  1377. }
  1378. return;
  1379. }
  1380. */
  1381. // HACK - Do not pass the browser handle created by CEF
  1382. // For some reason, we are not getting the paint messages anymore (might be related
  1383. // to some changes to htmlsurface.cpp (steam code)
  1384. // As a workaround, we are killing the supplied popup browser and create a new one
  1385. // Defer killing the supllied popup browser until the new one is fully created (HTML_BrowserReady_t
  1386. // message received) to work around a timing issue
  1387. // Note that we must also send a response to the HTML_StartRequest_t callback (with the browser handle
  1388. // created by CEF). If we do not reply to the callback, the browser may appear to hang (for 20 seconds)
  1389. // instead of navigating to the new page in the popup
  1390. // Create popup
  1391. // pCmd->unNewWindow_BrowserHandle getting removed once HTML_BrowserReady_t message received
  1392. HTMLPopup *p = new HTMLPopup( this, pCmd->unNewWindow_BrowserHandle, pCmd->pchURL, "" );
  1393. int wide = pCmd->unWide;
  1394. int tall = pCmd->unTall;
  1395. if ( wide == 0 || tall == 0 )
  1396. {
  1397. wide = MAX( 640, GetWide() );
  1398. tall = MAX( 480, GetTall() );
  1399. }
  1400. p->SetBounds( pCmd->unX, pCmd->unY, wide, tall );
  1401. p->SetDeleteSelfOnClose( true );
  1402. if ( pCmd->unX == 0 || pCmd->unY == 0 )
  1403. p->MoveToCenterOfScreen();
  1404. p->Activate();
  1405. }
  1406. //-----------------------------------------------------------------------------
  1407. // Purpose: browser telling us to use this cursor
  1408. //-----------------------------------------------------------------------------
  1409. void HTML::BrowserSetCursor( HTML_SetCursor_t *pCmd )
  1410. {
  1411. // GS - Mouse cursor value in CMsgSetCursor is set to one of EMouseCursor,
  1412. // by CChromePainter::OnSetCursor in html_chrome.cpp
  1413. // Code below relies on start of EMouseCursor being exactly same as vgui::CursorCode
  1414. vgui::CursorCode cursor;
  1415. uint32 msgCursor = pCmd->eMouseCursor;
  1416. if ( msgCursor >= (uint32)(dc_last) )
  1417. {
  1418. cursor = dc_arrow;
  1419. }
  1420. else
  1421. {
  1422. cursor = (CursorCode)msgCursor;
  1423. }
  1424. SetCursor( cursor );
  1425. }
  1426. //-----------------------------------------------------------------------------
  1427. // Purpose: browser telling to show the file loading dialog
  1428. //-----------------------------------------------------------------------------
  1429. void HTML::BrowserFileOpenDialog( HTML_FileOpenDialog_t *pCmd )
  1430. {
  1431. CHECK_BROWSER_HANDLE();
  1432. if ( m_hFileOpenDialog.Get() )
  1433. {
  1434. delete m_hFileOpenDialog.Get();
  1435. m_hFileOpenDialog = NULL;
  1436. }
  1437. m_hFileOpenDialog = new FileOpenDialog( this, pCmd->pchTitle, true );
  1438. m_hFileOpenDialog->SetStartDirectory( pCmd->pchInitialFile );
  1439. m_hFileOpenDialog->AddActionSignalTarget( this );
  1440. m_hFileOpenDialog->SetAutoDelete( true );
  1441. m_hFileOpenDialog->DoModal(false);
  1442. }
  1443. //-----------------------------------------------------------------------------
  1444. // Purpose: browser asking to show a tooltip
  1445. //-----------------------------------------------------------------------------
  1446. void HTML::BrowserShowToolTip( HTML_ShowToolTip_t *pCmd )
  1447. {
  1448. /*
  1449. BR FIXME
  1450. Tooltip *tip = GetTooltip();
  1451. tip->SetText( pCmd->text().c_str() );
  1452. tip->SetTooltipFormatToMultiLine();
  1453. tip->SetTooltipDelayMS( 250 );
  1454. tip->SetMaxToolTipWidth( MAX( 200, GetWide()/2 ) );
  1455. tip->ShowTooltip( this );
  1456. */
  1457. }
  1458. //-----------------------------------------------------------------------------
  1459. // Purpose: browser telling us to update tool tip text
  1460. //-----------------------------------------------------------------------------
  1461. void HTML::BrowserUpdateToolTip( HTML_UpdateToolTip_t *pCmd )
  1462. {
  1463. // GetTooltip()->SetText( pCmd->text().c_str() );
  1464. }
  1465. //-----------------------------------------------------------------------------
  1466. // Purpose: browser telling that it is done with the tip
  1467. //-----------------------------------------------------------------------------
  1468. void HTML::BrowserHideToolTip( HTML_HideToolTip_t *pCmd )
  1469. {
  1470. // GetTooltip()->HideTooltip();
  1471. // DeleteToolTip();
  1472. }
  1473. //-----------------------------------------------------------------------------
  1474. // Purpose: callback when performing a search
  1475. //-----------------------------------------------------------------------------
  1476. void HTML::BrowserSearchResults( HTML_SearchResults_t *pCmd )
  1477. {
  1478. CHECK_BROWSER_HANDLE();
  1479. if ( pCmd->unResults == 0 )
  1480. m_pFindBar->HideCountLabel();
  1481. else
  1482. m_pFindBar->ShowCountLabel();
  1483. if ( pCmd->unResults > 0 )
  1484. m_pFindBar->SetDialogVariable( "findcount", (int)pCmd->unResults );
  1485. if ( pCmd->unCurrentMatch > 0 )
  1486. m_pFindBar->SetDialogVariable( "findactive", (int)pCmd->unCurrentMatch );
  1487. m_pFindBar->InvalidateLayout();
  1488. }
  1489. //-----------------------------------------------------------------------------
  1490. // Purpose: browser telling us it had a close requested
  1491. //-----------------------------------------------------------------------------
  1492. void HTML::BrowserClose( HTML_CloseBrowser_t *pCmd )
  1493. {
  1494. CHECK_BROWSER_HANDLE();
  1495. PostActionSignal( new KeyValues( "OnCloseWindow" ) );
  1496. }
  1497. //-----------------------------------------------------------------------------
  1498. // Purpose: browser telling us the size of the horizontal scrollbars
  1499. //-----------------------------------------------------------------------------
  1500. void HTML::BrowserHorizontalScrollBarSizeResponse( HTML_HorizontalScroll_t *pCmd )
  1501. {
  1502. CHECK_BROWSER_HANDLE();
  1503. ScrollData_t scrollHorizontal;
  1504. scrollHorizontal.m_nScroll = pCmd->unScrollCurrent;
  1505. scrollHorizontal.m_nMax = pCmd->unScrollMax;
  1506. scrollHorizontal.m_bVisible = pCmd->bVisible;
  1507. scrollHorizontal.m_flZoom = pCmd->flPageScale;
  1508. /* Add this block if webkit scrollbars removed
  1509. int w, h;
  1510. GetSize( w, h );
  1511. scrollHorizontal.m_nY = h - (h / 100);
  1512. scrollHorizontal.m_nX = pCmd->unScrollCurrent;
  1513. scrollHorizontal.m_nWide = w;
  1514. scrollHorizontal.m_nTall = h / 100;
  1515. */
  1516. if ( scrollHorizontal != m_scrollHorizontal )
  1517. {
  1518. m_scrollHorizontal = scrollHorizontal;
  1519. UpdateSizeAndScrollBars();
  1520. }
  1521. else
  1522. {
  1523. m_scrollHorizontal = scrollHorizontal;
  1524. }
  1525. }
  1526. //-----------------------------------------------------------------------------
  1527. // Purpose: browser telling us the size of the vertical scrollbars
  1528. //-----------------------------------------------------------------------------
  1529. void HTML::BrowserVerticalScrollBarSizeResponse( HTML_VerticalScroll_t *pCmd )
  1530. {
  1531. CHECK_BROWSER_HANDLE();
  1532. ScrollData_t scrollVertical;
  1533. scrollVertical.m_nScroll = pCmd->unScrollCurrent;
  1534. scrollVertical.m_nMax = pCmd->unScrollMax;
  1535. scrollVertical.m_bVisible = pCmd->bVisible;
  1536. scrollVertical.m_flZoom = pCmd->flPageScale;
  1537. /* Add this block if webkit scrollbars removed
  1538. int w, h;
  1539. GetSize( w, h );
  1540. scrollVertical.m_nY = pCmd->unScrollCurrent;
  1541. scrollVertical.m_nX = w - (w / 100);
  1542. scrollVertical.m_nWide = w / 100;
  1543. scrollVertical.m_nTall = h;
  1544. */
  1545. if ( scrollVertical != m_scrollVertical )
  1546. {
  1547. m_scrollVertical = scrollVertical;
  1548. UpdateSizeAndScrollBars();
  1549. }
  1550. else
  1551. {
  1552. m_scrollVertical = scrollVertical;
  1553. }
  1554. }
  1555. //-----------------------------------------------------------------------------
  1556. // Purpose: browser telling us what is at this location on the page
  1557. //-----------------------------------------------------------------------------
  1558. void HTML::BrowserLinkAtPositionResponse( HTML_LinkAtPosition_t *pCmd )
  1559. {
  1560. CHECK_BROWSER_HANDLE();
  1561. m_LinkAtPos.m_sURL = pCmd->pchURL;
  1562. m_LinkAtPos.m_nX = pCmd->x;
  1563. m_LinkAtPos.m_nY = pCmd->y;
  1564. m_pContextMenu->SetItemVisible( m_iCopyLinkMenuItemID, !m_LinkAtPos.m_sURL.IsEmpty() ? true : false );
  1565. if ( m_bRequestingDragURL )
  1566. {
  1567. m_bRequestingDragURL = false;
  1568. m_sDragURL = m_LinkAtPos.m_sURL;
  1569. // make sure we get notified when the mouse gets released
  1570. if ( !m_sDragURL.IsEmpty() )
  1571. {
  1572. input()->SetMouseCapture( GetVPanel() );
  1573. }
  1574. }
  1575. if ( m_bRequestingCopyLink )
  1576. {
  1577. m_bRequestingCopyLink = false;
  1578. if ( !m_LinkAtPos.m_sURL.IsEmpty() )
  1579. system()->SetClipboardText( m_LinkAtPos.m_sURL, m_LinkAtPos.m_sURL.Length() );
  1580. else
  1581. system()->SetClipboardText( "", 1 );
  1582. }
  1583. OnLinkAtPosition( m_LinkAtPos.m_sURL );
  1584. }
  1585. //-----------------------------------------------------------------------------
  1586. // Purpose: browser telling us to pop a javascript alert dialog
  1587. //-----------------------------------------------------------------------------
  1588. void HTML::BrowserJSAlert( HTML_JSAlert_t *pCmd )
  1589. {
  1590. CHECK_BROWSER_HANDLE();
  1591. MessageBox *pDlg = new MessageBox( m_sCurrentURL, (const char *)pCmd->pchMessage, this );
  1592. pDlg->AddActionSignalTarget( this );
  1593. pDlg->SetCommand( new KeyValues( "DismissJSDialog", "result", false ) );
  1594. pDlg->DoModal();
  1595. }
  1596. //-----------------------------------------------------------------------------
  1597. // Purpose: browser telling us to pop a js confirm dialog
  1598. //-----------------------------------------------------------------------------
  1599. void HTML::BrowserJSConfirm( HTML_JSConfirm_t *pCmd )
  1600. {
  1601. CHECK_BROWSER_HANDLE();
  1602. QueryBox *pDlg = new QueryBox( m_sCurrentURL, (const char *)pCmd->pchMessage, this );
  1603. pDlg->AddActionSignalTarget( this );
  1604. pDlg->SetOKCommand( new KeyValues( "DismissJSDialog", "result", true ) );
  1605. pDlg->SetCancelCommand( new KeyValues( "DismissJSDialog", "result", false ) );
  1606. pDlg->DoModal();
  1607. }
  1608. //-----------------------------------------------------------------------------
  1609. // Purpose: browser telling us the state of back and forward buttons
  1610. //-----------------------------------------------------------------------------
  1611. void HTML::BrowserCanGoBackandForward( HTML_CanGoBackAndForward_t *pCmd )
  1612. {
  1613. CHECK_BROWSER_HANDLE();
  1614. m_bCanGoBack = pCmd->bCanGoBack;
  1615. m_bCanGoForward = pCmd->bCanGoForward;
  1616. }
  1617. //-----------------------------------------------------------------------------
  1618. // Purpose: ask the browser for what is at this x,y
  1619. //-----------------------------------------------------------------------------
  1620. void HTML::GetLinkAtPosition( int x, int y )
  1621. {
  1622. if ( m_unBrowserHandle == INVALID_HTMLBROWSER )
  1623. return;
  1624. m_SteamAPIContext.SteamHTMLSurface()->GetLinkAtPosition( m_unBrowserHandle, x, y );
  1625. }
  1626. //-----------------------------------------------------------------------------
  1627. // Purpose: update the size of the browser itself and scrollbars it shows
  1628. //-----------------------------------------------------------------------------
  1629. void HTML::UpdateSizeAndScrollBars()
  1630. {
  1631. // Tell IE
  1632. BrowserResize();
  1633. // Do this after we tell IE!
  1634. int w,h;
  1635. GetSize( w, h );
  1636. CalcScrollBars(w,h);
  1637. InvalidateLayout();
  1638. }