diff --git a/Src/IAEngine/imp/cpp/Components/SpriteRenderer.cpp b/Src/IAEngine/imp/cpp/Components/SpriteRenderer.cpp index a167e0c..a17fe54 100644 --- a/Src/IAEngine/imp/cpp/Components/SpriteRenderer.cpp +++ b/Src/IAEngine/imp/cpp/Components/SpriteRenderer.cpp @@ -26,7 +26,8 @@ namespace ia::iae SpriteRendererComponent::AnimationKeyFrame SpriteRendererComponent::GetKeyFrame(IN INT32 index) { index %= m_activeAnimation.Keys.size(); - return m_reverseAnimation ? m_activeAnimation.Keys[m_activeAnimation.Keys.size() - 1 - index] : m_activeAnimation.Keys[index]; + return m_reverseAnimation ? m_activeAnimation.Keys[m_activeAnimation.Keys.size() - 1 - index] + : m_activeAnimation.Keys[index]; } SpriteRendererComponent::SpriteRendererComponent(IN Node *node) : TextureRendererComponent(node) @@ -44,13 +45,24 @@ namespace ia::iae VOID SpriteRendererComponent::BakeAnimations() { if (m_animations.size()) - SetActiveAnimation(0); + ForceSetActiveAnimation(0); + } + + VOID SpriteRendererComponent::SetAnimationFrame(IN INT32 animation, IN INT32 frame) + { + m_activeAnimation = {}; + m_currentAnimationState = m_animations[animation].Keys[frame]; } VOID SpriteRendererComponent::SetActiveAnimation(IN Handle animation) { if (animation == m_activeAnimationHandle) return; + ForceSetActiveAnimation(animation); + } + + VOID SpriteRendererComponent::ForceSetActiveAnimation(IN Handle animation) + { IA_RELEASE_ASSERT((animation != INVALID_HANDLE) && (animation < m_animations.size())); m_prevAnimationKeyFrameIndex = 0; m_activeAnimation = m_animations[animation]; @@ -62,7 +74,8 @@ namespace ia::iae m_activeAnimationHandle = animation; CurrentTexture() = m_currentAnimationState.Texture; - m_node->DrawnSize() = m_node->GetScale() * m_currentAnimationState.Texture.GetExtent() * m_currentAnimationState.Scale; + m_node->DrawnSize() = + m_node->GetScale() * m_currentAnimationState.Texture.GetExtent() * m_currentAnimationState.Scale; } VOID SpriteRendererComponent::Update() @@ -84,7 +97,7 @@ namespace ia::iae VOID SpriteRendererComponent::UpdateAnimation() { const auto keyCount = m_activeAnimation.Keys.size(); - if (!keyCount) + if (keyCount <= 1) return; if (m_currentAnimationState.ShouldInterpolate) diff --git a/Src/IAEngine/imp/cpp/Input.cpp b/Src/IAEngine/imp/cpp/Input.cpp index b61eb7d..ec04e47 100644 --- a/Src/IAEngine/imp/cpp/Input.cpp +++ b/Src/IAEngine/imp/cpp/Input.cpp @@ -20,6 +20,8 @@ namespace ia::iae { + EXTERN SDL_Window *g_windowHandle; + struct InputDirection { glm::vec2 Velocity{}; @@ -29,15 +31,15 @@ namespace ia::iae STATIC CONSTEXPR InputDirection INPUT_TO_DIRECTION_MAP[] = { {glm::vec2{0.0f, 0.0f}, Input::DirectionalInput::NONE}, /* 0 */ {glm::vec2{1.0f, 0.0f}, Input::DirectionalInput::RIGHT}, /* D */ - {glm::vec2{-1.0f, 0.0f}, Input::DirectionalInput::LEFT}, /* A */ + {glm::vec2{-1.0f, 0.0f}, Input::DirectionalInput::LEFT}, /* A */ {glm::vec2{0.0f, 0.0f}, Input::DirectionalInput::NONE}, /* A, D */ {glm::vec2{0.0f, 1.0f}, Input::DirectionalInput::DOWN}, /* S */ {glm::vec2{1.0f, 1.0f}, Input::DirectionalInput::DOWN_RIGHT}, /* S, D */ - {glm::vec2{-1.0f, 1.0f}, Input::DirectionalInput::DOWN_LEFT}, /* S, A */ + {glm::vec2{-1.0f, 1.0f}, Input::DirectionalInput::DOWN_LEFT}, /* S, A */ {glm::vec2{0.0f, 0.0f}, Input::DirectionalInput::NONE}, /* S, A, D */ - {glm::vec2{0.0f, -1.0f}, Input::DirectionalInput::UP}, /* W */ - {glm::vec2{1.0f, -1.0f}, Input::DirectionalInput::UP_RIGHT}, /* W, D */ - {glm::vec2{-1.0f, -1.0f}, Input::DirectionalInput::UP_LEFT}, /* W, A */ + {glm::vec2{0.0f, -1.0f}, Input::DirectionalInput::UP}, /* W */ + {glm::vec2{1.0f, -1.0f}, Input::DirectionalInput::UP_RIGHT}, /* W, D */ + {glm::vec2{-1.0f, -1.0f}, Input::DirectionalInput::UP_LEFT}, /* W, A */ {glm::vec2{0.0f, 0.0f}, Input::DirectionalInput::NONE}, /* W, A, D */ {glm::vec2{0.0f, 0.0f}, Input::DirectionalInput::NONE}, /* W, S */ {glm::vec2{0.0f, 0.0f}, Input::DirectionalInput::NONE}, /* W, S, D */ @@ -82,4 +84,14 @@ namespace ia::iae direction = dir.Direction; return dir.Velocity; } + + VOID Input::StartTextInput() + { + SDL_StartTextInput(g_windowHandle); + } + + VOID Input::StopTextInput() + { + SDL_StopTextInput(g_windowHandle); + } } // namespace ia::iae \ No newline at end of file diff --git a/Src/IAEngine/imp/cpp/Rendering/Renderer.cpp b/Src/IAEngine/imp/cpp/Rendering/Renderer.cpp index f7fe56e..19df879 100644 --- a/Src/IAEngine/imp/cpp/Rendering/Renderer.cpp +++ b/Src/IAEngine/imp/cpp/Rendering/Renderer.cpp @@ -175,10 +175,10 @@ namespace ia::iae g_meshHandleQuad = CreateMesh( { - {glm::vec3{-1, 1, 0}, glm::vec2{0, 1}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, + {glm::vec3{0, 1, 0}, glm::vec2{0, 1}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, {glm::vec3{1, 1, 0}, glm::vec2{1, 1}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, - {glm::vec3{1, -1, 0}, glm::vec2{1, 0}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, - {glm::vec3{-1, -1, 0}, glm::vec2{0, 0}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, + {glm::vec3{1, 0, 0}, glm::vec2{1, 0}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, + {glm::vec3{0, 0, 0}, glm::vec2{0, 0}, glm::vec4{1.0f, 1.0f, 1.0f, 1.0f}}, }, {0, 1, 2, 2, 3, 0}); diff --git a/Src/IAEngine/imp/cpp/UI.cpp b/Src/IAEngine/imp/cpp/UI.cpp index f71b525..8fa7168 100644 --- a/Src/IAEngine/imp/cpp/UI.cpp +++ b/Src/IAEngine/imp/cpp/UI.cpp @@ -329,6 +329,30 @@ namespace ia::iae m_clickCallbacks[elementId] = callback; } + VOID AddHoverEnterListener(IN PCCHAR elementId, IN std::function callback) + { + m_document->GetElementById(elementId)->AddEventListener("mouseover", this); + m_hoverEnterCallbacks[elementId] = callback; + } + + VOID AddHoverExitListener(IN PCCHAR elementId, IN std::function callback) + { + m_document->GetElementById(elementId)->AddEventListener("mouseout", this); + m_hoverExitCallbacks[elementId] = callback; + } + + VOID AddPointerDownListener(IN PCCHAR elementId, IN std::function callback) + { + m_document->GetElementById(elementId)->AddEventListener("mousedown", this); + m_pointerDownCallbacks[elementId] = callback; + } + + VOID AddPointerUpListener(IN PCCHAR elementId, IN std::function callback) + { + m_document->GetElementById(elementId)->AddEventListener("mouseup", this); + m_pointerUpCallbacks[elementId] = callback; + } + VOID ProcessEvent(IN Rml::Event &event) { switch (event.GetId()) @@ -337,6 +361,22 @@ namespace ia::iae m_clickCallbacks[event.GetTargetElement()->GetId().c_str()](); break; + case Rml::EventId::Mouseover: + m_hoverEnterCallbacks[event.GetTargetElement()->GetId().c_str()](); + break; + + case Rml::EventId::Mouseout: + m_hoverExitCallbacks[event.GetTargetElement()->GetId().c_str()](); + break; + + case Rml::EventId::Mousedown: + m_pointerDownCallbacks[event.GetTargetElement()->GetId().c_str()](); + break; + + case Rml::EventId::Mouseup: + m_pointerUpCallbacks[event.GetTargetElement()->GetId().c_str()](); + break; + default: break; } @@ -345,6 +385,10 @@ namespace ia::iae private: Rml::ElementDocument *CONST m_document; Map> m_clickCallbacks; + Map> m_hoverEnterCallbacks; + Map> m_hoverExitCallbacks; + Map> m_pointerDownCallbacks; + Map> m_pointerUpCallbacks; }; } // namespace ia::iae @@ -418,6 +462,9 @@ namespace ia::iae case SDL_EventType::SDL_EVENT_KEY_UP: g_context->ProcessKeyUp(SDLKeyToRml(event->key.key), keymods); break; + case SDL_EventType::SDL_EVENT_TEXT_INPUT: + g_context->ProcessTextInput(Rml::String(&event->text.text[0])); + break; } } @@ -466,10 +513,42 @@ namespace ia::iae g_eventListeners[handle]->AddClickListener(elementId, callback); } + VOID UI::AddHoverEnterEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback) + { + g_eventListeners[handle]->AddHoverEnterListener(elementId, callback); + } + + VOID UI::AddHoverExitEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback) + { + g_eventListeners[handle]->AddHoverExitListener(elementId, callback); + } + + VOID UI::AddPointerDownEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback) + { + g_eventListeners[handle]->AddPointerDownListener(elementId, callback); + } + + VOID UI::AddPointerUpEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback) + { + g_eventListeners[handle]->AddPointerUpListener(elementId, callback); + } + String UI::GetInputValue(IN INT32 index) { return g_mainDataModel.InputValues[index].c_str(); } + + VOID UI::SetInputValue(IN INT32 index, IN CONST String &value) + { + g_mainDataModel.InputValues[index] = Rml::String(value.c_str()); + } + + VOID UI::DestroyWindow(IN Handle handle) + { + const auto w = reinterpret_cast(handle); + w->Hide(); + w->Close(); + } } // namespace ia::iae namespace ia::iae @@ -496,9 +575,10 @@ namespace ia::iae Renderer::SetState_CameraRelative(false); Renderer::SetState_TextureOffset(0, 0); if (texture) - Renderer::Draw(geometry, g_textures[texture - 1].GetHandle(), {translation.x, translation.y}, {1.0f, 1.0f}); + Renderer::Draw(geometry, g_textures[texture - 1].GetHandle(), {translation.x, translation.y}, {1.0f, 1.0f}, + 0.0f, Renderer::MAX_LAYER_INDEX); else - Renderer::Draw(geometry, 0, {translation.x, translation.y}, {1.0f, 1.0f}); + Renderer::Draw(geometry, 0, {translation.x, translation.y}, {1.0f, 1.0f}, 0.0f, Renderer::MAX_LAYER_INDEX); } void RmlUIRenderInterface::ReleaseGeometry(Rml::CompiledGeometryHandle geometry) @@ -507,8 +587,7 @@ namespace ia::iae Rml::TextureHandle RmlUIRenderInterface::LoadTexture(Rml::Vector2i &texture_dimensions, const Rml::String &source) { - g_textures.pushBack( - Engine::CreateTexture(File::ReadToVector(source.c_str()))); + g_textures.pushBack(Engine::CreateTexture(File::ReadToVector(source.c_str()))); return g_textures.size(); } diff --git a/Src/IAEngine/inc/IAEngine/Components/SpriteRenderer.hpp b/Src/IAEngine/inc/IAEngine/Components/SpriteRenderer.hpp index 21cd731..e063509 100644 --- a/Src/IAEngine/inc/IAEngine/Components/SpriteRenderer.hpp +++ b/Src/IAEngine/inc/IAEngine/Components/SpriteRenderer.hpp @@ -50,6 +50,9 @@ namespace ia::iae VOID BakeAnimations(); VOID SetActiveAnimation(IN Handle animation); + VOID ForceSetActiveAnimation(IN Handle animation); + + VOID SetAnimationFrame(IN INT32 animation, IN INT32 frame); public: Vector &Animations() diff --git a/Src/IAEngine/inc/IAEngine/Input.hpp b/Src/IAEngine/inc/IAEngine/Input.hpp index 81fcf6f..6b51c59 100644 --- a/Src/IAEngine/inc/IAEngine/Input.hpp +++ b/Src/IAEngine/inc/IAEngine/Input.hpp @@ -270,6 +270,9 @@ namespace ia::iae STATIC VOID Initialize(); STATIC VOID OnEvent(IN PVOID event); + STATIC VOID StartTextInput(); + STATIC VOID StopTextInput(); + STATIC BOOL IsKeyDown(IN Key key) { return s_keys[(UINT8)key]; diff --git a/Src/IAEngine/inc/IAEngine/UI.hpp b/Src/IAEngine/inc/IAEngine/UI.hpp index 958dc1d..4c66869 100644 --- a/Src/IAEngine/inc/IAEngine/UI.hpp +++ b/Src/IAEngine/inc/IAEngine/UI.hpp @@ -27,11 +27,19 @@ namespace ia::iae STATIC Handle AddWindowFromFile(IN CONST String &path); + STATIC VOID DestroyWindow(IN Handle handle); + STATIC VOID ShowWindow(IN Handle handle); STATIC VOID HideWindow(IN Handle handle); STATIC String GetInputValue(IN INT32 index); + STATIC VOID SetInputValue(IN INT32 index, IN CONST String& value); + STATIC VOID AddClickEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback); + STATIC VOID AddHoverEnterEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback); + STATIC VOID AddHoverExitEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback); + STATIC VOID AddPointerDownEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback); + STATIC VOID AddPointerUpEvent(IN Handle handle, IN PCCHAR elementId, IN std::function callback); STATIC VOID EnableDebugger(); STATIC VOID DisableDebugger();