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.

321 lines
9.4 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "filesystem.h"
  7. #include "matsys_controls/picker.h"
  8. #include "tier1/keyvalues.h"
  9. #include "vgui_controls/ListPanel.h"
  10. #include "vgui_controls/TextEntry.h"
  11. #include "vgui_controls/Button.h"
  12. #include "vgui/ISurface.h"
  13. #include "vgui/IInput.h"
  14. // NOTE: This has to be the last file included!
  15. #include "tier0/memdbgon.h"
  16. using namespace vgui;
  17. //-----------------------------------------------------------------------------
  18. //
  19. // Base asset Picker
  20. //
  21. //-----------------------------------------------------------------------------
  22. //-----------------------------------------------------------------------------
  23. // Sort by asset name
  24. //-----------------------------------------------------------------------------
  25. static int __cdecl PickerBrowserSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
  26. {
  27. const char *string1 = item1.kv->GetString("choice");
  28. const char *string2 = item2.kv->GetString("choice");
  29. return stricmp( string1, string2 );
  30. }
  31. //-----------------------------------------------------------------------------
  32. // Purpose: Constructor
  33. //-----------------------------------------------------------------------------
  34. CPicker::CPicker( vgui::Panel *pParent, const char *pColumnHeader, const char *pTextType ) :
  35. BaseClass( pParent, "Picker" )
  36. {
  37. m_pPickerType = pColumnHeader;
  38. m_pPickerTextType = pTextType;
  39. // FIXME: Make this an image browser
  40. m_pPickerBrowser = new vgui::ListPanel( this, "Browser" );
  41. m_pPickerBrowser->AddColumnHeader( 0, "choice", m_pPickerType, 52, 0 );
  42. m_pPickerBrowser->SetSelectIndividualCells( true );
  43. m_pPickerBrowser->SetEmptyListText( "Nothing to pick" );
  44. m_pPickerBrowser->SetDragEnabled( true );
  45. m_pPickerBrowser->AddActionSignalTarget( this );
  46. m_pPickerBrowser->SetSortFunc( 0, PickerBrowserSortFunc );
  47. m_pPickerBrowser->SetSortColumn( 0 );
  48. // filter selection
  49. m_pFilterList = new TextEntry( this, "FilterList" );
  50. m_pFilterList->AddActionSignalTarget( this );
  51. m_pFilterList->RequestFocus();
  52. LoadControlSettingsAndUserConfig( "resource/picker.res" );
  53. }
  54. //-----------------------------------------------------------------------------
  55. // Purpose: Destructor
  56. //-----------------------------------------------------------------------------
  57. CPicker::~CPicker()
  58. {
  59. }
  60. //-----------------------------------------------------------------------------
  61. // Purpose:
  62. //-----------------------------------------------------------------------------
  63. void CPicker::OnKeyCodeTyped( KeyCode code )
  64. {
  65. if (( code == KEY_UP ) || ( code == KEY_DOWN ) || ( code == KEY_PAGEUP ) || ( code == KEY_PAGEDOWN ))
  66. {
  67. KeyValues *pMsg = new KeyValues("KeyCodeTyped", "code", code);
  68. vgui::ipanel()->SendMessage( m_pPickerBrowser->GetVPanel(), pMsg, GetVPanel());
  69. pMsg->deleteThis();
  70. }
  71. else
  72. {
  73. BaseClass::OnKeyCodeTyped( code );
  74. }
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose: refreshes the asset list
  78. //-----------------------------------------------------------------------------
  79. void CPicker::SetStringList( const PickerList_t &list )
  80. {
  81. m_Type = list.m_Type;
  82. m_pPickerBrowser->RemoveAll();
  83. int nCount = list.Count();
  84. for ( int i = 0; i < nCount; ++i )
  85. {
  86. const char *pPickerName = list[i].m_pChoiceString;
  87. KeyValues *kv = new KeyValues( "node", "choice", pPickerName );
  88. if ( m_Type == PICKER_CHOICE_STRING )
  89. {
  90. kv->SetString( "value", list[i].m_pChoiceValue );
  91. }
  92. else
  93. {
  94. kv->SetPtr( "value", list[i].m_pChoiceValuePtr );
  95. }
  96. int nItemID = m_pPickerBrowser->AddItem( kv, 0, false, false );
  97. if ( m_Type == PICKER_CHOICE_STRING )
  98. {
  99. KeyValues *pDrag = new KeyValues( "drag", "text", list[i].m_pChoiceValue );
  100. if ( m_pPickerTextType )
  101. {
  102. pDrag->SetString( "texttype", m_pPickerTextType );
  103. }
  104. m_pPickerBrowser->SetItemDragData( nItemID, pDrag );
  105. }
  106. }
  107. RefreshChoiceList();
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Purpose: refreshes the choice list
  111. //-----------------------------------------------------------------------------
  112. void CPicker::RefreshChoiceList( )
  113. {
  114. // Check the filter matches
  115. int nMatchingCount = 0;
  116. int nTotalCount = 0;
  117. for ( int nItemID = m_pPickerBrowser->FirstItem(); nItemID != m_pPickerBrowser->InvalidItemID(); nItemID = m_pPickerBrowser->NextItem( nItemID ) )
  118. {
  119. KeyValues *kv = m_pPickerBrowser->GetItem( nItemID );
  120. const char *pPickerName = kv->GetString( "choice" );
  121. bool bVisible = !m_Filter.Length() || Q_stristr( pPickerName, m_Filter.Get() );
  122. m_pPickerBrowser->SetItemVisible( nItemID, bVisible );
  123. if ( bVisible )
  124. {
  125. ++nMatchingCount;
  126. }
  127. ++nTotalCount;
  128. }
  129. char pColumnTitle[512];
  130. Q_snprintf( pColumnTitle, sizeof(pColumnTitle), "%s (%d/%d)",
  131. m_pPickerType, nMatchingCount, nTotalCount );
  132. m_pPickerBrowser->SetColumnHeaderText( 0, pColumnTitle );
  133. m_pPickerBrowser->SortList();
  134. if ( ( m_pPickerBrowser->GetSelectedItemsCount() == 0 ) && ( m_pPickerBrowser->GetItemCount() > 0 ) )
  135. {
  136. int nItemID = m_pPickerBrowser->GetItemIDFromRow( 0 );
  137. m_pPickerBrowser->SetSelectedCell( nItemID, 0 );
  138. }
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Purpose: refreshes dialog on text changing
  142. //-----------------------------------------------------------------------------
  143. void CPicker::OnTextChanged( )
  144. {
  145. int nLength = m_pFilterList->GetTextLength();
  146. m_Filter.SetLength( nLength );
  147. if ( nLength > 0 )
  148. {
  149. m_pFilterList->GetText( m_Filter.Get(), nLength+1 );
  150. }
  151. RefreshChoiceList();
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Returns the selected string
  155. //-----------------------------------------------------------------------------
  156. PickerChoiceType_t CPicker::GetSelectionType() const
  157. {
  158. return m_Type;
  159. }
  160. const char *CPicker::GetSelectedString( ) const
  161. {
  162. if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
  163. return NULL;
  164. if ( m_Type != PICKER_CHOICE_STRING )
  165. return NULL;
  166. int nIndex = m_pPickerBrowser->GetSelectedItem( 0 );
  167. KeyValues *pItemKeyValues = m_pPickerBrowser->GetItem( nIndex );
  168. return pItemKeyValues->GetString( "value" );
  169. }
  170. void *CPicker::GetSelectedPtr( ) const
  171. {
  172. if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
  173. return NULL;
  174. if ( m_Type != PICKER_CHOICE_PTR )
  175. return NULL;
  176. int nIndex = m_pPickerBrowser->GetSelectedItem( 0 );
  177. KeyValues *pItemKeyValues = m_pPickerBrowser->GetItem( nIndex );
  178. return pItemKeyValues->GetPtr( "value" );
  179. }
  180. //-----------------------------------------------------------------------------
  181. // Returns the index of the selected string
  182. //-----------------------------------------------------------------------------
  183. int CPicker::GetSelectedIndex()
  184. {
  185. if ( m_pPickerBrowser->GetSelectedItemsCount() == 0 )
  186. return -1;
  187. return m_pPickerBrowser->GetSelectedItem( 0 );
  188. }
  189. //-----------------------------------------------------------------------------
  190. //
  191. // Purpose: Modal picker frame
  192. //
  193. //-----------------------------------------------------------------------------
  194. CPickerFrame::CPickerFrame( vgui::Panel *pParent, const char *pTitle, const char *pPickerType, const char *pTextType ) :
  195. BaseClass( pParent, "PickerFrame" )
  196. {
  197. m_pContextKeyValues = NULL;
  198. SetDeleteSelfOnClose( true );
  199. m_pPicker = new CPicker( this, pPickerType, pTextType );
  200. m_pPicker->AddActionSignalTarget( this );
  201. m_pOpenButton = new Button( this, "OpenButton", "#FileOpenDialog_Open", this, "Open" );
  202. m_pCancelButton = new Button( this, "CancelButton", "#FileOpenDialog_Cancel", this, "Cancel" );
  203. SetBlockDragChaining( true );
  204. LoadControlSettingsAndUserConfig( "resource/pickerframe.res" );
  205. SetTitle( pTitle, false );
  206. }
  207. CPickerFrame::~CPickerFrame()
  208. {
  209. CleanUpMessage();
  210. }
  211. //-----------------------------------------------------------------------------
  212. // Deletes the message
  213. //-----------------------------------------------------------------------------
  214. void CPickerFrame::CleanUpMessage()
  215. {
  216. if ( m_pContextKeyValues )
  217. {
  218. m_pContextKeyValues->deleteThis();
  219. m_pContextKeyValues = NULL;
  220. }
  221. }
  222. //-----------------------------------------------------------------------------
  223. // Purpose: Activate the dialog
  224. //-----------------------------------------------------------------------------
  225. void CPickerFrame::DoModal( const PickerList_t &list, KeyValues *pContextKeyValues )
  226. {
  227. CleanUpMessage();
  228. m_pContextKeyValues = pContextKeyValues;
  229. m_pPicker->SetStringList( list );
  230. BaseClass::DoModal();
  231. }
  232. //-----------------------------------------------------------------------------
  233. // On command
  234. //-----------------------------------------------------------------------------
  235. void CPickerFrame::OnCommand( const char *pCommand )
  236. {
  237. if ( !Q_stricmp( pCommand, "Open" ) )
  238. {
  239. KeyValues *pActionKeys = new KeyValues( "Picked" );
  240. pActionKeys->SetInt( "choiceIndex", m_pPicker->GetSelectedIndex( ) );
  241. if ( m_pPicker->GetSelectionType() == PICKER_CHOICE_STRING )
  242. {
  243. const char *pPickerName = m_pPicker->GetSelectedString( );
  244. pActionKeys->SetString( "choice", pPickerName );
  245. }
  246. else
  247. {
  248. void *pPickerPtr = m_pPicker->GetSelectedPtr( );
  249. pActionKeys->SetPtr( "choice", pPickerPtr );
  250. }
  251. if ( m_pContextKeyValues )
  252. {
  253. pActionKeys->AddSubKey( m_pContextKeyValues );
  254. m_pContextKeyValues = NULL;
  255. }
  256. PostActionSignal( pActionKeys );
  257. CloseModal();
  258. return;
  259. }
  260. if ( !Q_stricmp( pCommand, "Cancel" ) )
  261. {
  262. CloseModal();
  263. return;
  264. }
  265. BaseClass::OnCommand( pCommand );
  266. }