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.

504 lines
12 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "dme_controls/AttributeTextEntry.h"
  9. #include "tier1/KeyValues.h"
  10. #include "vgui_controls/Menu.h"
  11. #include "datamodel/dmelement.h"
  12. #include "dme_controls/AttributeTextPanel.h"
  13. #include "vgui/MouseCode.h"
  14. #include "vgui/KeyCode.h"
  15. #include "vgui/IInput.h"
  16. #include "movieobjects/dmeeditortypedictionary.h"
  17. #include "dme_controls/inotifyui.h"
  18. using namespace vgui;
  19. // ----------------------------------------------------------------------------
  20. // CAttributeTextEntry
  21. CAttributeTextEntry::CAttributeTextEntry( Panel *parent, const char *panelName ) :
  22. BaseClass( parent, panelName ),
  23. m_bValueStored( false ),
  24. m_flOriginalValue( 0.0f )
  25. {
  26. SetDragEnabled( true );
  27. SetDropEnabled( true, 0.5f );
  28. m_szOriginalText[ 0 ] = 0;
  29. AddActionSignalTarget( this );
  30. }
  31. void CAttributeTextEntry::ApplySchemeSettings( IScheme *pScheme )
  32. {
  33. BaseClass::ApplySchemeSettings( pScheme );
  34. SetBorder(NULL);
  35. //HFont font = pScheme->GetFont( "DmePropertyVerySmall", IsProportional() );
  36. //SetFont(font);
  37. }
  38. //-----------------------------------------------------------------------------
  39. // Returns the parent panel
  40. //-----------------------------------------------------------------------------
  41. inline CAttributeTextPanel *CAttributeTextEntry::GetParentAttributePanel()
  42. {
  43. return static_cast< CAttributeTextPanel * >( GetParent() );
  44. }
  45. //-----------------------------------------------------------------------------
  46. // Drag + drop
  47. //-----------------------------------------------------------------------------
  48. bool CAttributeTextEntry::GetDropContextMenu( Menu *menu, CUtlVector< KeyValues * >& msglist )
  49. {
  50. menu->AddMenuItem( "Drop as Text", "#BxDropText", "droptext", this );
  51. return true;
  52. }
  53. bool CAttributeTextEntry::IsDroppable( CUtlVector< KeyValues * >& msglist )
  54. {
  55. if ( !IsEnabled() )
  56. return false;
  57. if ( msglist.Count() != 1 )
  58. return false;
  59. KeyValues *msg = msglist[ 0 ];
  60. Panel *draggedPanel = ( Panel * )msg->GetPtr( "panel", NULL );
  61. if ( draggedPanel == GetParent() )
  62. return false;
  63. CAttributeTextPanel *pPanel = GetParentAttributePanel();
  64. if ( !pPanel )
  65. return false;
  66. // If a specific text type is specified, then filter if it doesn't match
  67. const char *pTextType = pPanel->GetTextType();
  68. if ( pTextType[0] )
  69. {
  70. const char *pMsgTextType = msg->GetString( "texttype" );
  71. if ( Q_stricmp( pTextType, pMsgTextType ) )
  72. return false;
  73. }
  74. DmAttributeType_t t = pPanel->GetAttributeType();
  75. switch ( t )
  76. {
  77. default:
  78. break;
  79. case AT_ELEMENT:
  80. {
  81. CDmElement *ptr = reinterpret_cast< CDmElement * >( g_pDataModel->GetElement( DmElementHandle_t( msg->GetInt( "root" ) ) ) );
  82. if ( ptr )
  83. {
  84. return true;
  85. }
  86. return false;
  87. }
  88. break;
  89. case AT_ELEMENT_ARRAY:
  90. return false;
  91. }
  92. return true;
  93. }
  94. void CAttributeTextEntry::OnPanelDropped( CUtlVector< KeyValues * >& msglist )
  95. {
  96. if ( msglist.Count() != 1 )
  97. return;
  98. KeyValues *data = msglist[ 0 ];
  99. Panel *draggedPanel = ( Panel * )data->GetPtr( "panel", NULL );
  100. if ( draggedPanel == GetParent() )
  101. return;
  102. CAttributeTextPanel *pPanel = GetParentAttributePanel();
  103. if ( !pPanel )
  104. return;
  105. // If a specific text type is specified, then filter if it doesn't match
  106. const char *pTextType = pPanel->GetTextType();
  107. if ( pTextType[0] )
  108. {
  109. const char *pMsgTextType = data->GetString( "texttype" );
  110. if ( Q_stricmp( pTextType, pMsgTextType ) )
  111. return;
  112. }
  113. const char *cmd = data->GetString( "command" );
  114. if ( !Q_stricmp( cmd, "droptext" ) || !Q_stricmp( cmd, "default" ) )
  115. {
  116. DmAttributeType_t t = pPanel->GetAttributeType();
  117. switch ( t )
  118. {
  119. default:
  120. {
  121. pPanel->SetDirty( true );
  122. SetText( data->GetString( "text" ) );
  123. if ( pPanel->IsAutoApply() )
  124. {
  125. pPanel->Apply();
  126. }
  127. }
  128. break;
  129. case AT_ELEMENT:
  130. {
  131. CDmElement *ptr = reinterpret_cast< CDmElement * >( g_pDataModel->GetElement( DmElementHandle_t( data->GetInt( "root" ) ) ) );
  132. if ( !ptr )
  133. {
  134. break;
  135. }
  136. pPanel->SetDirty( true );
  137. SetText( data->GetString( "text" ) );
  138. if ( pPanel->IsAutoApply() )
  139. {
  140. pPanel->Apply();
  141. }
  142. }
  143. break;
  144. case AT_ELEMENT_ARRAY:
  145. Assert( 0 );
  146. break;
  147. }
  148. }
  149. StoreInitialValue( true );
  150. }
  151. //-----------------------------------------------------------------------------
  152. // Enter causes changes to be applied
  153. //-----------------------------------------------------------------------------
  154. void CAttributeTextEntry::OnKeyCodeTyped(KeyCode code)
  155. {
  156. bool bCtrl = (input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL));
  157. switch ( code )
  158. {
  159. case KEY_ENTER:
  160. {
  161. CAttributeTextPanel *pPanel = GetParentAttributePanel();
  162. if ( !pPanel->IsAutoApply() )
  163. {
  164. pPanel->Apply();
  165. StoreInitialValue( true );
  166. }
  167. else
  168. {
  169. WriteValueToAttribute();
  170. StoreInitialValue( true );
  171. }
  172. }
  173. break;
  174. // Override the base class undo feature, it behaves poorly when typing in data
  175. case KEY_Z:
  176. if ( bCtrl )
  177. {
  178. WriteInitialValueToAttribute( );
  179. break;
  180. }
  181. // NOTE: Fall through to default if it's not Ctrl-Z
  182. default:
  183. BaseClass::OnKeyCodeTyped(code);
  184. break;
  185. }
  186. }
  187. void CAttributeTextEntry::OnTextChanged( KeyValues *data )
  188. {
  189. m_bValueStored = true;
  190. }
  191. //-----------------------------------------------------------------------------
  192. // We'll only create an "undo" record if the values differ upon focus change
  193. //-----------------------------------------------------------------------------
  194. void CAttributeTextEntry::StoreInitialValue( bool bForce )
  195. {
  196. // Already storing value???
  197. if ( m_bValueStored && !bForce )
  198. return;
  199. m_bValueStored = true;
  200. CAttributeTextPanel *pPanel = GetParentAttributePanel();
  201. Assert( pPanel );
  202. switch ( pPanel->GetAttributeType() )
  203. {
  204. case AT_FLOAT:
  205. m_flOriginalValue = pPanel->GetAttributeValue<float>( );
  206. break;
  207. case AT_INT:
  208. m_nOriginalValue = pPanel->GetAttributeValue<int>( );
  209. break;
  210. case AT_BOOL:
  211. m_bOriginalValue = pPanel->GetAttributeValue<bool>( );
  212. break;
  213. default:
  214. GetText( m_szOriginalText, sizeof( m_szOriginalText ) );
  215. break;
  216. }
  217. }
  218. //-----------------------------------------------------------------------------
  219. // Performs undo
  220. //-----------------------------------------------------------------------------
  221. void CAttributeTextEntry::WriteInitialValueToAttribute( )
  222. {
  223. // Already storing value???
  224. if ( !m_bValueStored )
  225. return;
  226. CDisableUndoScopeGuard guard;
  227. CAttributeTextPanel *pPanel = GetParentAttributePanel();
  228. Assert( pPanel );
  229. switch ( pPanel->GetAttributeType() )
  230. {
  231. case AT_FLOAT:
  232. pPanel->SetAttributeValue( m_flOriginalValue );
  233. break;
  234. case AT_INT:
  235. pPanel->SetAttributeValue( m_nOriginalValue );
  236. break;
  237. case AT_BOOL:
  238. pPanel->SetAttributeValue<bool>( m_bOriginalValue );
  239. break;
  240. default:
  241. pPanel->SetAttributeValueFromString( m_szOriginalText );
  242. break;
  243. }
  244. pPanel->SetDirty( false );
  245. pPanel->Refresh();
  246. }
  247. //-----------------------------------------------------------------------------
  248. // We'll only create an "undo" record if the values differ upon focus change
  249. //-----------------------------------------------------------------------------
  250. void CAttributeTextEntry::OnSetFocus()
  251. {
  252. BaseClass::OnSetFocus();
  253. StoreInitialValue();
  254. }
  255. //-----------------------------------------------------------------------------
  256. // Called when focus is lost
  257. //-----------------------------------------------------------------------------
  258. template<class T>
  259. void CAttributeTextEntry::ApplyMouseWheel( T newValue, T originalValue )
  260. {
  261. CAttributeTextPanel *pPanel = GetParentAttributePanel();
  262. // Kind of an evil hack, but "undo" copies the "old value" off for doing undo, and that value is the new value because
  263. // we haven't been tracking undo while manipulating this. So we'll turn off undo and set the value to the original value.
  264. // In effect, all of the wheeling will drop out and it'll look just like we started at the original value and ended up at the
  265. // final value...
  266. {
  267. CDisableUndoScopeGuard guard;
  268. pPanel->SetAttributeValue( originalValue );
  269. }
  270. if ( pPanel->IsAutoApply() )
  271. {
  272. pPanel->Apply();
  273. }
  274. else
  275. {
  276. CElementTreeUndoScopeGuard guard( 0, pPanel->GetNotify(), "Set Attribute Value", "Set Attribute Value" );
  277. pPanel->SetAttributeValue( newValue );
  278. }
  279. }
  280. void CAttributeTextEntry::WriteValueToAttribute()
  281. {
  282. if ( !m_bValueStored )
  283. return;
  284. m_bValueStored = false;
  285. char newText[ MAX_TEXT_LENGTH ];
  286. GetText( newText, sizeof( newText ) );
  287. CAttributeTextPanel *pPanel = GetParentAttributePanel();
  288. Assert( pPanel );
  289. switch (pPanel->GetAttributeType() )
  290. {
  291. case AT_FLOAT:
  292. ApplyMouseWheel( (float)atof(newText), m_flOriginalValue );
  293. break;
  294. case AT_INT:
  295. ApplyMouseWheel( atoi(newText), m_nOriginalValue );
  296. break;
  297. case AT_BOOL:
  298. ApplyMouseWheel( atoi(newText) != 0, m_bOriginalValue );
  299. break;
  300. default:
  301. if ( Q_strcmp( newText, m_szOriginalText ) )
  302. {
  303. pPanel->SetDirty( true );
  304. if ( pPanel->IsAutoApply() )
  305. {
  306. pPanel->Apply();
  307. StoreInitialValue( true );
  308. }
  309. }
  310. else
  311. {
  312. pPanel->SetDirty( false );
  313. }
  314. break;
  315. }
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Called when focus is lost
  319. //-----------------------------------------------------------------------------
  320. void CAttributeTextEntry::OnKillFocus()
  321. {
  322. BaseClass::OnKillFocus();
  323. if ( !IsEnabled() )
  324. return; // don't bother writing data if this attribute is read-only or being driven by a channel
  325. WriteValueToAttribute();
  326. StoreInitialValue();
  327. }
  328. void CAttributeTextEntry::OnMouseWheeled( int delta )
  329. {
  330. // Must have *keyboard* focus for it to work, and alse be writeable and not driven by a channel
  331. if ( !HasFocus() || !IsEnabled() )
  332. {
  333. // Otherwise, let the base class scroll up + down
  334. BaseClass::OnMouseWheeled( delta );
  335. return;
  336. }
  337. CAttributeTextPanel *pPanel = GetParentAttributePanel();
  338. if ( pPanel->GetDirty() )
  339. {
  340. if ( pPanel->IsAutoApply() )
  341. {
  342. pPanel->Apply();
  343. StoreInitialValue( true );
  344. }
  345. else
  346. {
  347. // FIXME: Make this work for non-auto-apply panels
  348. }
  349. }
  350. switch ( pPanel->GetAttributeType() )
  351. {
  352. case AT_FLOAT:
  353. {
  354. float deltaFactor;
  355. if ( input()->IsKeyDown(KEY_LSHIFT) )
  356. {
  357. deltaFactor = ((float)delta) * 10.0f;
  358. }
  359. else if ( input()->IsKeyDown(KEY_LCONTROL) )
  360. {
  361. deltaFactor = ((float)delta) / 100.0;
  362. }
  363. else
  364. {
  365. deltaFactor = ((float)delta) / 10.0;
  366. }
  367. float val = pPanel->GetAttributeValue<float>() + deltaFactor;
  368. if ( input()->IsKeyDown(KEY_LALT) )
  369. {
  370. //val = clamp(val, 0.0, 1.0);
  371. val = (val > 1) ? 1 : ((val < 0) ? 0 : val);
  372. }
  373. {
  374. // Note, these calls to Set won't create Undo Records,
  375. // since we'll check the value in SetFocus/KillFocus so that we
  376. // don't gum up the undo system with hundreds of records...
  377. CDisableUndoScopeGuard guard;
  378. pPanel->SetAttributeValue( val );
  379. }
  380. }
  381. break;
  382. case AT_INT:
  383. {
  384. if ( input()->IsKeyDown(KEY_LSHIFT) )
  385. {
  386. delta *= 10;
  387. }
  388. int val = pPanel->GetAttributeValue<int>() + delta;
  389. {
  390. // Note, these calls to Set won't create Undo Records,
  391. // since we'll check the value in SetFocus/KillFocus so that we
  392. // don't gum up the undo system with hundreds of records...
  393. CDisableUndoScopeGuard guard;
  394. pPanel->SetAttributeValue( val );
  395. }
  396. }
  397. break;
  398. case AT_BOOL:
  399. {
  400. bool val = !pPanel->GetAttributeValue<bool>();
  401. {
  402. // Note, these calls to Set won't create Undo Records,
  403. // since we'll check the value in SetFocus/KillFocus so that we
  404. // don't gum up the undo system with hundreds of records...
  405. CDisableUndoScopeGuard guard;
  406. pPanel->SetAttributeValue( val );
  407. }
  408. }
  409. break;
  410. default:
  411. return;
  412. }
  413. pPanel->Refresh();
  414. if ( pPanel->IsAutoApply() )
  415. {
  416. // NOTE: Don't call Apply since that generates an undo record
  417. CElementTreeNotifyScopeGuard notify( "CAttributeTextEntry::OnMouseWheeled", NOTIFY_CHANGE_ATTRIBUTE_VALUE | NOTIFY_SETDIRTYFLAG, pPanel->GetNotify() );
  418. }
  419. else
  420. {
  421. pPanel->SetDirty( true );
  422. }
  423. //SetDirty(true);
  424. //UpdateTime( m_flLastMouseTime );
  425. //UpdateZoom( -10.0f * delta );
  426. //UpdateTransform();
  427. }
  428. // ----------------------------------------------------------------------------