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.

973 lines
27 KiB

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #define PROTECTED_THINGS_DISABLE
  8. #include "vgui/Cursor.h"
  9. #include "vgui/IInput.h"
  10. #include "vgui/ILocalize.h"
  11. #include "vgui/IScheme.h"
  12. #include "vgui/ISurface.h"
  13. #include "vgui/IPanel.h"
  14. #include "keyvalues.h"
  15. #include "vgui_controls/Button.h"
  16. #include "vgui_controls/ComboBox.h"
  17. #include "vgui_controls/Menu.h"
  18. #include "vgui_controls/MenuItem.h"
  19. #include "vgui_controls/TextImage.h"
  20. #include <ctype.h>
  21. // memdbgon must be the last include file in a .cpp file!!!
  22. #include "tier0/memdbgon.h"
  23. using namespace vgui;
  24. namespace vgui
  25. {
  26. ComboBoxButton::ComboBoxButton(ComboBox *parent, const char *panelName, const char *text) : Button(parent, panelName, text)
  27. {
  28. SetButtonActivationType(ACTIVATE_ONPRESSED);
  29. }
  30. void ComboBoxButton::ApplySchemeSettings(IScheme *pScheme)
  31. {
  32. Button::ApplySchemeSettings(pScheme);
  33. SetFont(pScheme->GetFont("Marlett", IsProportional()));
  34. SetContentAlignment(Label::a_west);
  35. #ifdef PLATFORM_OSX
  36. SetTextInset(-3, 0);
  37. #else
  38. SetTextInset(3, 0);
  39. #endif
  40. SetDefaultBorder(pScheme->GetBorder("ScrollBarButtonBorder"));
  41. // arrow changes color but the background doesnt.
  42. SetDefaultColor(GetSchemeColor("ComboBoxButton.ArrowColor", pScheme), GetSchemeColor("ComboBoxButton.BgColor", pScheme));
  43. SetArmedColor(GetSchemeColor("ComboBoxButton.ArmedArrowColor", pScheme), GetSchemeColor("ComboBoxButton.BgColor", pScheme));
  44. SetDepressedColor(GetSchemeColor("ComboBoxButton.ArmedArrowColor", pScheme), GetSchemeColor("ComboBoxButton.BgColor", pScheme));
  45. m_DisabledBgColor = GetSchemeColor("ComboBoxButton.DisabledBgColor", pScheme);
  46. }
  47. IBorder * ComboBoxButton::GetBorder(bool depressed, bool armed, bool selected, bool keyfocus)
  48. {
  49. return NULL;
  50. // return Button::GetBorder(depressed, armed, selected, keyfocus);
  51. }
  52. //-----------------------------------------------------------------------------
  53. // Purpose: Dim the arrow on the button when exiting the box
  54. // only if the menu is closed, so let the parent handle this.
  55. //-----------------------------------------------------------------------------
  56. void ComboBoxButton::OnCursorExited()
  57. {
  58. // want the arrow to go grey when we exit the box if the menu is not open
  59. CallParentFunction(new KeyValues("CursorExited"));
  60. }
  61. } // namespace vgui
  62. vgui::Panel *ComboBox_Factory()
  63. {
  64. return new ComboBox( NULL, NULL, 5, true );
  65. }
  66. DECLARE_BUILD_FACTORY_CUSTOM( ComboBox, ComboBox_Factory );
  67. //-----------------------------------------------------------------------------
  68. // Purpose: Constructor
  69. // Input : parent - parent class
  70. // panelName
  71. // numLines - number of lines in dropdown menu
  72. // allowEdit - whether combobox is editable or not
  73. //-----------------------------------------------------------------------------
  74. ComboBox::ComboBox(Panel *parent, const char *panelName, int numLines, bool allowEdit ) : TextEntry(parent, panelName)
  75. {
  76. SetEditable(allowEdit);
  77. SetHorizontalScrolling(false); // do not scroll, always Start at the beginning of the text.
  78. // create the drop-down menu
  79. m_pDropDown = new Menu(this, NULL);
  80. m_pDropDown->AddActionSignalTarget(this);
  81. m_pDropDown->SetTypeAheadMode( Menu::TYPE_AHEAD_MODE );
  82. // button to Activate menu
  83. m_pButton = new ComboBoxButton(this, NULL, "u");
  84. m_pButton->SetCommand("ButtonClicked");
  85. m_pButton->AddActionSignalTarget(this);
  86. SetNumberOfEditLines(numLines);
  87. m_bHighlight = false;
  88. m_iDirection = Menu::DOWN;
  89. m_iOpenOffsetY = 0;
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose: Destructor
  93. //-----------------------------------------------------------------------------
  94. ComboBox::~ComboBox()
  95. {
  96. m_pDropDown->DeletePanel();
  97. m_pButton->DeletePanel();
  98. }
  99. //-----------------------------------------------------------------------------
  100. // Purpose: Set the number of items in the dropdown menu.
  101. // Input : numLines - number of items in dropdown menu
  102. //-----------------------------------------------------------------------------
  103. void ComboBox::SetNumberOfEditLines( int numLines )
  104. {
  105. m_pDropDown->SetNumberOfVisibleItems( numLines );
  106. }
  107. //-----------------------------------------------------------------------------
  108. // Purpose: Add an item to the drop down
  109. // Input : char *itemText - name of dropdown menu item
  110. //-----------------------------------------------------------------------------
  111. int ComboBox::AddItem(const char *itemText, const KeyValues *userData)
  112. {
  113. // when the menu item is selected it will send the custom message "SetText"
  114. return m_pDropDown->AddMenuItem( itemText, new KeyValues("SetText", "text", itemText), this, userData );
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose: Add an item to the drop down
  118. // Input : char *itemText - name of dropdown menu item
  119. //-----------------------------------------------------------------------------
  120. int ComboBox::AddItem(const wchar_t *itemText, const KeyValues *userData)
  121. {
  122. // add the element to the menu
  123. // when the menu item is selected it will send the custom message "SetText"
  124. KeyValues *kv = new KeyValues("SetText");
  125. kv->SetWString("text", itemText);
  126. // get an ansi version for the menuitem name
  127. char ansi[128];
  128. g_pVGuiLocalize->ConvertUnicodeToANSI(itemText, ansi, sizeof(ansi));
  129. return m_pDropDown->AddMenuItem(ansi, kv, this, userData);
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Removes a single item
  133. //-----------------------------------------------------------------------------
  134. void ComboBox::DeleteItem( int itemID )
  135. {
  136. if ( !m_pDropDown->IsValidMenuID(itemID))
  137. return;
  138. m_pDropDown->DeleteItem( itemID );
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Purpose: Updates a current item to the drop down
  142. // Input : char *itemText - name of dropdown menu item
  143. //-----------------------------------------------------------------------------
  144. bool ComboBox::UpdateItem(int itemID, const char *itemText, const KeyValues *userData)
  145. {
  146. if ( !m_pDropDown->IsValidMenuID(itemID))
  147. return false;
  148. // when the menu item is selected it will send the custom message "SetText"
  149. m_pDropDown->UpdateMenuItem(itemID, itemText, new KeyValues("SetText", "text", itemText), userData);
  150. InvalidateLayout();
  151. return true;
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Purpose: Updates a current item to the drop down
  155. // Input : wchar_t *itemText - name of dropdown menu item
  156. //-----------------------------------------------------------------------------
  157. bool ComboBox::UpdateItem(int itemID, const wchar_t *itemText, const KeyValues *userData)
  158. {
  159. if ( !m_pDropDown->IsValidMenuID(itemID))
  160. return false;
  161. // when the menu item is selected it will send the custom message "SetText"
  162. KeyValues *kv = new KeyValues("SetText");
  163. kv->SetWString("text", itemText);
  164. m_pDropDown->UpdateMenuItem(itemID, itemText, kv, userData);
  165. InvalidateLayout();
  166. return true;
  167. }
  168. //-----------------------------------------------------------------------------
  169. // Purpose: Updates a current item to the drop down
  170. // Input : wchar_t *itemText - name of dropdown menu item
  171. //-----------------------------------------------------------------------------
  172. bool ComboBox::IsItemIDValid( int itemID )
  173. {
  174. return m_pDropDown->IsValidMenuID(itemID);
  175. }
  176. //-----------------------------------------------------------------------------
  177. // Purpose:
  178. //-----------------------------------------------------------------------------
  179. void ComboBox::SetItemEnabled(const char *itemText, bool state)
  180. {
  181. m_pDropDown->SetItemEnabled(itemText, state);
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Purpose:
  185. //-----------------------------------------------------------------------------
  186. void ComboBox::SetItemEnabled(int itemID, bool state)
  187. {
  188. m_pDropDown->SetItemEnabled(itemID, state);
  189. }
  190. //-----------------------------------------------------------------------------
  191. // Purpose: Remove all items from the drop down menu
  192. //-----------------------------------------------------------------------------
  193. void ComboBox::RemoveAll()
  194. {
  195. m_pDropDown->DeleteAllItems();
  196. }
  197. //-----------------------------------------------------------------------------
  198. // Purpose:
  199. //-----------------------------------------------------------------------------
  200. int ComboBox::GetItemCount()
  201. {
  202. return m_pDropDown->GetItemCount();
  203. }
  204. int ComboBox::GetItemIDFromRow( int row )
  205. {
  206. // valid from [0, GetItemCount)
  207. return m_pDropDown->GetMenuID( row );
  208. }
  209. //-----------------------------------------------------------------------------
  210. // Purpose: Activate the item in the menu list, as if that menu item had been selected by the user
  211. // Input : itemID - itemID from AddItem in list of dropdown items
  212. //-----------------------------------------------------------------------------
  213. void ComboBox::ActivateItem(int itemID)
  214. {
  215. m_pDropDown->ActivateItem(itemID);
  216. }
  217. //-----------------------------------------------------------------------------
  218. // Purpose: Activate the item in the menu list, as if that menu item had been selected by the user
  219. // Input : itemID - itemID from AddItem in list of dropdown items
  220. //-----------------------------------------------------------------------------
  221. void ComboBox::ActivateItemByRow(int row)
  222. {
  223. m_pDropDown->ActivateItemByRow(row);
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Purpose: Allows a custom menu to be used with the combo box
  227. //-----------------------------------------------------------------------------
  228. void ComboBox::SetMenu( Menu *menu )
  229. {
  230. if ( m_pDropDown )
  231. {
  232. m_pDropDown->MarkForDeletion();
  233. }
  234. m_pDropDown = menu;
  235. if ( m_pDropDown )
  236. {
  237. m_pDropDown->SetParent( this );
  238. }
  239. }
  240. //-----------------------------------------------------------------------------
  241. // Purpose: Layout the format of the combo box for drawing on screen
  242. //-----------------------------------------------------------------------------
  243. void ComboBox::PerformLayout()
  244. {
  245. int wide, tall;
  246. GetPaintSize(wide, tall);
  247. BaseClass::PerformLayout();
  248. HFont buttonFont = m_pButton->GetFont();
  249. int fontTall = surface()->GetFontTall( buttonFont );
  250. int buttonSize = MIN( tall, fontTall );
  251. int buttonY = ( ( tall - 1 ) - buttonSize ) / 2;
  252. // Some dropdown button icons in our games are wider than they are taller. We need to factor that in.
  253. int button_wide, button_tall;
  254. m_pButton->GetContentSize(button_wide, button_tall);
  255. button_wide = MAX( buttonSize, button_wide );
  256. m_pButton->SetBounds( wide - button_wide, buttonY, button_wide, buttonSize );
  257. if ( IsEditable() )
  258. {
  259. SetCursor(dc_ibeam);
  260. }
  261. else
  262. {
  263. SetCursor(dc_arrow);
  264. }
  265. m_pButton->SetEnabled(IsEnabled());
  266. DoMenuLayout();
  267. }
  268. //-----------------------------------------------------------------------------
  269. // Purpose:
  270. //-----------------------------------------------------------------------------
  271. void ComboBox::DoMenuLayout()
  272. {
  273. m_pDropDown->PositionRelativeToPanel( this, m_iDirection, m_iOpenOffsetY );
  274. // reset the width of the drop down menu to be the width of the combo box
  275. m_pDropDown->SetFixedWidth(GetWide());
  276. m_pDropDown->ForceCalculateWidth();
  277. }
  278. //-----------------------------------------------------------------------------
  279. // Purpose: Sorts the items in the list
  280. //-----------------------------------------------------------------------------
  281. void ComboBox::SortItems( void )
  282. {
  283. }
  284. //-----------------------------------------------------------------------------
  285. // Purpose: return the index of the last selected item
  286. //-----------------------------------------------------------------------------
  287. int ComboBox::GetActiveItem()
  288. {
  289. return m_pDropDown->GetActiveItem();
  290. }
  291. //-----------------------------------------------------------------------------
  292. // Purpose:
  293. //-----------------------------------------------------------------------------
  294. KeyValues *ComboBox::GetActiveItemUserData()
  295. {
  296. return m_pDropDown->GetItemUserData(GetActiveItem());
  297. }
  298. //-----------------------------------------------------------------------------
  299. // Purpose:
  300. //-----------------------------------------------------------------------------
  301. KeyValues *ComboBox::GetItemUserData(int itemID)
  302. {
  303. return m_pDropDown->GetItemUserData(itemID);
  304. }
  305. //-----------------------------------------------------------------------------
  306. // Purpose: data accessor
  307. //-----------------------------------------------------------------------------
  308. void ComboBox::GetItemText( int itemID, wchar_t *text, int bufLenInBytes )
  309. {
  310. m_pDropDown->GetItemText( itemID, text, bufLenInBytes );
  311. }
  312. void ComboBox::GetItemText( int itemID, char *text, int bufLenInBytes )
  313. {
  314. m_pDropDown->GetItemText( itemID, text, bufLenInBytes );
  315. }
  316. //-----------------------------------------------------------------------------
  317. // Purpose:
  318. // Output : Returns true on success, false on failure.
  319. //-----------------------------------------------------------------------------
  320. bool ComboBox::IsDropdownVisible()
  321. {
  322. return m_pDropDown->IsVisible();
  323. }
  324. //-----------------------------------------------------------------------------
  325. // Purpose:
  326. // Input : *inResourceData -
  327. //-----------------------------------------------------------------------------
  328. void ComboBox::ApplySchemeSettings(IScheme *pScheme)
  329. {
  330. BaseClass::ApplySchemeSettings(pScheme);
  331. SetBorder(pScheme->GetBorder("ComboBoxBorder"));
  332. }
  333. //-----------------------------------------------------------------------------
  334. // Purpose: Set the visiblity of the drop down menu button.
  335. //-----------------------------------------------------------------------------
  336. void ComboBox::SetDropdownButtonVisible(bool state)
  337. {
  338. m_pButton->SetVisible(state);
  339. }
  340. //-----------------------------------------------------------------------------
  341. // Purpose: overloads TextEntry MousePressed
  342. //-----------------------------------------------------------------------------
  343. void ComboBox::OnMousePressed(MouseCode code)
  344. {
  345. if ( !m_pDropDown )
  346. return;
  347. if ( !IsEnabled() )
  348. return;
  349. // make sure it's getting pressed over us (it may not be due to mouse capture)
  350. if ( !IsCursorOver() )
  351. {
  352. HideMenu();
  353. return;
  354. }
  355. if ( IsEditable() )
  356. {
  357. BaseClass::OnMousePressed(code);
  358. HideMenu();
  359. }
  360. else
  361. {
  362. // clicking on a non-editable text box just activates the drop down menu
  363. RequestFocus();
  364. DoClick();
  365. }
  366. }
  367. //-----------------------------------------------------------------------------
  368. // Purpose: Double-click acts the same as a single-click
  369. //-----------------------------------------------------------------------------
  370. void ComboBox::OnMouseDoublePressed(MouseCode code)
  371. {
  372. if (IsEditable())
  373. {
  374. BaseClass::OnMouseDoublePressed(code);
  375. }
  376. else
  377. {
  378. OnMousePressed(code);
  379. }
  380. }
  381. //-----------------------------------------------------------------------------
  382. // Purpose: Called when a command is received from the menu
  383. // Changes the label text to be that of the command
  384. // Input : char *command -
  385. //-----------------------------------------------------------------------------
  386. void ComboBox::OnCommand( const char *command )
  387. {
  388. if (!stricmp(command, "ButtonClicked"))
  389. {
  390. // hide / show the menu underneath
  391. DoClick();
  392. }
  393. Panel::OnCommand(command);
  394. }
  395. //-----------------------------------------------------------------------------
  396. // Purpose:
  397. //-----------------------------------------------------------------------------
  398. void ComboBox::OnSetText(const wchar_t *newtext)
  399. {
  400. // see if the combobox text has changed, and if so, post a message detailing the new text
  401. const wchar_t *text = newtext;
  402. // check if the new text is a localized string, if so undo it
  403. if (*text == '#')
  404. {
  405. char cbuf[255];
  406. g_pVGuiLocalize->ConvertUnicodeToANSI(text, cbuf, 255);
  407. // try lookup in localization tables
  408. StringIndex_t unlocalizedTextSymbol = g_pVGuiLocalize->FindIndex(cbuf + 1);
  409. if (unlocalizedTextSymbol != INVALID_STRING_INDEX)
  410. {
  411. // we have a new text value
  412. text = g_pVGuiLocalize->GetValueByIndex(unlocalizedTextSymbol);
  413. }
  414. }
  415. wchar_t wbuf[255];
  416. GetText(wbuf, 254);
  417. if ( wcscmp(wbuf, text) )
  418. {
  419. // text has changed
  420. SetText(text);
  421. // fire off that things have changed
  422. PostActionSignal(new KeyValues("TextChanged", "text", text));
  423. Repaint();
  424. }
  425. // close the box
  426. HideMenu();
  427. }
  428. //-----------------------------------------------------------------------------
  429. // Purpose: hides the menu
  430. //-----------------------------------------------------------------------------
  431. void ComboBox::HideMenu(void)
  432. {
  433. if ( !m_pDropDown )
  434. return;
  435. // hide the menu
  436. m_pDropDown->SetVisible(false);
  437. Repaint();
  438. OnHideMenu(m_pDropDown);
  439. }
  440. //-----------------------------------------------------------------------------
  441. // Purpose: shows the menu
  442. //-----------------------------------------------------------------------------
  443. void ComboBox::ShowMenu(void)
  444. {
  445. if ( !m_pDropDown )
  446. return;
  447. // hide the menu
  448. m_pDropDown->SetVisible(false);
  449. DoClick();
  450. }
  451. //-----------------------------------------------------------------------------
  452. // Purpose: Called when the window loses focus; hides the menu
  453. //-----------------------------------------------------------------------------
  454. void ComboBox::OnKillFocus()
  455. {
  456. SelectNoText();
  457. }
  458. //-----------------------------------------------------------------------------
  459. // Purpose: Called when the menu is closed
  460. //-----------------------------------------------------------------------------
  461. void ComboBox::OnMenuClose()
  462. {
  463. HideMenu();
  464. if ( HasFocus() )
  465. {
  466. SelectAllText(false);
  467. }
  468. else if ( m_bHighlight )
  469. {
  470. m_bHighlight = false;
  471. // we want the text to be highlighted when we request the focus
  472. // SelectAllOnFirstFocus(true);
  473. RequestFocus();
  474. }
  475. // if cursor is in this box or the arrow box
  476. else if ( IsCursorOver() )// make sure it's getting pressed over us (it may not be due to mouse capture)
  477. {
  478. SelectAllText(false);
  479. OnCursorEntered();
  480. // Get focus so the box will unhighlight if we click somewhere else.
  481. RequestFocus();
  482. }
  483. else
  484. {
  485. m_pButton->SetArmed(false);
  486. }
  487. }
  488. //-----------------------------------------------------------------------------
  489. // Purpose: Handles hotkey accesses
  490. // FIXME: make this open different directions as necessary see menubutton.
  491. //-----------------------------------------------------------------------------
  492. void ComboBox::DoClick()
  493. {
  494. // menu is already visible, hide the menu
  495. if ( m_pDropDown->IsVisible() )
  496. {
  497. HideMenu();
  498. return;
  499. }
  500. // do nothing if menu is not enabled
  501. if ( !m_pDropDown->IsEnabled() )
  502. {
  503. return;
  504. }
  505. // force the menu to Think
  506. m_pDropDown->PerformLayout();
  507. // make sure we're at the top of the draw order (and therefore our children as well)
  508. // RequestFocus();
  509. // We want the item that is shown in the combo box to show as selected
  510. int itemToSelect = -1;
  511. int i;
  512. wchar_t comboBoxContents[255];
  513. GetText(comboBoxContents, 255);
  514. for ( i = 0 ; i < m_pDropDown->GetItemCount() ; i++ )
  515. {
  516. wchar_t menuItemName[255];
  517. int menuID = m_pDropDown->GetMenuID(i);
  518. m_pDropDown->GetMenuItem(menuID)->GetText(menuItemName, 255);
  519. if (!wcscmp(menuItemName, comboBoxContents))
  520. {
  521. itemToSelect = i;
  522. break;
  523. }
  524. }
  525. // if we found a match, highlight it on opening the menu
  526. if ( itemToSelect >= 0 )
  527. {
  528. m_pDropDown->SetCurrentlyHighlightedItem( m_pDropDown->GetMenuID(itemToSelect) );
  529. }
  530. // reset the dropdown's position
  531. DoMenuLayout();
  532. // make sure we're at the top of the draw order (and therefore our children as well)
  533. // this important to make sure the menu will be drawn in the foreground
  534. MoveToFront();
  535. // notify
  536. OnShowMenu(m_pDropDown);
  537. // show the menu
  538. m_pDropDown->SetVisible(true);
  539. // bring to focus
  540. m_pDropDown->RequestFocus();
  541. // no text is highlighted when the menu is opened
  542. SelectNoText();
  543. // highlight the arrow while menu is open
  544. m_pButton->SetArmed(true);
  545. Repaint();
  546. }
  547. //-----------------------------------------------------------------------------
  548. // Purpose: Brighten the arrow on the button when entering the box
  549. //-----------------------------------------------------------------------------
  550. void ComboBox::OnCursorEntered()
  551. {
  552. // want the arrow to go white when we enter the box
  553. m_pButton->OnCursorEntered();
  554. TextEntry::OnCursorEntered();
  555. }
  556. //-----------------------------------------------------------------------------
  557. // Purpose: Dim the arrow on the button when exiting the box
  558. //-----------------------------------------------------------------------------
  559. void ComboBox::OnCursorExited()
  560. {
  561. // want the arrow to go grey when we exit the box if the menu is not open
  562. if ( !m_pDropDown->IsVisible() )
  563. {
  564. m_pButton->SetArmed(false);
  565. TextEntry::OnCursorExited();
  566. }
  567. }
  568. //-----------------------------------------------------------------------------
  569. // Purpose:
  570. //-----------------------------------------------------------------------------
  571. #ifdef _GAMECONSOLE
  572. void ComboBox::OnMenuItemSelected()
  573. {
  574. m_bHighlight = true;
  575. // For editable cbs, fill in the text field from whatever is chosen from the dropdown...
  576. int idx = GetActiveItem();
  577. if ( idx >= 0 )
  578. {
  579. wchar_t name[ 256 ];
  580. GetItemText( idx, name, sizeof( name ) );
  581. OnSetText( name );
  582. }
  583. Repaint();
  584. // go to the next control
  585. if(!NavigateDown())
  586. {
  587. NavigateUp();
  588. }
  589. }
  590. #else
  591. void ComboBox::OnMenuItemSelected()
  592. {
  593. m_bHighlight = true;
  594. // Fill in the text field from whatever is chosen from the dropdown...
  595. int idx = GetActiveItem();
  596. if ( idx >= 0 )
  597. {
  598. wchar_t name[ 256 ];
  599. GetItemText( idx, name, sizeof( name ) );
  600. OnSetText( name );
  601. }
  602. Repaint();
  603. }
  604. #endif
  605. //-----------------------------------------------------------------------------
  606. // Purpose:
  607. //-----------------------------------------------------------------------------
  608. void ComboBox::OnSizeChanged(int wide, int tall)
  609. {
  610. BaseClass::OnSizeChanged( wide, tall);
  611. // set the drawwidth.
  612. int bwide, btall;
  613. PerformLayout();
  614. m_pButton->GetSize( bwide, btall);
  615. SetDrawWidth( wide - bwide );
  616. }
  617. //-----------------------------------------------------------------------------
  618. // Purpose:
  619. //-----------------------------------------------------------------------------
  620. #ifdef _GAMECONSOLE
  621. void ComboBox::OnSetFocus()
  622. {
  623. BaseClass::OnSetFocus();
  624. GotoTextEnd();
  625. SelectAllText(true);
  626. }
  627. #else
  628. void ComboBox::OnSetFocus()
  629. {
  630. BaseClass::OnSetFocus();
  631. GotoTextEnd();
  632. SelectAllText(false);
  633. }
  634. #endif
  635. //-----------------------------------------------------------------------------
  636. // Purpose:
  637. //-----------------------------------------------------------------------------
  638. #ifdef _GAMECONSOLE
  639. void ComboBox::OnKeyCodePressed(KeyCode code)
  640. {
  641. switch ( GetBaseButtonCode( code ) )
  642. {
  643. case KEY_XBUTTON_A:
  644. DoClick();
  645. break;
  646. case KEY_XBUTTON_UP:
  647. case KEY_XSTICK1_UP:
  648. case KEY_XSTICK2_UP:
  649. if(m_pDropDown->IsVisible())
  650. {
  651. MoveAlongMenuItemList(-1);
  652. }
  653. else
  654. {
  655. BaseClass::OnKeyCodePressed(code);
  656. }
  657. break;
  658. case KEY_XBUTTON_DOWN:
  659. case KEY_XSTICK1_DOWN:
  660. case KEY_XSTICK2_DOWN:
  661. if(m_pDropDown->IsVisible())
  662. {
  663. MoveAlongMenuItemList(1);
  664. }
  665. else
  666. {
  667. BaseClass::OnKeyCodePressed(code);
  668. }
  669. break;
  670. default:
  671. BaseClass::OnKeyCodePressed(code);
  672. break;
  673. }
  674. }
  675. #endif
  676. //-----------------------------------------------------------------------------
  677. // Purpose: Handles up/down arrows
  678. //-----------------------------------------------------------------------------
  679. void ComboBox::OnKeyCodeTyped(KeyCode code)
  680. {
  681. bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
  682. if (alt)
  683. {
  684. switch (code)
  685. {
  686. case KEY_UP:
  687. case KEY_DOWN:
  688. {
  689. DoClick();
  690. break;
  691. }
  692. default:
  693. {
  694. BaseClass::OnKeyCodeTyped(code);
  695. break;
  696. }
  697. }
  698. }
  699. else
  700. {
  701. switch (code)
  702. {
  703. case KEY_HOME:
  704. case KEY_END:
  705. case KEY_PAGEUP:
  706. case KEY_PAGEDOWN:
  707. case KEY_UP:
  708. case KEY_DOWN:
  709. {
  710. int itemSelected = m_pDropDown->GetCurrentlyHighlightedItem();
  711. m_pDropDown->OnKeyCodeTyped(code);
  712. int itemToSelect = m_pDropDown->GetCurrentlyHighlightedItem();
  713. if ( itemToSelect != itemSelected )
  714. {
  715. SelectMenuItem(itemToSelect);
  716. }
  717. break;
  718. }
  719. case KEY_ENTER:
  720. {
  721. int itemToSelect = m_pDropDown->GetCurrentlyHighlightedItem();
  722. if ( m_pDropDown->IsValidMenuID( itemToSelect ) )
  723. {
  724. m_pDropDown->ActivateItem(itemToSelect);
  725. }
  726. else
  727. {
  728. BaseClass::OnKeyCodeTyped( code );
  729. }
  730. break;
  731. }
  732. default:
  733. {
  734. BaseClass::OnKeyCodeTyped(code);
  735. break;
  736. }
  737. }
  738. }
  739. }
  740. //-----------------------------------------------------------------------------
  741. // Purpose: handles key input
  742. //-----------------------------------------------------------------------------
  743. void ComboBox::OnKeyTyped(wchar_t unichar)
  744. {
  745. if ( IsEditable() || unichar == '\t') // don't play with key presses in edit mode
  746. {
  747. BaseClass::OnKeyTyped( unichar );
  748. return;
  749. }
  750. int itemSelected = m_pDropDown->GetCurrentlyHighlightedItem();
  751. m_pDropDown->OnKeyTyped(unichar);
  752. int itemToSelect = m_pDropDown->GetCurrentlyHighlightedItem();
  753. if ( itemToSelect != itemSelected )
  754. {
  755. SelectMenuItem(itemToSelect);
  756. }
  757. else
  758. {
  759. BaseClass::OnKeyTyped( unichar );
  760. }
  761. }
  762. void ComboBox::SelectMenuItem(int itemToSelect)
  763. {
  764. // if we found this item, then we scroll up or down
  765. if ( itemToSelect >= 0 && itemToSelect < m_pDropDown->GetItemCount() )
  766. {
  767. wchar_t menuItemName[255];
  768. int menuID = m_pDropDown->GetMenuID(itemToSelect);
  769. m_pDropDown->GetMenuItem(menuID)->GetText(menuItemName, 254);
  770. OnSetText(menuItemName);
  771. SelectAllText(false);
  772. }
  773. }
  774. //-----------------------------------------------------------------------------
  775. // Purpose:
  776. //-----------------------------------------------------------------------------
  777. void ComboBox::MoveAlongMenuItemList(int direction)
  778. {
  779. // We want the item that is shown in the combo box to show as selected
  780. int itemToSelect = -1;
  781. wchar_t menuItemName[255];
  782. int i;
  783. wchar_t comboBoxContents[255];
  784. GetText(comboBoxContents, 254);
  785. for ( i = 0 ; i < m_pDropDown->GetItemCount() ; i++ )
  786. {
  787. int menuID = m_pDropDown->GetMenuID(i);
  788. m_pDropDown->GetMenuItem(menuID)->GetText(menuItemName, 254);
  789. if ( !wcscmp(menuItemName, comboBoxContents) )
  790. {
  791. itemToSelect = i;
  792. break;
  793. }
  794. }
  795. if ( itemToSelect >= 0 )
  796. {
  797. int newItem = itemToSelect + direction;
  798. if ( newItem < 0 )
  799. {
  800. newItem = 0;
  801. }
  802. else if ( newItem >= m_pDropDown->GetItemCount() )
  803. {
  804. newItem = m_pDropDown->GetItemCount() - 1;
  805. }
  806. SelectMenuItem(newItem);
  807. }
  808. }
  809. void ComboBox::MoveToFirstMenuItem()
  810. {
  811. SelectMenuItem(0);
  812. }
  813. void ComboBox::MoveToLastMenuItem()
  814. {
  815. SelectMenuItem(m_pDropDown->GetItemCount() - 1);
  816. }
  817. //-----------------------------------------------------------------------------
  818. // Purpose: Sets the direction from the menu button the menu should open
  819. //-----------------------------------------------------------------------------
  820. void ComboBox::SetOpenDirection(Menu::MenuDirection_e direction)
  821. {
  822. m_iDirection = direction;
  823. }
  824. void ComboBox::SetFont( HFont font )
  825. {
  826. BaseClass::SetFont( font );
  827. m_pDropDown->SetFont( font );
  828. }
  829. void ComboBox::SetUseFallbackFont( bool bState, HFont hFallback )
  830. {
  831. BaseClass::SetUseFallbackFont( bState, hFallback );
  832. m_pDropDown->SetUseFallbackFont( bState, hFallback );
  833. }