UiTextInputComponent.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <LyShine/Bus/UiInteractableBus.h>
  10. #include <LyShine/Bus/UiTextInputBus.h>
  11. #include <LyShine/Bus/UiInitializationBus.h>
  12. #include <LyShine/UiComponentTypes.h>
  13. #include "UiInteractableComponent.h"
  14. #include <AzCore/Serialization/SerializeContext.h>
  15. #include <AzCore/Math/Vector3.h>
  16. #include <LmbrCentral/Rendering/TextureAsset.h>
  17. ////////////////////////////////////////////////////////////////////////////////////////////////////
  18. class UiTextInputComponent
  19. : public UiInteractableComponent
  20. , public UiInitializationBus::Handler
  21. , public UiTextInputBus::Handler
  22. {
  23. public: //types
  24. using EntityComboBoxVec = AZStd::vector < AZStd::pair<AZ::EntityId, AZStd::string> >;
  25. public: // member functions
  26. AZ_COMPONENT(UiTextInputComponent, LyShine::UiTextInputComponentUuid, AZ::Component);
  27. UiTextInputComponent();
  28. ~UiTextInputComponent() override;
  29. // UiInteractableInterface
  30. bool HandlePressed(AZ::Vector2 point, bool& shouldStayActive) override;
  31. bool HandleReleased(AZ::Vector2 point) override;
  32. bool HandleEnterPressed(bool& shouldStayActive) override;
  33. bool HandleEnterReleased() override;
  34. bool HandleAutoActivation() override;
  35. bool HandleTextInput(const AZStd::string& textUTF8) override;
  36. bool HandleKeyInputBegan(const AzFramework::InputChannel::Snapshot& inputSnapshot, AzFramework::ModifierKeyMask activeModifierKeys) override;
  37. void InputPositionUpdate(AZ::Vector2 point) override;
  38. void LostActiveStatus() override;
  39. // ~UiInteractableInterface
  40. // UiCanvasUpdateNotification
  41. void Update(float deltaTime) override;
  42. // ~UiCanvasUpdateNotification
  43. // UiInitializationInterface
  44. void InGamePostActivate() override;
  45. // ~UiInitializationInterface
  46. // UiTextInputInterface
  47. bool GetIsPasswordField() override;
  48. void SetIsPasswordField(bool passwordField) override;
  49. uint32_t GetReplacementCharacter() override;
  50. void SetReplacementCharacter(uint32_t replacementChar) override;
  51. AZ::Color GetTextSelectionColor() override;
  52. void SetTextSelectionColor(const AZ::Color& color) override;
  53. AZ::Color GetTextCursorColor() override;
  54. void SetTextCursorColor(const AZ::Color& color) override;
  55. float GetCursorBlinkInterval() override;
  56. void SetCursorBlinkInterval(float interval) override;
  57. int GetMaxStringLength() override;
  58. void SetMaxStringLength(int maxCharacters) override;
  59. TextInputCallback GetOnChangeCallback() override;
  60. void SetOnChangeCallback(TextInputCallback callbackFunction) override;
  61. TextInputCallback GetOnEndEditCallback() override;
  62. void SetOnEndEditCallback(TextInputCallback callbackFunction) override;
  63. TextInputCallback GetOnEnterCallback() override;
  64. void SetOnEnterCallback(TextInputCallback callbackFunction) override;
  65. const LyShine::ActionName& GetChangeAction() override;
  66. void SetChangeAction(const LyShine::ActionName& actionName) override;
  67. const LyShine::ActionName& GetEndEditAction() override;
  68. void SetEndEditAction(const LyShine::ActionName& actionName) override;
  69. const LyShine::ActionName& GetEnterAction() override;
  70. void SetEnterAction(const LyShine::ActionName& actionName) override;
  71. AZ::EntityId GetTextEntity() override;
  72. void SetTextEntity(AZ::EntityId textEntity) override;
  73. AZStd::string GetText() override;
  74. void SetText(const AZStd::string& text) override;
  75. AZ::EntityId GetPlaceHolderTextEntity() override;
  76. void SetPlaceHolderTextEntity(AZ::EntityId textEntity) override;
  77. bool GetIsClipboardEnabled() override;
  78. void SetIsClipboardEnabled(bool enableClipboard) override;
  79. // ~UiTextInputInterface
  80. protected: // member functions
  81. // AZ::Component
  82. void Activate() override;
  83. void Deactivate() override;
  84. // ~AZ::Component
  85. // UiInteractableComponent
  86. bool IsAutoActivationSupported() override;
  87. // ~UiInteractableComponent
  88. void BeginEditState();
  89. void EndEditState();
  90. float GetValidDragDistanceInPixels(AZ::Vector2 startPoint, AZ::Vector2 endPoint);
  91. void CheckForDragOrHandOffToParent(AZ::Vector2 point);
  92. //! Changes the DisplayedTextFunction callback of our child m_textEntity
  93. //! If m_isPasswordField is true, we assign a callback that replaces the contents
  94. //! of the displayed string with our m_replacementCharacter, otherwise we assign a
  95. //! null callback (default behavior).
  96. void UpdateDisplayedTextFunction();
  97. void OnReplacementCharacterChange();
  98. EntityComboBoxVec PopulateTextEntityList();
  99. UiInteractableStatesInterface::State ComputeInteractableState() override;
  100. protected: // static member functions
  101. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  102. {
  103. provided.push_back(AZ_CRC_CE("UiInteractableService"));
  104. provided.push_back(AZ_CRC_CE("UiNavigationService"));
  105. provided.push_back(AZ_CRC_CE("UiStateActionsService"));
  106. }
  107. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  108. {
  109. incompatible.push_back(AZ_CRC_CE("UiInteractableService"));
  110. incompatible.push_back(AZ_CRC_CE("UiNavigationService"));
  111. incompatible.push_back(AZ_CRC_CE("UiStateActionsService"));
  112. }
  113. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  114. {
  115. required.push_back(AZ_CRC_CE("UiElementService"));
  116. required.push_back(AZ_CRC_CE("UiTransformService"));
  117. }
  118. static void Reflect(AZ::ReflectContext* context);
  119. private: // member functions
  120. AZ_DISABLE_COPY_MOVE(UiTextInputComponent);
  121. //! Change text and notify listeners
  122. void ChangeText(const AZStd::string& textString);
  123. //! Make cursor visible when a change in text or cursor position has occurred
  124. void ResetCursorBlink();
  125. uint GetMultiByteCharLength(const AZStd::string& textString);
  126. void CheckStartTextInput();
  127. private: // static member functions
  128. static bool VersionConverter(AZ::SerializeContext& context,
  129. AZ::SerializeContext::DataElementNode& classElement);
  130. private: // data
  131. bool m_isDragging;
  132. bool m_isEditing;
  133. bool m_isTextInputStarted;
  134. int m_textCursorPos; //!< UTF8 element/character index into rendered string.
  135. int m_textSelectionStartPos; //!< UTF8 index that will different in value from m_textCursorPos
  136. //!< if a range of text is currently selected.
  137. float m_cursorBlinkStartTime;
  138. // We use EntityIds for the text and placeholder entities so the the reflection
  139. // system can save and load the references.
  140. AZ::EntityId m_textEntity;
  141. AZ::EntityId m_placeHolderTextEntity;
  142. AZ::Color m_textSelectionColor;
  143. AZ::Color m_textCursorColor;
  144. int m_maxStringLength;
  145. float m_cursorBlinkInterval;
  146. bool m_childTextStateDirtyFlag;
  147. TextInputCallback m_onChange;
  148. TextInputCallback m_onEndEdit;
  149. TextInputCallback m_onEnter;
  150. LyShine::ActionName m_changeAction;
  151. LyShine::ActionName m_endEditAction;
  152. LyShine::ActionName m_enterAction;
  153. uint32_t m_replacementCharacter; //!< If this component is configured as a password field (m_isPasswordField),
  154. //!< then we'll use this UTF8 character to replace the contents of the m_textEntity
  155. //!< string when we render (note that the string contents of m_textEntity
  156. //!< remain unaltered and this only affects rendering).
  157. bool m_isPasswordField; //!< True if m_textEntity should be treated as a password field, false otherwise
  158. bool m_clipInputText; //!< True if input text should be visually clipped to child text element, false otherwise.
  159. bool m_enableClipboard; //!< True if copy/cut/paste should be supported, false otherwise.
  160. };