From dc439d69a55a03ab673301e222299ba002e6e53e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 15 Jan 2017 13:25:12 +0100 Subject: [PATCH 01/47] Sdk/Console: Turn console into a widget (WIP) --- SDK/include/NDK/Application.hpp | 6 +- SDK/include/NDK/Application.inl | 1 - SDK/include/NDK/Console.hpp | 37 ++--- SDK/include/NDK/Console.inl | 44 +----- SDK/src/NDK/Application.cpp | 13 +- SDK/src/NDK/Console.cpp | 228 ++++------------------------- SDK/src/NDK/Lua/LuaBinding_SDK.cpp | 15 +- 7 files changed, 58 insertions(+), 286 deletions(-) diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index b3f803fe1..cb94ad00c 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -17,6 +17,7 @@ #include #ifndef NDK_SERVER +#include #include #include #include @@ -83,7 +84,7 @@ namespace Ndk #ifndef NDK_SERVER struct ConsoleOverlay { - std::unique_ptr console; + Console* console; Nz::LuaInstance lua; NazaraSlot(Nz::EventHandler, OnEvent, eventSlot); @@ -116,10 +117,11 @@ namespace Ndk Nz::RenderTarget* renderTarget; std::unique_ptr window; std::unique_ptr console; + std::unique_ptr canvas; std::unique_ptr fpsCounter; std::unique_ptr overlayWorld; }; - + void SetupConsole(WindowInfo& info); void SetupFPSCounter(WindowInfo& info); void SetupOverlay(WindowInfo& info); diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index 0b4f2ce10..31ca1cff6 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -114,7 +114,6 @@ namespace Ndk } m_overlayFlags |= OverlayFlags_Console; - } else { diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index 59a98df0d..9c776f1ab 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace Nz @@ -26,13 +27,14 @@ namespace Ndk { class Console; class Entity; + class TextAreaWidget; using ConsoleHandle = Nz::ObjectHandle; - class NDK_API Console : public Nz::Node, public Nz::HandledObject + class NDK_API Console : public BaseWidget, public Nz::HandledObject { public: - Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance); + Console(BaseWidget* parent, Nz::LuaInstance& instance); Console(const Console& console) = delete; Console(Console&& console) = default; ~Console() = default; @@ -42,31 +44,22 @@ namespace Ndk void Clear(); inline unsigned int GetCharacterSize() const; - inline const EntityHandle& GetHistory() const; - inline const EntityHandle& GetHistoryBackground() const; - inline const EntityHandle& GetInput() const; - inline const EntityHandle& GetInputBackground() const; - inline const Nz::Vector2f& GetSize() const; + inline const TextAreaWidget* GetHistory() const; + inline const TextAreaWidget* GetInput() const; inline const Nz::FontRef& GetTextFont() const; - inline bool IsVisible() const; - - void SendCharacter(char32_t character); - void SendEvent(const Nz::WindowEvent& event); + void ResizeToContent() override; void SetCharacterSize(unsigned int size); - void SetSize(const Nz::Vector2f& size); void SetTextFont(Nz::FontRef font); - void Show(bool show = true); - Console& operator=(const Console& console) = delete; Console& operator=(Console&& console) = default; private: void AddLineInternal(const Nz::String& text, const Nz::Color& color = Nz::Color::White); void ExecuteInput(); - void Layout(); + void Layout() override; void RefreshHistory(); struct Line @@ -78,20 +71,10 @@ namespace Ndk std::size_t m_historyPosition; std::vector m_commandHistory; std::vector m_historyLines; - EntityOwner m_historyBackground; - EntityOwner m_history; - EntityOwner m_input; - EntityOwner m_inputBackground; + TextAreaWidget* m_history; + TextAreaWidget* m_input; Nz::FontRef m_defaultFont; Nz::LuaInstance& m_instance; - Nz::SpriteRef m_historyBackgroundSprite; - Nz::SpriteRef m_inputBackgroundSprite; - Nz::SimpleTextDrawer m_historyDrawer; - Nz::SimpleTextDrawer m_inputDrawer; - Nz::TextSpriteRef m_historyTextSprite; - Nz::TextSpriteRef m_inputTextSprite; - Nz::Vector2f m_size; - bool m_opened; unsigned int m_characterSize; unsigned int m_maxHistoryLines; }; diff --git a/SDK/include/NDK/Console.inl b/SDK/include/NDK/Console.inl index 94a6daf91..c8e825ebd 100644 --- a/SDK/include/NDK/Console.inl +++ b/SDK/include/NDK/Console.inl @@ -22,51 +22,21 @@ namespace Ndk * \return History of the console */ - inline const EntityHandle& Console::GetHistory() const + inline const TextAreaWidget* Console::GetHistory() const { return m_history; } - /*! - * \brief Gets the entity representing the background of the console's history - * \return Background history of the console - */ - - inline const EntityHandle& Console::GetHistoryBackground() const - { - return m_historyBackground; - } - /*! * \brief Gets the entity representing the input of the console * \return Input of the console */ - inline const EntityHandle& Console::GetInput() const + inline const TextAreaWidget* Console::GetInput() const { return m_input; } - /*! - * \brief Gets the entity representing the background of the console's input - * \return Background input of the console - */ - - inline const EntityHandle& Console::GetInputBackground() const - { - return m_inputBackground; - } - - /*! - * \brief Gets the size of the console - * \return Size (Width, Height) of the console - */ - - inline const Nz::Vector2f& Console::GetSize() const - { - return m_size; - } - /*! * \brief Gets the font used by the console * \return A reference to the font currenty used @@ -76,14 +46,4 @@ namespace Ndk { return m_defaultFont; } - - /*! - * \brief Checks whether the console is visible - * \return true If it is the case - */ - - inline bool Console::IsVisible() const - { - return m_opened; - } } diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index 4098b8a2b..caea4fd8f 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -147,13 +147,15 @@ namespace Ndk Nz::Vector2ui windowDimensions; if (info.window->IsValid()) - windowDimensions.Set(info.window->GetWidth(), info.window->GetHeight() / 4); + windowDimensions.Set(info.window->GetWidth(), info.window->GetHeight()); else windowDimensions.MakeZero(); - overlay->console = std::make_unique(*info.overlayWorld, Nz::Vector2f(windowDimensions), overlay->lua); + overlay->console = info.canvas->Add(overlay->lua); Console& consoleRef = *overlay->console; + consoleRef.SetSize({float(windowDimensions.x), windowDimensions.y / 4.f}); + consoleRef.Show(false); // Redirect logs toward the console overlay->logSlot.Connect(Nz::Log::OnLogWrite, [&consoleRef] (const Nz::String& str) @@ -197,11 +199,11 @@ namespace Ndk // Setup a few event callback to handle the console Nz::EventHandler& eventHandler = info.window->GetEventHandler(); - overlay->eventSlot.Connect(eventHandler.OnEvent, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent& event) + /*overlay->eventSlot.Connect(eventHandler.OnEvent, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent& event) { if (consoleRef.IsVisible()) consoleRef.SendEvent(event); - }); + });*/ overlay->keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& event) { @@ -233,6 +235,9 @@ namespace Ndk { info.overlayWorld = std::make_unique(false); //< No default system + if (info.window->IsValid()) + info.canvas = std::make_unique(info.overlayWorld->CreateHandle(), info.window->GetEventHandler()); + RenderSystem& renderSystem = info.overlayWorld->AddSystem(); renderSystem.ChangeRenderTechnique(); renderSystem.SetDefaultBackground(nullptr); diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 82d3d40af..78ff11b04 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include ///TODO: For now is unable to display different color in the history, it needs a RichTextDrawer to do so @@ -33,71 +34,24 @@ namespace Ndk * \param instance Lua instance that will interact with the world */ - Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance) : + Console::Console(BaseWidget* parent, Nz::LuaInstance& instance) : + BaseWidget(parent), m_historyPosition(0), m_defaultFont(Nz::Font::GetDefault()), m_instance(instance), - m_size(size), - m_opened(false), m_characterSize(24) { - Nz::MaterialRef backgroundMaterial = Nz::Material::New(); - backgroundMaterial->EnableBlending(true); - backgroundMaterial->EnableDepthBuffer(false); - backgroundMaterial->SetDstBlend(Nz::BlendFunc_InvSrcAlpha); - backgroundMaterial->SetSrcBlend(Nz::BlendFunc_SrcAlpha); - - // History bakckground - m_historyBackgroundSprite = Nz::Sprite::New(); - m_historyBackgroundSprite->SetColor(Nz::Color(80, 80, 160, 128)); - m_historyBackgroundSprite->SetMaterial(backgroundMaterial); - - m_historyBackground = world.CreateEntity(); - m_historyBackground->Enable(m_opened); - m_historyBackground->AddComponent().Attach(m_historyBackgroundSprite, -1); - m_historyBackground->AddComponent().SetParent(this); - // History - m_historyDrawer.SetCharacterSize(m_characterSize); - m_historyDrawer.SetColor(Nz::Color(200, 200, 200)); - m_historyDrawer.SetFont(m_defaultFont); - - m_historyTextSprite = Nz::TextSprite::New(); - - m_history = world.CreateEntity(); - m_history->Enable(m_opened); - m_history->AddComponent().Attach(m_historyTextSprite); - - Ndk::NodeComponent& historyNode = m_history->AddComponent(); - historyNode.SetParent(this); - - // Input background - m_inputBackgroundSprite = Nz::Sprite::New(); - m_inputBackgroundSprite->SetColor(Nz::Color(255, 255, 255, 200)); - m_inputBackgroundSprite->SetMaterial(backgroundMaterial); - - m_inputBackground = world.CreateEntity(); - m_inputBackground->Enable(m_opened); - m_inputBackground->AddComponent().Attach(m_inputBackgroundSprite, -1); - m_inputBackground->AddComponent().SetParent(this); + m_history = Add(); + m_history->EnableBackground(true); + m_history->SetReadOnly(true); + m_history->SetBackgroundColor(Nz::Color(80, 80, 160, 128)); // Input - m_inputDrawer.SetColor(Nz::Color::Black); - m_inputDrawer.SetCharacterSize(m_characterSize); - m_inputDrawer.SetFont(m_defaultFont); - m_inputDrawer.SetText(s_inputPrefix); - - m_inputTextSprite = Nz::TextSprite::New(); - m_inputTextSprite->Update(m_inputDrawer); - - m_input = world.CreateEntity(); - m_input->Enable(m_opened); - m_input->AddComponent().Attach(m_inputTextSprite); - - Ndk::NodeComponent& inputNode = m_input->AddComponent(); - inputNode.SetParent(this); - - Layout(); + m_input = Add(); + m_input->EnableBackground(true); + m_input->SetText(s_inputPrefix); + m_input->SetTextColor(Nz::Color::Black); } /*! @@ -123,90 +77,8 @@ namespace Ndk RefreshHistory(); } - /*! - * \brief Sends a character to the console - * - * \param character Character that will be added to the console - */ - - void Console::SendCharacter(char32_t character) + void Console::ResizeToContent() { - switch (character) - { - case '\b': - { - Nz::String input = m_inputDrawer.GetText(); - if (input.GetLength() <= s_inputPrefixSize) // Prevent removal of the input prefix - return; // Ignore if no user character is there - - input.Resize(-1, Nz::String::HandleUtf8); - m_inputDrawer.SetText(input); - break; - } - - case '\r': - case '\n': - ExecuteInput(); - break; - - default: - { - if (Nz::Unicode::GetCategory(character) == Nz::Unicode::Category_Other_Control) - return; - - m_inputDrawer.AppendText(Nz::String::Unicode(character)); - break; - } - } - - m_inputTextSprite->Update(m_inputDrawer); - } - - /*! - * \brief Sends an event to the console - * - * \param event Event to be takin into consideration by the console - */ - void Console::SendEvent(const Nz::WindowEvent& event) - { - switch (event.type) - { - case Nz::WindowEventType_TextEntered: - SendCharacter(event.text.character); - break; - - case Nz::WindowEventType_KeyPressed: - { - switch (event.key.code) - { - case Nz::Keyboard::Down: - case Nz::Keyboard::Up: - { - if (event.key.code == Nz::Keyboard::Up) - m_historyPosition = std::min(m_commandHistory.size(), m_historyPosition + 1); - else - { - if (m_historyPosition > 1) - m_historyPosition--; - else if (m_historyPosition == 0) - m_historyPosition = 1; - } - - Nz::String text = m_commandHistory[m_commandHistory.size() - m_historyPosition]; - m_inputDrawer.SetText(s_inputPrefix + text); - m_inputTextSprite->Update(m_inputDrawer); - break; - } - - default: - break; - } - break; - } - - default: - break; - } } /*! @@ -219,27 +91,14 @@ namespace Ndk { m_characterSize = size; - m_historyDrawer.SetCharacterSize(m_characterSize); - m_historyTextSprite->Update(m_historyDrawer); - m_inputDrawer.SetCharacterSize(m_characterSize); - m_inputTextSprite->Update(m_inputDrawer); + //m_historyDrawer.SetCharacterSize(m_characterSize); + //m_historyTextSprite->Update(m_historyDrawer); + //m_inputDrawer.SetCharacterSize(m_characterSize); + //m_inputTextSprite->Update(m_inputDrawer); Layout(); } - /*! - * \brief Sets the console size - * - * \param size (Width, Height) of the console - */ - - void Console::SetSize(const Nz::Vector2f& size) - { - m_size = size; - m_historyBackgroundSprite->SetSize(m_size); - Layout(); - } - /*! * \brief Sets the text font * @@ -253,31 +112,12 @@ namespace Ndk NazaraAssert(font && font->IsValid(), "Invalid font"); m_defaultFont = std::move(font); - m_historyDrawer.SetFont(m_defaultFont); - m_inputDrawer.SetFont(m_defaultFont); + //m_historyDrawer.SetFont(m_defaultFont); + //m_inputDrawer.SetFont(m_defaultFont); Layout(); } - /*! - * \brief Shows the console - * - * \param show Should the console be showed - */ - - void Console::Show(bool show) - { - if (m_opened != show) - { - m_historyBackground->Enable(show); - m_history->Enable(show); - m_input->Enable(show); - m_inputBackground->Enable(show); - - m_opened = show; - } - } - /*! * \brief Adds a line to the history of the console * @@ -296,7 +136,7 @@ namespace Ndk void Console::ExecuteInput() { - Nz::String input = m_inputDrawer.GetText(); + /*Nz::String input = m_inputDrawer.GetText(); Nz::String inputCmd = input.SubString(s_inputPrefixSize);; m_inputDrawer.SetText(s_inputPrefix); @@ -310,7 +150,7 @@ namespace Ndk if (!m_instance.Execute(inputCmd)) AddLineInternal(m_instance.GetLastError(), Nz::Color::Red); - RefreshHistory(); + RefreshHistory();*/ } /*! @@ -319,23 +159,18 @@ namespace Ndk void Console::Layout() { + const Nz::Vector2f& size = GetContentSize(); + unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight; - - Ndk::NodeComponent& inputNode = m_input->GetComponent(); - inputNode.SetPosition(0.f, m_size.y - lineHeight - 5.f); - - float historyHeight = m_size.y - lineHeight - 5.f - 2.f; - m_historyBackgroundSprite->SetSize(m_size.x, historyHeight); + float historyHeight = size.y - lineHeight - 5.f - 2.f; m_maxHistoryLines = static_cast(std::ceil(historyHeight / lineHeight)); - Ndk::NodeComponent& historyNode = m_history->GetComponent(); - historyNode.SetPosition(0.f, historyHeight - m_maxHistoryLines * lineHeight); + m_history->SetSize({size.x, historyHeight}); + m_history->SetPosition(0.f, historyHeight - m_maxHistoryLines * lineHeight); - Ndk::NodeComponent& inputBackgroundNode = m_inputBackground->GetComponent(); - inputBackgroundNode.SetPosition(0.f, historyHeight + 2.f); - - m_inputBackgroundSprite->SetSize(m_size.x, m_size.y - historyHeight); + m_input->SetPosition(0.f, historyHeight + 2.f); + m_input->SetSize({size.x, size.y - historyHeight}); } /*! @@ -344,7 +179,8 @@ namespace Ndk void Console::RefreshHistory() { - m_historyDrawer.Clear(); + m_history->Clear(); + auto it = m_historyLines.end(); if (m_historyLines.size() > m_maxHistoryLines) it -= m_maxHistoryLines; @@ -355,13 +191,11 @@ namespace Ndk { if (m_maxHistoryLines - i <= m_historyLines.size() && it != m_historyLines.end()) { - m_historyDrawer.AppendText(it->text); + m_history->AppendText(it->text); ++it; } - m_historyDrawer.AppendText(Nz::String('\n')); + m_history->AppendText(Nz::String('\n')); } - - m_historyTextSprite->Update(m_historyDrawer); } } diff --git a/SDK/src/NDK/Lua/LuaBinding_SDK.cpp b/SDK/src/NDK/Lua/LuaBinding_SDK.cpp index ad9bb49e9..739c32573 100644 --- a/SDK/src/NDK/Lua/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_SDK.cpp @@ -62,23 +62,12 @@ namespace Ndk console.BindMethod("AddLine", &Console::AddLine, Nz::Color::White); console.BindMethod("Clear", &Console::Clear); console.BindMethod("GetCharacterSize", &Console::GetCharacterSize); - console.BindMethod("GetHistory", &Console::GetHistory); - console.BindMethod("GetHistoryBackground", &Console::GetHistoryBackground); - console.BindMethod("GetInput", &Console::GetInput); - console.BindMethod("GetInputBackground", &Console::GetInputBackground); - console.BindMethod("GetSize", &Console::GetSize); + //console.BindMethod("GetHistory", &Console::GetHistory); + //console.BindMethod("GetInput", &Console::GetInput); console.BindMethod("GetTextFont", &Console::GetTextFont); - console.BindMethod("IsVisible", &Console::IsVisible); - - console.BindMethod("SendCharacter", &Console::SendCharacter); - //consoleClass.SetMethod("SendEvent", &Console::SendEvent); - console.BindMethod("SetCharacterSize", &Console::SetCharacterSize); - console.BindMethod("SetSize", &Console::SetSize); console.BindMethod("SetTextFont", &Console::SetTextFont); - - console.BindMethod("Show", &Console::Show, true); } #endif From 19fdaa918b49ff19b56bfe513dcae9f6b09a85fe Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 20 Jan 2017 20:32:54 +0100 Subject: [PATCH 02/47] Sdk/Application: Fix after merge, allow for cursor handling --- SDK/src/NDK/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index 32b6d0e84..1b2664985 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -236,7 +236,7 @@ namespace Ndk info.overlayWorld = std::make_unique(false); //< No default system if (info.window->IsValid()) - info.canvas = std::make_unique(info.overlayWorld->CreateHandle(), info.window->GetEventHandler()); + info.canvas = std::make_unique(info.overlayWorld->CreateHandle(), info.window->GetEventHandler(), info.window->GetCursorController().CreateHandle()); RenderSystem& renderSystem = info.overlayWorld->AddSystem(); renderSystem.ChangeRenderTechnique(); From 0257f4be3c895c032e380671d210c6becc6c090e Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 20 Jan 2017 20:35:21 +0100 Subject: [PATCH 03/47] Sdk/Console: Fix style --- SDK/include/NDK/Console.hpp | 1 - SDK/src/NDK/Console.cpp | 68 ++++++++++--------------------------- 2 files changed, 18 insertions(+), 51 deletions(-) diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index b609b3d94..4ae400a3e 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -60,7 +60,6 @@ namespace Ndk void AddLineInternal(const Nz::String& text, const Nz::Color& color = Nz::Color::White); void ExecuteInput(); void Layout() override; - void RefreshHistory(); struct Line { diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 99818a9c1..f24888bca 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -46,12 +46,17 @@ namespace Ndk m_history->EnableBackground(true); m_history->SetReadOnly(true); m_history->SetBackgroundColor(Nz::Color(80, 80, 160, 128)); + m_history->SetPadding(0.f, 0.f, 0.f, 4.f); // Input m_input = Add(); m_input->EnableBackground(true); m_input->SetText(s_inputPrefix); m_input->SetTextColor(Nz::Color::Black); + m_input->SetPadding(0.f, 2.f, 0.f, 2.f); + + // General + SetPadding(0.f, 0.f, 0.f, 0.f); } /*! @@ -63,8 +68,8 @@ namespace Ndk void Console::AddLine(const Nz::String& text, const Nz::Color& color) { - AddLineInternal(text, color); - RefreshHistory(); + m_historyLines.emplace_back(Line{ color, text }); + m_history->AppendText(text + '\n'); } /*! @@ -74,7 +79,8 @@ namespace Ndk void Console::Clear() { m_historyLines.clear(); - RefreshHistory(); + m_history->Clear(); + m_input->SetText(s_inputPrefix); } void Console::ResizeToContent() @@ -118,18 +124,6 @@ namespace Ndk Layout(); } - /*! - * \brief Adds a line to the history of the console - * - * \param text New line of text - * \param color Color for the text - */ - - void Console::AddLineInternal(const Nz::String& text, const Nz::Color& color) - { - m_historyLines.emplace_back(Line{color, text}); - } - /*! * \brief Performs this action when an input is added to the console */ @@ -145,12 +139,10 @@ namespace Ndk m_historyPosition = 0; - AddLineInternal(input); //< With the input prefix + AddLine(input); //< With the input prefix if (!m_instance.Execute(inputCmd)) - AddLineInternal(m_instance.GetLastError(), Nz::Color::Red); - - RefreshHistory();*/ + AddLine(m_instance.GetLastError(), Nz::Color::Red); } /*! @@ -159,43 +151,19 @@ namespace Ndk void Console::Layout() { + Nz::Vector2f origin = GetContentOrigin(); const Nz::Vector2f& size = GetContentSize(); unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight; - float historyHeight = size.y - lineHeight - 5.f - 2.f; + float historyHeight = size.y - lineHeight; m_maxHistoryLines = static_cast(std::ceil(historyHeight / lineHeight)); + float diff = historyHeight - m_maxHistoryLines * lineHeight; - m_history->SetSize({size.x, historyHeight}); - m_history->SetPosition(0.f, historyHeight - m_maxHistoryLines * lineHeight); + m_history->SetPosition(origin.x, origin.y + diff); + m_history->SetSize({size.x, historyHeight - diff - 4.f}); - m_input->SetPosition(0.f, historyHeight + 2.f); - m_input->SetSize({size.x, size.y - historyHeight}); - } - - /*! - * \brief Refreshes the history of the console - */ - - void Console::RefreshHistory() - { - m_history->Clear(); - - auto it = m_historyLines.end(); - if (m_historyLines.size() > m_maxHistoryLines) - it -= m_maxHistoryLines; - else - it = m_historyLines.begin(); - - for (unsigned int i = 0; i < m_maxHistoryLines; ++i) - { - if (m_maxHistoryLines - i <= m_historyLines.size() && it != m_historyLines.end()) - { - m_history->AppendText(it->text); - ++it; - } - - m_history->AppendText(Nz::String('\n')); - } + m_input->SetContentSize({size.x, size.y - historyHeight}); + m_input->SetPosition(origin.x, origin.y + historyHeight); } } From 2baaaaa554adc03ed116c146fc2281d1670a8472 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 20 Jan 2017 20:40:16 +0100 Subject: [PATCH 04/47] Sdk/Console: Add input processing back --- SDK/include/NDK/Console.hpp | 3 +-- SDK/src/NDK/Console.cpp | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index 4ae400a3e..74a98f2ec 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -57,8 +57,7 @@ namespace Ndk Console& operator=(Console&& console) = default; private: - void AddLineInternal(const Nz::String& text, const Nz::Color& color = Nz::Color::White); - void ExecuteInput(); + void ExecuteInput(const TextAreaWidget* textArea, bool* ignoreDefaultAction); void Layout() override; struct Line diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index f24888bca..d94fa07d4 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -55,6 +55,20 @@ namespace Ndk m_input->SetTextColor(Nz::Color::Black); m_input->SetPadding(0.f, 2.f, 0.f, 2.f); + m_input->OnTextAreaKeyReturn.Connect(this, &Console::ExecuteInput); + + // Protect input prefix from erasure/selection + m_input->OnTextAreaCursorMove.Connect([](const TextAreaWidget* textArea, std::size_t* newCursorPos) + { + *newCursorPos = std::max(*newCursorPos, s_inputPrefixSize); + }); + + m_input->OnTextAreaKeyBackspace.Connect([](const TextAreaWidget* textArea, bool* ignoreDefaultAction) + { + if (textArea->GetCursorPosition() <= s_inputPrefixSize) + *ignoreDefaultAction = true; + }); + // General SetPadding(0.f, 0.f, 0.f, 0.f); } @@ -128,11 +142,13 @@ namespace Ndk * \brief Performs this action when an input is added to the console */ - void Console::ExecuteInput() + void Console::ExecuteInput(const TextAreaWidget* textArea, bool* ignoreDefaultAction) { - /*Nz::String input = m_inputDrawer.GetText(); - Nz::String inputCmd = input.SubString(s_inputPrefixSize);; - m_inputDrawer.SetText(s_inputPrefix); + NazaraAssert(textArea == m_input, "Unexpected signal from an other text area"); + + Nz::String input = m_input->GetText(); + Nz::String inputCmd = input.SubString(s_inputPrefixSize); + m_input->SetText(s_inputPrefix); if (m_commandHistory.empty() || m_commandHistory.back() != inputCmd) m_commandHistory.push_back(inputCmd); From cd332c79ad86647128d055e7c64ab7f73d924033 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Aug 2017 17:06:15 +0200 Subject: [PATCH 05/47] Sdk/Console: Handle history --- SDK/src/NDK/Console.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index a7a90d014..34d7808f5 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -58,6 +58,8 @@ namespace Ndk m_input->OnTextAreaKeyReturn.Connect(this, &Console::ExecuteInput); // Protect input prefix from erasure/selection + m_input->SetCursorPosition(s_inputPrefixSize); + m_input->OnTextAreaCursorMove.Connect([](const TextAreaWidget* textArea, std::size_t* newCursorPos) { *newCursorPos = std::max(*newCursorPos, s_inputPrefixSize); @@ -69,6 +71,27 @@ namespace Ndk *ignoreDefaultAction = true; }); + // Handle history + m_input->OnTextAreaKeyUp.Connect([&] (const TextAreaWidget* textArea, bool* ignoreDefaultAction) + { + *ignoreDefaultAction = true; + + if (m_historyPosition > 0) + m_historyPosition--; + + m_input->SetText(s_inputPrefix + m_commandHistory[m_historyPosition]); + }); + + m_input->OnTextAreaKeyDown.Connect([&] (const TextAreaWidget* textArea, bool* ignoreDefaultAction) + { + *ignoreDefaultAction = true; + + if (++m_historyPosition >= m_commandHistory.size()) + m_historyPosition = 0; + + m_input->SetText(s_inputPrefix + m_commandHistory[m_historyPosition]); + }); + // General SetPadding(0.f, 0.f, 0.f, 0.f); } @@ -153,7 +176,7 @@ namespace Ndk if (m_commandHistory.empty() || m_commandHistory.back() != inputCmd) m_commandHistory.push_back(inputCmd); - m_historyPosition = 0; + m_historyPosition = m_commandHistory.size(); AddLine(input); //< With the input prefix From 583cfb5f7114b702b6d9efb568ac4fa752f8fad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Thu, 12 Apr 2018 13:40:03 +0200 Subject: [PATCH 06/47] Fix console size --- SDK/src/NDK/Application.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index 011889c37..784df724b 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -147,10 +147,7 @@ namespace Ndk Nz::Vector2ui windowDimensions; if (info.window->IsValid()) - { windowDimensions = info.window->GetSize(); - windowDimensions.y /= 4; - } else windowDimensions.MakeZero(); From 917c41f90e250c28a1c3fc17fefe19c083e30df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Thu, 12 Apr 2018 13:40:39 +0200 Subject: [PATCH 07/47] Sdk/TextAreaWidget: Fix GetGlyphIndex not being const + add overload returning current glyph index --- SDK/include/NDK/Widgets/TextAreaWidget.hpp | 3 ++- SDK/include/NDK/Widgets/TextAreaWidget.inl | 17 +++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index e0f08053e..873ca274a 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -34,7 +34,8 @@ namespace Ndk inline const Nz::Vector2ui& GetCursorPosition() const; inline const Nz::String& GetDisplayText() const; inline EchoMode GetEchoMode() const; - inline std::size_t GetGlyphIndex(const Nz::Vector2ui& cursorPosition); + inline std::size_t GetGlyphIndex() const; + inline std::size_t GetGlyphIndex(const Nz::Vector2ui& cursorPosition) const; inline const Nz::String& GetText() const; inline const Nz::Color& GetTextColor() const; diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index 07daf7896..1e13a96e5 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -37,7 +37,17 @@ namespace Ndk return m_drawer.GetText(); } - inline std::size_t TextAreaWidget::GetGlyphIndex(const Nz::Vector2ui& cursorPosition) + inline EchoMode TextAreaWidget::GetEchoMode() const + { + return m_echoMode; + } + + inline std::size_t TextAreaWidget::GetGlyphIndex() const + { + return GetGlyphIndex(m_cursorPosition); + } + + inline std::size_t TextAreaWidget::GetGlyphIndex(const Nz::Vector2ui& cursorPosition) const { std::size_t glyphIndex = m_drawer.GetLine(cursorPosition.y).glyphIndex + cursorPosition.x; if (m_drawer.GetLineCount() > cursorPosition.y + 1) @@ -48,11 +58,6 @@ namespace Ndk return glyphIndex; } - inline EchoMode TextAreaWidget::GetEchoMode() const - { - return m_echoMode; - } - inline const Nz::String& TextAreaWidget::GetText() const { return m_text; From f44a4dd3490311df9a402482f0cefdb4a8cc99ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Thu, 12 Apr 2018 13:41:09 +0200 Subject: [PATCH 08/47] Sdk/TextAreaWidget: Fix SetCharacterSize not updating displayed text --- SDK/include/NDK/Widgets/TextAreaWidget.inl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index 1e13a96e5..e13c0a640 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -119,6 +119,8 @@ namespace Ndk inline void TextAreaWidget::SetCharacterSize(unsigned int characterSize) { m_drawer.SetCharacterSize(characterSize); + + UpdateDisplayText(); } inline void TextAreaWidget::SetCursorPosition(std::size_t glyphIndex) From 7cc94d06173ef764e45f2741081c45977f914bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Thu, 12 Apr 2018 13:41:30 +0200 Subject: [PATCH 09/47] Sdk/Console: Fix merge issue --- SDK/src/NDK/Console.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index b1d302d68..8d3992868 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -68,7 +68,7 @@ namespace Ndk m_input->OnTextAreaKeyBackspace.Connect([](const TextAreaWidget* textArea, bool* ignoreDefaultAction) { - if (textArea->GetGlyphUnderCursor() <= s_inputPrefixSize) + if (textArea->GetGlyphIndex() <= s_inputPrefixSize) *ignoreDefaultAction = true; }); From 6fb44796a0ca24f1d24c9e4ca9eb8f234f0566c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Thu, 12 Apr 2018 13:41:48 +0200 Subject: [PATCH 10/47] Sdk/Console: Fix SetCharacterSize not updating character size --- SDK/src/NDK/Console.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 8d3992868..184d6e9d2 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -135,10 +135,8 @@ namespace Ndk { m_characterSize = size; - //m_historyDrawer.SetCharacterSize(m_characterSize); - //m_historyTextSprite->Update(m_historyDrawer); - //m_inputDrawer.SetCharacterSize(m_characterSize); - //m_inputTextSprite->Update(m_inputDrawer); + m_history->SetCharacterSize(size); + m_input->SetCharacterSize(size); Layout(); } From 26f0a9fec934f0bff088aad92e1814a7dae8ac8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Thu, 12 Apr 2018 13:42:36 +0200 Subject: [PATCH 11/47] Sdk/Console: Add ClearFocus/SetFocus methods Theses should be virtuals --- SDK/include/NDK/Console.hpp | 2 ++ SDK/src/NDK/Console.cpp | 25 +++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index 1f6e5f9a1..ae6b63b48 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -42,6 +42,7 @@ namespace Ndk void AddLine(const Nz::String& text, const Nz::Color& color = Nz::Color::White); void Clear(); + void ClearFocus(); inline unsigned int GetCharacterSize() const; inline const TextAreaWidget* GetHistory() const; @@ -51,6 +52,7 @@ namespace Ndk void ResizeToContent() override; void SetCharacterSize(unsigned int size); + void SetFocus(); void SetTextFont(Nz::FontRef font); Console& operator=(const Console& console) = delete; diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 184d6e9d2..f1f43ed9d 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -103,7 +103,6 @@ namespace Ndk * \param text New line of text * \param color Color for the text */ - void Console::AddLine(const Nz::String& text, const Nz::Color& color) { m_historyLines.emplace_back(Line{ color, text }); @@ -112,8 +111,9 @@ namespace Ndk /*! * \brief Clears the console + * + * Clears the console history and input */ - void Console::Clear() { m_historyLines.clear(); @@ -121,6 +121,16 @@ namespace Ndk m_input->SetText(s_inputPrefix); } + /*! + * \brief Clears the console focus + * + * Clear console input widget focus (if owned) + */ + void Console::ClearFocus() + { + m_input->ClearFocus(); + } + void Console::ResizeToContent() { } @@ -130,7 +140,6 @@ namespace Ndk * * \param size Size of the font */ - void Console::SetCharacterSize(unsigned int size) { m_characterSize = size; @@ -141,6 +150,15 @@ namespace Ndk Layout(); } + /*! + * \brief Give the console input focus + * + */ + void Console::SetFocus() + { + m_input->SetFocus(); + } + /*! * \brief Sets the text font * @@ -148,7 +166,6 @@ namespace Ndk * * \remark Produces a NazaraAssert if font is invalid or null */ - void Console::SetTextFont(Nz::FontRef font) { NazaraAssert(font && font->IsValid(), "Invalid font"); From 42b475968018949ac6b324b3421643b7f2eded1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Thu, 12 Apr 2018 13:42:54 +0200 Subject: [PATCH 12/47] Sdk/Application: Give/clear console focus when enabling/disabling it --- SDK/src/NDK/Application.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index 784df724b..b190250ff 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -209,7 +209,19 @@ namespace Ndk overlay->keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& event) { if (event.code == Nz::Keyboard::F9) - consoleRef.Show(!consoleRef.IsVisible()); + { + // Toggle console visibility and focus + if (consoleRef.IsVisible()) + { + consoleRef.ClearFocus(); + consoleRef.Show(false); + } + else + { + consoleRef.Show(true); + consoleRef.SetFocus(); + } + } }); overlay->resizedSlot.Connect(info.renderTarget->OnRenderTargetSizeChange, [&consoleRef] (const Nz::RenderTarget* renderTarget) From 1c0a234d04fce869c5f60823c267783741199bd4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 31 Oct 2018 18:39:14 +0100 Subject: [PATCH 13/47] Merge branch 'master' into console-widget --- SDK/include/NDK/Console.hpp | 2 -- SDK/include/NDK/Widgets/TextAreaWidget.inl | 2 +- SDK/src/NDK/Application.cpp | 4 ++-- SDK/src/NDK/Console.cpp | 17 ++++------------- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index ae6b63b48..75f4d48f9 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -49,8 +49,6 @@ namespace Ndk inline const TextAreaWidget* GetInput() const; inline const Nz::FontRef& GetTextFont() const; - void ResizeToContent() override; - void SetCharacterSize(unsigned int size); void SetFocus(); void SetTextFont(Nz::FontRef font); diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index 3a02e741f..2a7234b79 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -83,7 +83,7 @@ namespace Ndk inline std::size_t TextAreaWidget::GetGlyphIndex() const { - return GetGlyphIndex(m_cursorPosition); + return GetGlyphIndex(m_cursorPositionBegin); } inline std::size_t TextAreaWidget::GetGlyphIndex(const Nz::Vector2ui& cursorPosition) const diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index b190250ff..c26b1e7d2 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -154,7 +154,7 @@ namespace Ndk overlay->console = info.canvas->Add(overlay->lua); Console& consoleRef = *overlay->console; - consoleRef.SetSize({float(windowDimensions.x), windowDimensions.y / 4.f}); + consoleRef.Resize({float(windowDimensions.x), windowDimensions.y / 4.f}); consoleRef.Show(false); // Redirect logs toward the console @@ -227,7 +227,7 @@ namespace Ndk overlay->resizedSlot.Connect(info.renderTarget->OnRenderTargetSizeChange, [&consoleRef] (const Nz::RenderTarget* renderTarget) { Nz::Vector2ui size = renderTarget->GetSize(); - consoleRef.SetSize({float(size.x), size.y / 4.f}); + consoleRef.Resize({float(size.x), size.y / 4.f}); }); info.console = std::move(overlay); diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index f1f43ed9d..a6ad6d38a 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -47,14 +47,12 @@ namespace Ndk m_history->EnableBackground(true); m_history->SetReadOnly(true); m_history->SetBackgroundColor(Nz::Color(80, 80, 160, 128)); - m_history->SetPadding(0.f, 0.f, 0.f, 4.f); // Input m_input = Add(); m_input->EnableBackground(true); m_input->SetText(s_inputPrefix); m_input->SetTextColor(Nz::Color::Black); - m_input->SetPadding(0.f, 2.f, 0.f, 2.f); m_input->OnTextAreaKeyReturn.Connect(this, &Console::ExecuteInput); @@ -92,9 +90,6 @@ namespace Ndk m_input->SetText(s_inputPrefix + m_commandHistory[m_historyPosition]); }); - - // General - SetPadding(0.f, 0.f, 0.f, 0.f); } /*! @@ -131,10 +126,6 @@ namespace Ndk m_input->ClearFocus(); } - void Console::ResizeToContent() - { - } - /*! * \brief Sets the character size * @@ -206,8 +197,8 @@ namespace Ndk void Console::Layout() { - Nz::Vector2f origin = GetContentOrigin(); - const Nz::Vector2f& size = GetContentSize(); + Nz::Vector2f origin = Nz::Vector2f(GetPosition()); + const Nz::Vector2f& size = GetSize(); unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight; float historyHeight = size.y - lineHeight; @@ -215,10 +206,10 @@ namespace Ndk m_maxHistoryLines = static_cast(std::ceil(historyHeight / lineHeight)); float diff = historyHeight - m_maxHistoryLines * lineHeight; + m_history->Resize({ size.x, historyHeight - diff - 4.f }); m_history->SetPosition(origin.x, origin.y + diff); - m_history->SetSize({size.x, historyHeight - diff - 4.f}); - m_input->SetContentSize({size.x, size.y - historyHeight}); + m_input->Resize({size.x, size.y - historyHeight}); m_input->SetPosition(origin.x, origin.y + historyHeight); } } From 29718db08575e4c7d35d77d51097398fe860a616 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 13 Jun 2019 19:05:25 +0200 Subject: [PATCH 14/47] SDK/TextAreaWidget: Add TextOutline property --- ChangeLog.md | 19 ++++++++-------- SDK/include/NDK/Widgets/TextAreaWidget.hpp | 4 ++++ SDK/include/NDK/Widgets/TextAreaWidget.inl | 26 +++++++++++++++++++++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 100ee3c89..ea46c15c8 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -55,7 +55,7 @@ Nazara Engine: - Fix RigidBody3D copy constructor not copying all physics states (angular/linear damping/velocity, mass center, position and rotation) - Add RigidBody3D simulation control (via EnableSimulation and IsSimulationEnabled), which allows to disable physics and collisions at will. - Fix some uninitialized values (found by Valgrind) in Network module -- Fix possible infinite recursion when outputting a Thread::Id object +- Fix possible infinite recursion when outputting a Thread::Id object - ⚠️ Replaced implicit conversion from a Nz::String to a std::string by an explicit method ToStdString() - Fix LuaInstance movement constructor/assignment operator which was corrupting Lua memory - Fix potential bug on SocketImpl::Connect (used by TcpClient::Connect) on POSIX platforms @@ -112,7 +112,7 @@ Nazara Engine: - Fixed SocketPoller not be able to recover from some errors (like invalid sockets and such) - Add LuaImplQuery implementation for std::vector - Fixed LuaState::PushGlobal & LuaState::PushField to copy the object before moving it -- ⚠️ Replaced currentBitPos and currentByte fields by [read|write][BitPos][Byte] to handle properly bit reading/writing. +- ⚠️ Replaced currentBitPos and currentByte fields by [read|write][BitPos][Byte] to handle properly bit reading/writing. - InstancedRenderable::SetMaterial methods are now public. - Fixed Model copy constructor not copying materials - ⚠️ Added InstancedRenderable::Clone() method @@ -148,8 +148,8 @@ Nazara Engine: - ⚠️ CullingList now handles full and partial visibility testing - Added math class Angle, capable of handling both degrees and radians angles and converting them to euler angles/quaternions to improve 2D interface. - ⚠️ AbstractSocket::OnStateChange has been replaced by OnStateChanged, which is now called after state has been changed (with oldState and newState as parameters). -- ⚠️ TcpClient::WaitForconnected now returns the new socket state. -- Added TcpClient::PollForConnected +- ⚠️ TcpClient::WaitForconnected now returns the new socket state. +- Added TcpClient::PollForConnected - ⚠️ Use of the new Angle class instead of floating point angle - It is now possible to set elasticity/friction/surface bodies of 2D colliders and change it at runtime on RigidBody2D - ObjectHandle were remade and should be way more optimized now @@ -188,7 +188,7 @@ Nazara Engine: - Fixed TextSprite not handling multiple textures well - ⚠ TextSprite will now use multiple render layers by itself (the current one and the one right before, ex: [-1, 0] if base layer is 0) if you use text outlines. - ⚠ SimpleTextDrawer no longer supports faux bold rendering -- Added PhysWorld2D::[RaycastQuery, RegionQuery] overloads taking a callback +- Added PhysWorld2D::[RaycastQuery, RegionQuery] overloads taking a callback Nazara Development Kit: - Added ImageWidget (#139) @@ -265,6 +265,7 @@ Nazara Development Kit: - Added LifetimeComponent and LifetimeSystem - Fixed a subtle bug regarding entities invalidation and kill (ex: if an entity #2 kills entity #1 during Entity::Destroy callbacks, entity #1 will survive destruction). - Added PhysicsSystem2D::[RaycastQuery, RegionQuery] overloads taking a callback +- Added TextAreaWidget support for outline # 0.4: @@ -352,8 +353,8 @@ Nazara Engine: - Added [Nz::TcpClient::SendMultiple](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_tcp_client.html#a495c32beb46ed9192699a3b82d358035) method, allowing to send multiple buffers at once. - Added [Nz::PlacementDestroy](https://nazara.digitalpulsesoftware.net/doc/namespace_nz.html#a27c8667def991fc896c5beff3e62668a). (ea985fa76586762f008e4054938db3234eeaf0cb) - Added [Nz::String::Format](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_string.html#a4b699982e7f9ea38f6d44b43ac1e2040) and [Nz::String::FormatVA](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_string.html#abe0fcbce11224b157ac756b60e8dee92) static methods. (cc6e4127dc6c61799a64404770992cef0804ad34). -- Added [Nz::ParticleGroup::GetBuffer](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_particle_mapper.html#aefe1b251efc8c9b8668842275561be0c) method. (4dc85789b59e50d964c83321dbd4b6485c04bef6) -- Added Nz::ParticleMapper::GetPointer method. (1f4e6c2d1594b7bb9dd6f4ea5480fdd16cf5f208) +- Added [Nz::ParticleGroup::GetBuffer](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_particle_mapper.html#aefe1b251efc8c9b8668842275561be0c) method. (4dc85789b59e50d964c83321dbd4b6485c04bef6) +- Added Nz::ParticleMapper::GetPointer method. (1f4e6c2d1594b7bb9dd6f4ea5480fdd16cf5f208) - ⚠️ Structures provied by ParticleStruct header now have a float life. (472d964d587d906764ad1e05bfcc9ab1bf979483) - Fixed scale property of Nz::TextSprite not affecting its bounding volume. (52b29bac775823294c4ad7de70f4dc3f4adfa743) - ⚠️ Nz:MeshParams::flipUVs has been replaced by texCoordOffset and texCoordScale. (a1a7d908adc060fd7a43491c903dfe3b501d98e5) @@ -380,7 +381,7 @@ Nazara Engine: - All noises classes now uses std::mt19937 as a random number generator, to ensure the same results on every machine. (1f5ea9839016964c173d919263827dee69ecb65d) Nazara Development Kit: -- **Added basic widgets**. (c8a12083b3133e946bf60dd060331a4b4631f8d8) +- **Added basic widgets**. (c8a12083b3133e946bf60dd060331a4b4631f8d8) - VelocitySystem will no longer affect entities with PhysicsComponent2D. (a6853234412c744cdcb28344f02f7b0c92704d77) - Fixed EulerAngles constructor in Lua. (d55149a0a70f6230b6f1c3fb50e37dc82a2feb9f) - Fixed Component::OnDetached not being called on entity destruction. (5b777eb4853639d7aeb232ca46d17f0d432f47ca) @@ -391,7 +392,7 @@ Nazara Engine: Nazara Engine: - Nazara binaries are now compiled with Run-Time Type-Information. (a70acdc8f44010627a65282fd3099202116d3e13) -- Nazara demos are now compiled with relative dependencies on Linux. +- Nazara demos are now compiled with relative dependencies on Linux. (d6fbb4c408d48c4a768fad7b43460c76a0df1777) - Added [**Nz::BitCount**](https://nazara.digitalpulsesoftware.net/doc/group__core.html#ga6bfbcff78eb6cfbe3ddaedcfc8c04196) function. (82e31a3ec8449da6618f41690164c2e1d883edb4) - Added [**Nz::Bitset::AppendBits**](https://nazara.digitalpulsesoftware.net/doc/class_nz_1_1_bitset.html#a5ca8f365006c86d6d699d02471904f7e) method. (b018a400499a2356c4455a40d9f6a6c12b3cb36b) diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index 9a5d33335..d215603eb 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -49,6 +49,8 @@ namespace Ndk inline std::size_t GetGlyphIndex(const Nz::Vector2ui& cursorPosition); inline const Nz::String& GetText() const; inline const Nz::Color& GetTextColor() const; + inline const Nz::Color& GetTextOulineColor() const; + inline float GetTextOulineThickness() const; Nz::Vector2ui GetHoveredGlyph(float x, float y) const; @@ -70,6 +72,8 @@ namespace Ndk inline void SetSelection(Nz::Vector2ui fromPosition, Nz::Vector2ui toPosition); inline void SetText(const Nz::String& text); inline void SetTextColor(const Nz::Color& text); + inline void SetTextOutlineColor(const Nz::Color& color); + inline void SetTextOutlineThickness(float thickness); inline void Write(const Nz::String& text); inline void Write(const Nz::String& text, const Nz::Vector2ui& glyphPosition); diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index e4c9f2c30..0c931cebd 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -102,6 +102,16 @@ namespace Ndk return m_drawer.GetColor(); } + inline const Nz::Color& TextAreaWidget::GetTextOulineColor() const + { + return m_drawer.GetOutlineColor(); + } + + inline float TextAreaWidget::GetTextOulineThickness() const + { + return m_drawer.GetOutlineThickness(); + } + inline bool TextAreaWidget::HasSelection() const { return m_cursorPositionBegin != m_cursorPositionEnd; @@ -241,7 +251,21 @@ namespace Ndk { m_drawer.SetColor(text); - m_textSprite->Update(m_drawer); + UpdateDisplayText(); + } + + inline void TextAreaWidget::SetTextOutlineColor(const Nz::Color& color) + { + m_drawer.SetOutlineColor(color); + + UpdateDisplayText(); + } + + inline void TextAreaWidget::SetTextOutlineThickness(float thickness) + { + m_drawer.SetOutlineThickness(thickness); + + UpdateDisplayText(); } inline void TextAreaWidget::Write(const Nz::String& text) From 6e7fd326db12fef4717c61f7cd7d13fe733249f5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 13 Jun 2019 19:06:09 +0200 Subject: [PATCH 15/47] SDK/BaseWidget: Fix possible crash when disabling background --- ChangeLog.md | 1 + SDK/src/NDK/BaseWidget.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index ea46c15c8..b2f71d16d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -266,6 +266,7 @@ Nazara Development Kit: - Fixed a subtle bug regarding entities invalidation and kill (ex: if an entity #2 kills entity #1 during Entity::Destroy callbacks, entity #1 will survive destruction). - Added PhysicsSystem2D::[RaycastQuery, RegionQuery] overloads taking a callback - Added TextAreaWidget support for outline +- Fixed possible crash when disabling BaseWidget background # 0.4: diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 89ca6bb9c..499a7aa2b 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -89,6 +89,7 @@ namespace Ndk } else { + DestroyEntity(m_backgroundEntity); m_backgroundEntity.Reset(); m_backgroundSprite.Reset(); } @@ -185,7 +186,7 @@ namespace Ndk void BaseWidget::Layout() { - if (m_backgroundEntity) + if (m_backgroundSprite) m_backgroundSprite->SetSize(m_size.x, m_size.y); UpdatePositionAndSize(); From c23248c56433e6ef9823448b74381e75a88d04ac Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 16 Jun 2019 15:40:24 +0200 Subject: [PATCH 16/47] PhysWorld2D: Fix possible stack overflow when using wildcard collision handler --- src/Nazara/Physics2D/PhysWorld2D.cpp | 30 ++++------------------------ thirdparty/src/chipmunk/chipmunk.c | 2 +- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/Nazara/Physics2D/PhysWorld2D.cpp b/src/Nazara/Physics2D/PhysWorld2D.cpp index 1390bc84f..6e0c9c22a 100644 --- a/src/Nazara/Physics2D/PhysWorld2D.cpp +++ b/src/Nazara/Physics2D/PhysWorld2D.cpp @@ -403,11 +403,7 @@ namespace Nz const Callback* customCallbacks = static_cast(data); if (customCallbacks->startCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata)) - { - cpBool retA = cpArbiterCallWildcardBeginA(arb, space); - cpBool retB = cpArbiterCallWildcardBeginB(arb, space); - return retA && retB; - } + return cpTrue; else return cpFalse; }; @@ -416,9 +412,7 @@ namespace Nz { handler->beginFunc = [](cpArbiter* arb, cpSpace* space, void*) -> cpBool { - cpBool retA = cpArbiterCallWildcardBeginA(arb, space); - cpBool retB = cpArbiterCallWildcardBeginB(arb, space); - return retA && retB; + return cpTrue; }; } @@ -438,17 +432,12 @@ namespace Nz const Callback* customCallbacks = static_cast(data); customCallbacks->endCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata); - - cpArbiterCallWildcardSeparateA(arb, space); - cpArbiterCallWildcardSeparateB(arb, space); }; } else { handler->separateFunc = [](cpArbiter* arb, cpSpace* space, void*) { - cpArbiterCallWildcardSeparateA(arb, space); - cpArbiterCallWildcardSeparateB(arb, space); }; } @@ -468,11 +457,7 @@ namespace Nz const Callback* customCallbacks = static_cast(data); if (customCallbacks->preSolveCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata)) - { - cpBool retA = cpArbiterCallWildcardPreSolveA(arb, space); - cpBool retB = cpArbiterCallWildcardPreSolveB(arb, space); - return retA && retB; - } + return cpTrue; else return cpFalse; }; @@ -481,9 +466,7 @@ namespace Nz { handler->preSolveFunc = [](cpArbiter* arb, cpSpace* space, void* data) -> cpBool { - cpBool retA = cpArbiterCallWildcardPreSolveA(arb, space); - cpBool retB = cpArbiterCallWildcardPreSolveB(arb, space); - return retA && retB; + return cpTrue; }; } @@ -503,17 +486,12 @@ namespace Nz const Callback* customCallbacks = static_cast(data); customCallbacks->postSolveCallback(*world, arbiter, *firstRigidBody, *secondRigidBody, customCallbacks->userdata); - - cpArbiterCallWildcardPostSolveA(arb, space); - cpArbiterCallWildcardPostSolveB(arb, space); }; } else { handler->postSolveFunc = [](cpArbiter* arb, cpSpace* space, void* data) { - cpArbiterCallWildcardPostSolveA(arb, space); - cpArbiterCallWildcardPostSolveB(arb, space); }; } } diff --git a/thirdparty/src/chipmunk/chipmunk.c b/thirdparty/src/chipmunk/chipmunk.c index 503265cf6..a6cc9d6d4 100644 --- a/thirdparty/src/chipmunk/chipmunk.c +++ b/thirdparty/src/chipmunk/chipmunk.c @@ -89,7 +89,7 @@ cpAreaForSegment(cpVect a, cpVect b, cpFloat r) } cpFloat -cpMomentForPoly(cpFloat m, const int count, const cpVect *verts, cpVect offset, cpFloat r) +cpMomentForPoly(cpFloat m, int count, const cpVect *verts, cpVect offset, cpFloat r) { // TODO account for radius. if(count == 2) return cpMomentForSegment(m, verts[0], verts[1], 0.0f); From 37c16dc2029467cb2e98c0a8aa1a72f597870459 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:17:22 +0200 Subject: [PATCH 17/47] Platform/Event: Add x/y mouse position to MouseWheelEvent --- ChangeLog.md | 1 + include/Nazara/Platform/Event.hpp | 2 ++ src/Nazara/Platform/Win32/WindowImpl.cpp | 10 ++++++++-- src/Nazara/Platform/X11/WindowImpl.cpp | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index b2f71d16d..820f91e93 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -189,6 +189,7 @@ Nazara Engine: - ⚠ TextSprite will now use multiple render layers by itself (the current one and the one right before, ex: [-1, 0] if base layer is 0) if you use text outlines. - ⚠ SimpleTextDrawer no longer supports faux bold rendering - Added PhysWorld2D::[RaycastQuery, RegionQuery] overloads taking a callback +- Added x and y mouse position to MouseWheelEvent Nazara Development Kit: - Added ImageWidget (#139) diff --git a/include/Nazara/Platform/Event.hpp b/include/Nazara/Platform/Event.hpp index 1fe219e8e..02a842889 100644 --- a/include/Nazara/Platform/Event.hpp +++ b/include/Nazara/Platform/Event.hpp @@ -55,6 +55,8 @@ namespace Nz struct MouseWheelEvent { float delta; + int x; + int y; }; // Used by: diff --git a/src/Nazara/Platform/Win32/WindowImpl.cpp b/src/Nazara/Platform/Win32/WindowImpl.cpp index 27b4fa889..6ee3365ac 100644 --- a/src/Nazara/Platform/Win32/WindowImpl.cpp +++ b/src/Nazara/Platform/Win32/WindowImpl.cpp @@ -712,7 +712,10 @@ namespace Nz { WindowEvent event; event.type = WindowEventType_MouseWheelMoved; - event.mouseWheel.delta = static_cast(GET_WHEEL_DELTA_WPARAM(wParam))/WHEEL_DELTA; + event.mouseWheel.delta = static_cast(GET_WHEEL_DELTA_WPARAM(wParam)) / WHEEL_DELTA; + event.mouseWheel.x = GET_X_LPARAM(lParam); + event.mouseWheel.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); } else @@ -722,7 +725,10 @@ namespace Nz { WindowEvent event; event.type = WindowEventType_MouseWheelMoved; - event.mouseWheel.delta = static_cast(m_scrolling/WHEEL_DELTA); + event.mouseWheel.delta = static_cast(m_scrolling / WHEEL_DELTA); + event.mouseWheel.x = GET_X_LPARAM(lParam); + event.mouseWheel.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); m_scrolling %= WHEEL_DELTA; diff --git a/src/Nazara/Platform/X11/WindowImpl.cpp b/src/Nazara/Platform/X11/WindowImpl.cpp index 0e8215e37..abf2db675 100644 --- a/src/Nazara/Platform/X11/WindowImpl.cpp +++ b/src/Nazara/Platform/X11/WindowImpl.cpp @@ -1233,6 +1233,8 @@ namespace Nz { event.type = Nz::WindowEventType_MouseWheelMoved; event.mouseWheel.delta = (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_4) ? 1 : -1; + event.mouseWheel.x = buttonReleaseEvent->event_x; + event.mouseWheel.y = buttonReleaseEvent->event_y; break; } default: From 5039bfbf1defdb1d09d53e85e0c96138da7f8196 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:19:17 +0200 Subject: [PATCH 18/47] SDK/BaseWidget: Add OnMouseWheelMoved event --- ChangeLog.md | 1 + SDK/include/NDK/BaseWidget.hpp | 1 + SDK/include/NDK/Canvas.hpp | 6 ++++-- SDK/include/NDK/Canvas.inl | 3 ++- SDK/src/NDK/BaseWidget.cpp | 4 ++++ SDK/src/NDK/Canvas.cpp | 15 ++++++++++++++- 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 820f91e93..09aec3d4f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -268,6 +268,7 @@ Nazara Development Kit: - Added PhysicsSystem2D::[RaycastQuery, RegionQuery] overloads taking a callback - Added TextAreaWidget support for outline - Fixed possible crash when disabling BaseWidget background +- Added BaseWidget::OnMouseWheelMoved # 0.4: diff --git a/SDK/include/NDK/BaseWidget.hpp b/SDK/include/NDK/BaseWidget.hpp index 26c7f5539..aed8359d8 100644 --- a/SDK/include/NDK/BaseWidget.hpp +++ b/SDK/include/NDK/BaseWidget.hpp @@ -115,6 +115,7 @@ namespace Ndk virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY); virtual void OnMouseButtonPress(int x, int y, Nz::Mouse::Button button); virtual void OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button); + virtual void OnMouseWheelMoved(int x, int y, float delta); virtual void OnMouseExit(); virtual void OnParentResized(const Nz::Vector2f& newSize); virtual void OnTextEntered(char32_t character, bool repeated); diff --git a/SDK/include/NDK/Canvas.hpp b/SDK/include/NDK/Canvas.hpp index d563c6cd3..1b0fbda4f 100644 --- a/SDK/include/NDK/Canvas.hpp +++ b/SDK/include/NDK/Canvas.hpp @@ -48,8 +48,9 @@ namespace Ndk private: void OnEventMouseButtonPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event); void OnEventMouseButtonRelease(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event); - void OnEventMouseMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseMoveEvent& event); void OnEventMouseLeft(const Nz::EventHandler* eventHandler); + void OnEventMouseMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseMoveEvent& event); + void OnEventMouseWheelMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseWheelEvent& event); void OnEventKeyPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event); void OnEventKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event); void OnEventTextEntered(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::TextEvent& event); @@ -65,8 +66,9 @@ namespace Ndk NazaraSlot(Nz::EventHandler, OnKeyReleased, m_keyReleasedSlot); NazaraSlot(Nz::EventHandler, OnMouseButtonPressed, m_mouseButtonPressedSlot); NazaraSlot(Nz::EventHandler, OnMouseButtonReleased, m_mouseButtonReleasedSlot); - NazaraSlot(Nz::EventHandler, OnMouseMoved, m_mouseMovedSlot); NazaraSlot(Nz::EventHandler, OnMouseLeft, m_mouseLeftSlot); + NazaraSlot(Nz::EventHandler, OnMouseMoved, m_mouseMovedSlot); + NazaraSlot(Nz::EventHandler, OnMouseWheelMoved, m_mouseWheelMovedSlot); NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot); std::size_t m_keyboardOwner; diff --git a/SDK/include/NDK/Canvas.inl b/SDK/include/NDK/Canvas.inl index 7a602cffb..75b642328 100644 --- a/SDK/include/NDK/Canvas.inl +++ b/SDK/include/NDK/Canvas.inl @@ -24,8 +24,9 @@ namespace Ndk m_keyReleasedSlot.Connect(eventHandler.OnKeyReleased, this, &Canvas::OnEventKeyReleased); m_mouseButtonPressedSlot.Connect(eventHandler.OnMouseButtonPressed, this, &Canvas::OnEventMouseButtonPressed); m_mouseButtonReleasedSlot.Connect(eventHandler.OnMouseButtonReleased, this, &Canvas::OnEventMouseButtonRelease); - m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, this, &Canvas::OnEventMouseMoved); m_mouseLeftSlot.Connect(eventHandler.OnMouseLeft, this, &Canvas::OnEventMouseLeft); + m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, this, &Canvas::OnEventMouseMoved); + m_mouseWheelMovedSlot.Connect(eventHandler.OnMouseWheelMoved, this, &Canvas::OnEventMouseWheelMoved); m_textEnteredSlot.Connect(eventHandler.OnTextEntered, this, &Canvas::OnEventTextEntered); } diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 499a7aa2b..669747531 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -237,6 +237,10 @@ namespace Ndk { } + void BaseWidget::OnMouseWheelMoved(int /*x*/, int /*y*/, float /*delta*/) + { + } + void BaseWidget::OnMouseExit() { } diff --git a/SDK/src/NDK/Canvas.cpp b/SDK/src/NDK/Canvas.cpp index 3959f1765..aced59e4e 100644 --- a/SDK/src/NDK/Canvas.cpp +++ b/SDK/src/NDK/Canvas.cpp @@ -61,7 +61,7 @@ namespace Ndk } } - void Canvas::OnEventMouseButtonRelease(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent & event) + void Canvas::OnEventMouseButtonRelease(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent& event) { if (m_hoveredWidget != InvalidCanvasIndex) { @@ -128,6 +128,19 @@ namespace Ndk } } + void Canvas::OnEventMouseWheelMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseWheelEvent& event) + { + if (m_hoveredWidget != InvalidCanvasIndex) + { + WidgetEntry& hoveredWidget = m_widgetEntries[m_hoveredWidget]; + + int x = static_cast(std::round(event.x - hoveredWidget.box.x)); + int y = static_cast(std::round(event.y - hoveredWidget.box.y)); + + hoveredWidget.widget->OnMouseWheelMoved(x, y, event.delta); + } + } + void Canvas::OnEventMouseLeft(const Nz::EventHandler* /*eventHandler*/) { if (m_hoveredWidget != InvalidCanvasIndex) From 912b47cedf623184d6cc672b73aeba684d86cd0e Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:19:53 +0200 Subject: [PATCH 19/47] SDK/BaseWidget: Set preferred size no longer resize the widget --- SDK/include/NDK/BaseWidget.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/BaseWidget.inl b/SDK/include/NDK/BaseWidget.inl index e24b89285..4420a7a44 100644 --- a/SDK/include/NDK/BaseWidget.inl +++ b/SDK/include/NDK/BaseWidget.inl @@ -237,7 +237,7 @@ namespace Ndk { m_preferredSize = preferredSize; - Resize(m_preferredSize); + //Resize(m_preferredSize); } inline bool BaseWidget::IsRegisteredToCanvas() const From c4b7534ac119a588f97f1350d218205a24dba86a Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:20:13 +0200 Subject: [PATCH 20/47] SDK/TextAreaWidget: Fix clear not setting preferred size --- SDK/include/NDK/Widgets/TextAreaWidget.inl | 1 + 1 file changed, 1 insertion(+) diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index e5dbced4a..a2e9f22c9 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -13,6 +13,7 @@ namespace Ndk m_drawer.Clear(); m_text.Clear(); m_textSprite->Update(m_drawer); + SetPreferredSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths())); RefreshCursor(); OnTextChanged(this, m_text); From c09b2d374782f22e15017b5e031c46f8d2ad9d6c Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:21:06 +0200 Subject: [PATCH 21/47] SDK/Entity: Add OnEntity[Disabled|Enabled] signals --- ChangeLog.md | 1 + SDK/include/NDK/Entity.hpp | 2 ++ SDK/src/NDK/Entity.cpp | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 09aec3d4f..ba3b40b55 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -269,6 +269,7 @@ Nazara Development Kit: - Added TextAreaWidget support for outline - Fixed possible crash when disabling BaseWidget background - Added BaseWidget::OnMouseWheelMoved +- Added Entity::OnEntity[Disabled|Enabled] signals # 0.4: diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index 43a4a43c7..e09f4eac4 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -74,6 +74,8 @@ namespace Ndk Entity& operator=(Entity&&) = delete; NazaraSignal(OnEntityDestruction, Entity* /*entity*/); + NazaraSignal(OnEntityDisabled, Entity* /*entity*/); + NazaraSignal(OnEntityEnabled, Entity* /*entity*/); private: Entity(World* world, EntityId id); diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 7bc81982d..4e211f0db 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -111,11 +111,15 @@ namespace Ndk { for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) m_components[i]->OnEntityEnabled(); + + OnEntityEnabled(this); } else { for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) m_components[i]->OnEntityDisabled(); + + OnEntityDisabled(this); } Invalidate(); From 3bed2fb7fe3376bd3e3c50ee9d18ab3206783100 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:21:35 +0200 Subject: [PATCH 22/47] SDK/BaseWidget: Add SetParent --- ChangeLog.md | 1 + SDK/include/NDK/BaseWidget.hpp | 1 + SDK/src/NDK/BaseWidget.cpp | 21 +++++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index ba3b40b55..a34d932a9 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -270,6 +270,7 @@ Nazara Development Kit: - Fixed possible crash when disabling BaseWidget background - Added BaseWidget::OnMouseWheelMoved - Added Entity::OnEntity[Disabled|Enabled] signals +- Added BaseWidget::SetParent # 0.4: diff --git a/SDK/include/NDK/BaseWidget.hpp b/SDK/include/NDK/BaseWidget.hpp index aed8359d8..77f97bd1f 100644 --- a/SDK/include/NDK/BaseWidget.hpp +++ b/SDK/include/NDK/BaseWidget.hpp @@ -81,6 +81,7 @@ namespace Ndk void SetBackgroundColor(const Nz::Color& color); void SetCursor(Nz::SystemCursor systemCursor); void SetFocus(); + void SetParent(BaseWidget* widget); inline void SetFixedHeight(float fixedHeight); inline void SetFixedSize(const Nz::Vector2f& fixedSize); diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 669747531..80978ffaf 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -145,6 +145,27 @@ namespace Ndk m_canvas->SetKeyboardOwner(m_canvasIndex); } + void BaseWidget::SetParent(BaseWidget* widget) + { + Canvas* oldCanvas = m_canvas; + Canvas* newCanvas = widget->GetCanvas(); + + // Changing a widget canvas is a problem because of the canvas entities + NazaraAssert(oldCanvas == newCanvas, "Transferring a widget between canvas is not yet supported"); + + Node::SetParent(widget); + m_widgetParent = widget; + + Layout(); + } + + void BaseWidget::SetRenderingRect(const Nz::Rectf& renderingRect) + { + m_renderingRect = renderingRect; + + UpdatePositionAndSize(); + } + void BaseWidget::Show(bool show) { if (m_visible != show) From 2d4dd7a8ab1dcf93e4847926b5f995a0cc1a331e Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:23:48 +0200 Subject: [PATCH 23/47] SDK/Widgets: Fix Show overriding entity enabled state --- ChangeLog.md | 1 + SDK/include/NDK/BaseWidget.hpp | 6 ++++-- SDK/src/NDK/BaseWidget.cpp | 25 +++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index a34d932a9..5cc4c9924 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -271,6 +271,7 @@ Nazara Development Kit: - Added BaseWidget::OnMouseWheelMoved - Added Entity::OnEntity[Disabled|Enabled] signals - Added BaseWidget::SetParent +- BaseWidget::Show will no longer show entities disabled by the widget # 0.4: diff --git a/SDK/include/NDK/BaseWidget.hpp b/SDK/include/NDK/BaseWidget.hpp index 77f97bd1f..ec69cb813 100644 --- a/SDK/include/NDK/BaseWidget.hpp +++ b/SDK/include/NDK/BaseWidget.hpp @@ -26,8 +26,6 @@ namespace Ndk friend Canvas; public: - struct Padding; - BaseWidget(BaseWidget* parent); BaseWidget(const BaseWidget&) = delete; BaseWidget(BaseWidget&&) = delete; @@ -138,6 +136,10 @@ namespace Ndk struct WidgetEntity { EntityOwner handle; + bool isEnabled = true; + + NazaraSlot(Ndk::Entity, OnEntityDisabled, onDisabledSlot); + NazaraSlot(Ndk::Entity, OnEntityEnabled, onEnabledSlot); }; static constexpr std::size_t InvalidCanvasIndex = std::numeric_limits::max(); diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 80978ffaf..ed3b8265c 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -178,14 +178,20 @@ namespace Ndk UnregisterFromCanvas(); for (WidgetEntity& entity : m_entities) - entity.handle->Enable(show); + { + if (entity.isEnabled) + { + entity.handle->Enable(show); //< This will override isEnabled + entity.isEnabled = true; + } + } for (const auto& widgetPtr : m_children) widgetPtr->Show(show); } } - const Ndk::EntityHandle& BaseWidget::CreateEntity() + const EntityHandle& BaseWidget::CreateEntity() { const EntityHandle& newEntity = m_world->CreateEntity(); newEntity->Enable(m_visible); @@ -193,6 +199,21 @@ namespace Ndk m_entities.emplace_back(); WidgetEntity& widgetEntity = m_entities.back(); widgetEntity.handle = newEntity; + widgetEntity.onDisabledSlot.Connect(newEntity->OnEntityDisabled, [this](Entity* entity) + { + auto it = std::find_if(m_entities.begin(), m_entities.end(), [&](const WidgetEntity& widgetEntity) { return widgetEntity.handle == entity; }); + NazaraAssert(it != m_entities.end(), "Entity does not belong to this widget"); + + it->isEnabled = false; + }); + + widgetEntity.onEnabledSlot.Connect(newEntity->OnEntityEnabled, [this](Entity* entity) + { + auto it = std::find_if(m_entities.begin(), m_entities.end(), [&](const WidgetEntity& widgetEntity) { return widgetEntity.handle == entity; }); + NazaraAssert(it != m_entities.end(), "Entity does not belong to this widget"); + + it->isEnabled = true; + }); return newEntity; } From b214f482256064e2ba927a2e1af22ab85c465c55 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:24:49 +0200 Subject: [PATCH 24/47] SDK/TextAreaWidget: Preferred size will now adjust to content --- SDK/src/NDK/Widgets/TextAreaWidget.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 09355c09c..9b946eac1 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -31,8 +31,10 @@ namespace Ndk m_textEntity = CreateEntity(); m_textEntity->AddComponent().Attach(m_textSprite); - m_textEntity->AddComponent().SetParent(this); - m_textEntity->GetComponent().SetPosition(5.f, 3.f); + + auto& textNode = m_textEntity->AddComponent(); + textNode.SetParent(this); + textNode.SetPosition(5.f, 3.f); SetCursor(Nz::SystemCursor_Text); SetCharacterSize(GetCharacterSize()); //< Actualize minimum / preferred size @@ -73,6 +75,7 @@ namespace Ndk } m_textSprite->Update(m_drawer); + SetPreferredSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths())); OnTextChanged(this, m_text); } @@ -163,7 +166,6 @@ namespace Ndk Nz::Vector2f size = { float(spaceAdvance), float(lineHeight) + 5.f }; SetMinimumSize(size); - SetPreferredSize({ size.x * 6.f, size.y }); } void TextAreaWidget::Write(const Nz::String& text, std::size_t glyphPosition) @@ -606,6 +608,7 @@ namespace Ndk } m_textSprite->Update(m_drawer); + SetPreferredSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths())); SetCursorPosition(m_cursorPositionBegin); //< Refresh cursor position (prevent it from being outside of the text) } From 7c045a50dbe788049ca3cf7f39b666ce970cc234 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:25:45 +0200 Subject: [PATCH 25/47] SDK/BaseWidget: Add Rendering rect --- ChangeLog.md | 1 + SDK/include/NDK/BaseWidget.hpp | 6 ++++++ SDK/include/NDK/BaseWidget.inl | 12 ++++++++++++ SDK/src/NDK/BaseWidget.cpp | 8 +++++++- 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 5cc4c9924..e448c5df6 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -272,6 +272,7 @@ Nazara Development Kit: - Added Entity::OnEntity[Disabled|Enabled] signals - Added BaseWidget::SetParent - BaseWidget::Show will no longer show entities disabled by the widget +- BaseWidget now has a rendering rect property (allowing to tell a widget what part of it will be rendered) # 0.4: diff --git a/SDK/include/NDK/BaseWidget.hpp b/SDK/include/NDK/BaseWidget.hpp index ec69cb813..010abd437 100644 --- a/SDK/include/NDK/BaseWidget.hpp +++ b/SDK/include/NDK/BaseWidget.hpp @@ -39,6 +39,7 @@ namespace Ndk inline void CenterVertical(); void ClearFocus(); + inline void ClearRenderingRect(); void Destroy(); @@ -66,6 +67,8 @@ namespace Ndk inline Nz::Vector2f GetPreferredSize() const; inline float GetPreferredWidth() const; + inline const Nz::Rectf& GetRenderingRect() const; + inline Nz::Vector2f GetSize() const; inline float GetWidth() const; inline std::size_t GetWidgetChildCount() const; @@ -93,6 +96,8 @@ namespace Ndk inline void SetMinimumSize(const Nz::Vector2f& minimumSize); inline void SetMinimumWidth(float minimumWidth); + virtual void SetRenderingRect(const Nz::Rectf& renderingRect); + void Show(bool show = true); BaseWidget& operator=(const BaseWidget&) = delete; @@ -151,6 +156,7 @@ namespace Ndk EntityOwner m_backgroundEntity; WorldHandle m_world; Nz::Color m_backgroundColor; + Nz::Rectf m_renderingRect; Nz::SpriteRef m_backgroundSprite; Nz::SystemCursor m_cursor; Nz::Vector2f m_maximumSize; diff --git a/SDK/include/NDK/BaseWidget.inl b/SDK/include/NDK/BaseWidget.inl index 4420a7a44..605220774 100644 --- a/SDK/include/NDK/BaseWidget.inl +++ b/SDK/include/NDK/BaseWidget.inl @@ -5,6 +5,7 @@ #include #include #include +#include namespace Ndk { @@ -12,6 +13,7 @@ namespace Ndk m_canvasIndex(InvalidCanvasIndex), m_canvas(nullptr), m_backgroundColor(Nz::Color(230, 230, 230, 255)), + m_renderingRect(-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()), m_cursor(Nz::SystemCursor_Default), m_size(50.f, 50.f), m_maximumSize(std::numeric_limits::infinity()), @@ -66,6 +68,11 @@ namespace Ndk SetPosition(GetPosition(Nz::CoordSys_Local).x, (parentSize.y - mySize.y) / 2.f); } + inline void BaseWidget::ClearRenderingRect() + { + SetRenderingRect(Nz::Rectf(-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity())); + } + template inline void BaseWidget::ForEachWidgetChild(F iterator) { @@ -145,6 +152,11 @@ namespace Ndk return m_preferredSize.x; } + inline const Nz::Rectf& BaseWidget::GetRenderingRect() const + { + return m_renderingRect; + } + inline Nz::Vector2f BaseWidget::GetSize() const { return Nz::Vector2f(GetWidth(), GetHeight()); diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index ed3b8265c..647f451c6 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -336,7 +336,13 @@ namespace Ndk Nz::Vector2f widgetPos = Nz::Vector2f(GetPosition()); Nz::Vector2f widgetSize = GetSize(); - Nz::Recti fullBounds(Nz::Rectf(widgetPos.x, widgetPos.y, widgetSize.x, widgetSize.y)); + Nz::Rectf widgetRect(widgetPos.x, widgetPos.y, widgetSize.x, widgetSize.y); + Nz::Rectf widgetRenderingRect(widgetPos.x + m_renderingRect.x, widgetPos.y + m_renderingRect.y, m_renderingRect.width, m_renderingRect.height); + + Nz::Rectf widgetBounds; + widgetRect.Intersect(widgetRenderingRect, &widgetBounds); + + Nz::Recti fullBounds(widgetBounds); for (WidgetEntity& widgetEntity : m_entities) { const Ndk::EntityHandle& entity = widgetEntity.handle; From 42aa7ca355468ee70c58fec70134649066afeea2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:26:11 +0200 Subject: [PATCH 26/47] SDK: Add ScrollAreaWidget (WIP) --- ChangeLog.md | 1 + SDK/include/NDK/Widgets.hpp | 1 + SDK/include/NDK/Widgets/ScrollAreaWidget.hpp | 67 +++++++ SDK/include/NDK/Widgets/ScrollAreaWidget.inl | 24 +++ SDK/src/NDK/Widgets/ScrollAreaWidget.cpp | 184 +++++++++++++++++++ 5 files changed, 277 insertions(+) create mode 100644 SDK/include/NDK/Widgets/ScrollAreaWidget.hpp create mode 100644 SDK/include/NDK/Widgets/ScrollAreaWidget.inl create mode 100644 SDK/src/NDK/Widgets/ScrollAreaWidget.cpp diff --git a/ChangeLog.md b/ChangeLog.md index e448c5df6..f027918e9 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -273,6 +273,7 @@ Nazara Development Kit: - Added BaseWidget::SetParent - BaseWidget::Show will no longer show entities disabled by the widget - BaseWidget now has a rendering rect property (allowing to tell a widget what part of it will be rendered) +- Added ScrollAreaWidget # 0.4: diff --git a/SDK/include/NDK/Widgets.hpp b/SDK/include/NDK/Widgets.hpp index a4b74b2d6..303b22519 100644 --- a/SDK/include/NDK/Widgets.hpp +++ b/SDK/include/NDK/Widgets.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #endif // NDK_WIDGETS_GLOBAL_HPP diff --git a/SDK/include/NDK/Widgets/ScrollAreaWidget.hpp b/SDK/include/NDK/Widgets/ScrollAreaWidget.hpp new file mode 100644 index 000000000..5b7106b1f --- /dev/null +++ b/SDK/include/NDK/Widgets/ScrollAreaWidget.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2019 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#pragma once + +#ifndef NDK_WIDGETS_SCROLLAREAWIDGET_HPP +#define NDK_WIDGETS_SCROLLAREAWIDGET_HPP + +#include +#include +#include + +namespace Ndk +{ + class NDK_API ScrollAreaWidget : public BaseWidget + { + public: + ScrollAreaWidget(BaseWidget* parent, BaseWidget* content); + ScrollAreaWidget(const ScrollAreaWidget&) = delete; + ScrollAreaWidget(ScrollAreaWidget&&) = default; + ~ScrollAreaWidget() = default; + + inline float GetScrollHeight() const; + inline float GetScrollRatio() const; + + inline void ScrollToHeight(float height); + void ScrollToRatio(float ratio); + + ScrollAreaWidget& operator=(const ScrollAreaWidget&) = delete; + ScrollAreaWidget& operator=(ScrollAreaWidget&&) = default; + + private: + enum class ScrollBarStatus + { + Grabbed, + Hovered, + None + }; + + Nz::Rectf GetScrollbarRect() const; + + void Layout() override; + + void OnMouseButtonPress(int x, int y, Nz::Mouse::Button button) override; + void OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button) override; + void OnMouseExit() override; + void OnMouseMoved(int x, int y, int deltaX, int deltaY) override; + void OnMouseWheelMoved(int x, int y, float delta) override; + + void UpdateScrollbarStatus(ScrollBarStatus status); + + BaseWidget* m_content; + EntityHandle m_scrollbarBackgroundEntity; + EntityHandle m_scrollbarEntity; + Nz::SpriteRef m_scrollbarBackgroundSprite; + Nz::SpriteRef m_scrollbarSprite; + Nz::Vector2i m_grabbedDelta; + ScrollBarStatus m_scrollbarStatus; + bool m_isScrollBarVisible; + float m_scrollRatio; + }; +} + +#include + +#endif // NDK_WIDGETS_SCROLLAREAWIDGET_HPP diff --git a/SDK/include/NDK/Widgets/ScrollAreaWidget.inl b/SDK/include/NDK/Widgets/ScrollAreaWidget.inl new file mode 100644 index 000000000..c98230180 --- /dev/null +++ b/SDK/include/NDK/Widgets/ScrollAreaWidget.inl @@ -0,0 +1,24 @@ +// Copyright (C) 2019 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include + +namespace Ndk +{ + inline float ScrollAreaWidget::GetScrollHeight() const + { + return m_scrollRatio * m_content->GetHeight(); + } + + inline float ScrollAreaWidget::GetScrollRatio() const + { + return m_scrollRatio; + } + + inline void ScrollAreaWidget::ScrollToHeight(float height) + { + float contentHeight = m_content->GetHeight(); + ScrollToRatio(height / contentHeight); + } +} diff --git a/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp b/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp new file mode 100644 index 000000000..4f5ca3f6b --- /dev/null +++ b/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp @@ -0,0 +1,184 @@ +// Copyright (C) 2019 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include +#include +#include + +namespace Ndk +{ + namespace + { + constexpr float scrollbarPadding = 5.f; + } + + ScrollAreaWidget::ScrollAreaWidget(BaseWidget* parent, BaseWidget* content) : + BaseWidget(parent), + m_content(content), + m_scrollbarStatus(ScrollBarStatus::None), + m_scrollRatio(0.f) + { + m_content->SetParent(this); + m_content->SetPosition(Nz::Vector3f::Zero()); + + m_scrollbarBackgroundSprite = Nz::Sprite::New(); + m_scrollbarBackgroundSprite->SetColor(Nz::Color(62, 62, 62)); + m_scrollbarBackgroundSprite->SetMaterial("Basic2D"); + + m_scrollbarBackgroundEntity = CreateEntity(); + m_scrollbarBackgroundEntity->AddComponent().SetParent(this); + m_scrollbarBackgroundEntity->AddComponent().Attach(m_scrollbarBackgroundSprite, 1); + + m_scrollbarSprite = Nz::Sprite::New(); + m_scrollbarSprite->SetColor(Nz::Color(104, 104, 104)); + m_scrollbarSprite->SetMaterial("Basic2D"); + + m_scrollbarEntity = CreateEntity(); + m_scrollbarEntity->AddComponent().SetParent(this); + m_scrollbarEntity->AddComponent().Attach(m_scrollbarSprite); + + Resize(m_content->GetSize()); + } + + void ScrollAreaWidget::ScrollToRatio(float ratio) + { + m_scrollRatio = Nz::Clamp(ratio, 0.f, 1.f); + + float widgetHeight = GetHeight(); + float maxHeight = widgetHeight - m_scrollbarSprite->GetSize().y - 2.f * scrollbarPadding; + + auto& scrollbarNode = m_scrollbarEntity->GetComponent(); + scrollbarNode.SetPosition(Nz::Vector2f(scrollbarNode.GetPosition(Nz::CoordSys_Local).x, scrollbarPadding + m_scrollRatio * maxHeight)); + + float contentPosition = m_scrollRatio * (widgetHeight - m_content->GetHeight()); + + m_content->SetPosition(0.f, contentPosition); + m_content->SetRenderingRect(Nz::Rectf(-std::numeric_limits::infinity(), -contentPosition, std::numeric_limits::infinity(), widgetHeight)); + } + + Nz::Rectf ScrollAreaWidget::GetScrollbarRect() const + { + Nz::Vector2f scrollBarPosition = Nz::Vector2f(m_scrollbarEntity->GetComponent().GetPosition(Nz::CoordSys_Local)); + Nz::Vector2f scrollBarSize = m_scrollbarSprite->GetSize(); + return Nz::Rectf(scrollBarPosition.x, scrollBarPosition.y, scrollBarSize.x, scrollBarSize.y); + } + + void ScrollAreaWidget::Layout() + { + constexpr float scrollBarBackgroundWidth = 20.f; + constexpr float scrollBarWidth = scrollBarBackgroundWidth - 2.f * scrollbarPadding; + + float areaHeight = GetHeight(); + float contentHeight = m_content->GetHeight(); + + if (contentHeight > areaHeight) + { + m_isScrollBarVisible = true; + + Nz::Vector2f contentSize(GetWidth() - scrollBarBackgroundWidth, contentHeight); + m_content->Resize(contentSize); + + m_scrollbarEntity->Enable(); + m_scrollbarBackgroundEntity->Enable(); + + float scrollBarHeight = std::max(std::floor(areaHeight * (areaHeight / contentHeight)), 20.f); + + m_scrollbarBackgroundSprite->SetSize(scrollBarBackgroundWidth, areaHeight); + m_scrollbarSprite->SetSize(scrollBarWidth, scrollBarHeight); + + m_scrollbarBackgroundEntity->GetComponent().SetPosition(contentSize.x, 0.f); + m_scrollbarEntity->GetComponent().SetPosition(contentSize.x + (scrollBarBackgroundWidth - scrollBarWidth) / 2.f, 0.f); + + ScrollToRatio(m_scrollRatio); + } + else + { + m_isScrollBarVisible = false; + + m_content->Resize(GetSize()); + + m_scrollbarEntity->Disable(); + m_scrollbarBackgroundEntity->Disable(); + + ScrollToRatio(0.f); + } + + BaseWidget::Layout(); + } + + void ScrollAreaWidget::OnMouseButtonPress(int x, int y, Nz::Mouse::Button button) + { + if (button != Nz::Mouse::Left) + return; + + if (m_scrollbarStatus == ScrollBarStatus::Hovered) + { + UpdateScrollbarStatus(ScrollBarStatus::Grabbed); + + auto& scrollbarNode = m_scrollbarEntity->GetComponent(); + + m_grabbedDelta.Set(x, y - scrollbarNode.GetPosition(Nz::CoordSys_Local).y); + } + } + + void ScrollAreaWidget::OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button) + { + if (button != Nz::Mouse::Left) + return; + + if (m_scrollbarStatus == ScrollBarStatus::Grabbed) + { + Nz::Rectf scrollBarRect = GetScrollbarRect(); + UpdateScrollbarStatus((scrollBarRect.Contains(Nz::Vector2f(x, y))) ? ScrollBarStatus::Hovered : ScrollBarStatus::None); + } + } + + void ScrollAreaWidget::OnMouseExit() + { + //if (m_scrollbarStatus == ScrollBarStatus::Hovered) + UpdateScrollbarStatus(ScrollBarStatus::None); + } + + void ScrollAreaWidget::OnMouseMoved(int x, int y, int /*deltaX*/, int /*deltaY*/) + { + if (m_scrollbarStatus == ScrollBarStatus::Grabbed) + { + float height = GetHeight(); + float maxHeight = height - m_scrollbarSprite->GetSize().y; + float newHeight = Nz::Clamp(float(y - m_grabbedDelta.y), 0.f, maxHeight); + + ScrollToHeight(newHeight / maxHeight * m_content->GetHeight()); + } + else + { + Nz::Rectf scrollBarRect = GetScrollbarRect(); + UpdateScrollbarStatus((scrollBarRect.Contains(Nz::Vector2f(x, y))) ? ScrollBarStatus::Hovered : ScrollBarStatus::None); + } + } + + void ScrollAreaWidget::OnMouseWheelMoved(int /*x*/, int /*y*/, float delta) + { + constexpr float scrollStep = 100.f; + + ScrollToHeight(GetScrollHeight() - scrollStep * delta); + } + + void ScrollAreaWidget::UpdateScrollbarStatus(ScrollBarStatus status) + { + if (m_scrollbarStatus != status) + { + Nz::Color newColor; + switch (status) + { + case ScrollBarStatus::Grabbed: newColor = Nz::Color(235, 235, 235); break; + case ScrollBarStatus::Hovered: newColor = Nz::Color(152, 152, 152); break; + case ScrollBarStatus::None: newColor = Nz::Color(104, 104, 104); break; + } + + m_scrollbarSprite->SetColor(newColor); + m_scrollbarStatus = status; + } + } +} From 296b5459c646c5ffbdf967ee18e1524e117deb95 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:26:22 +0200 Subject: [PATCH 27/47] SDK/Console: Make use of ScrollAreaWidget --- SDK/include/NDK/Console.hpp | 2 ++ SDK/src/NDK/Console.cpp | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index 75f4d48f9..cb79fcbee 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -27,6 +27,7 @@ namespace Ndk { class Console; class Entity; + class ScrollAreaWidget; class TextAreaWidget; using ConsoleHandle = Nz::ObjectHandle; @@ -69,6 +70,7 @@ namespace Ndk std::size_t m_historyPosition; std::vector m_commandHistory; std::vector m_historyLines; + ScrollAreaWidget* m_historyArea; TextAreaWidget* m_history; TextAreaWidget* m_input; Nz::FontRef m_defaultFont; diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index a6ad6d38a..84d9b08e4 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -48,6 +48,8 @@ namespace Ndk m_history->SetReadOnly(true); m_history->SetBackgroundColor(Nz::Color(80, 80, 160, 128)); + m_historyArea = Add(m_history); + // Input m_input = Add(); m_input->EnableBackground(true); @@ -102,6 +104,9 @@ namespace Ndk { m_historyLines.emplace_back(Line{ color, text }); m_history->AppendText(text + '\n'); + m_history->Resize(m_history->GetPreferredSize()); + m_historyArea->Resize(m_historyArea->GetSize()); + m_historyArea->ScrollToRatio(1.f); } /*! @@ -113,6 +118,8 @@ namespace Ndk { m_historyLines.clear(); m_history->Clear(); + m_history->Resize(m_history->GetPreferredSize()); + m_historyArea->Resize(m_historyArea->GetSize()); m_input->SetText(s_inputPrefix); } @@ -206,8 +213,8 @@ namespace Ndk m_maxHistoryLines = static_cast(std::ceil(historyHeight / lineHeight)); float diff = historyHeight - m_maxHistoryLines * lineHeight; - m_history->Resize({ size.x, historyHeight - diff - 4.f }); - m_history->SetPosition(origin.x, origin.y + diff); + m_historyArea->SetPosition(origin.x, origin.y + diff); + m_historyArea->Resize({ size.x, historyHeight - diff - 4.f }); m_input->Resize({size.x, size.y - historyHeight}); m_input->SetPosition(origin.x, origin.y + historyHeight); From 9975f11ca0b22ba5ee138dacd74043b113c2dace Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 22:26:57 +0200 Subject: [PATCH 28/47] Update ChangeLog.md --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index f027918e9..bfb292c04 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -274,6 +274,7 @@ Nazara Development Kit: - BaseWidget::Show will no longer show entities disabled by the widget - BaseWidget now has a rendering rect property (allowing to tell a widget what part of it will be rendered) - Added ScrollAreaWidget +- Console has been remade with widgets (allowing to scroll back history, select text, etc.) # 0.4: From 0ec1480024c0260e15e6aacf8c414176de9ce455 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Jul 2019 23:12:12 +0200 Subject: [PATCH 29/47] Add line wrapping --- ChangeLog.md | 2 + SDK/include/NDK/Widgets/TextAreaWidget.hpp | 4 +- SDK/include/NDK/Widgets/TextAreaWidget.inl | 5 +++ SDK/src/NDK/Console.cpp | 1 + SDK/src/NDK/Widgets/TextAreaWidget.cpp | 34 ++++++++++++++-- include/Nazara/Utility/SimpleTextDrawer.hpp | 3 ++ src/Nazara/Utility/SimpleTextDrawer.cpp | 43 +++++++++++++++++---- 7 files changed, 79 insertions(+), 13 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index bfb292c04..49790d33f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -190,6 +190,7 @@ Nazara Engine: - ⚠ SimpleTextDrawer no longer supports faux bold rendering - Added PhysWorld2D::[RaycastQuery, RegionQuery] overloads taking a callback - Added x and y mouse position to MouseWheelEvent +- Added SimpleTextDrawer::[Get|Set]MaxLineWidth (which does line wrap) Nazara Development Kit: - Added ImageWidget (#139) @@ -275,6 +276,7 @@ Nazara Development Kit: - BaseWidget now has a rendering rect property (allowing to tell a widget what part of it will be rendered) - Added ScrollAreaWidget - Console has been remade with widgets (allowing to scroll back history, select text, etc.) +- Added TextAreaWidget line wrap option # 0.4: diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index bb121c5f0..069e89add 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -32,7 +32,7 @@ namespace Ndk //virtual TextAreaWidget* Clone() const = 0; - + void EnableLineWrap(bool enable = true); inline void EnableMultiline(bool enable = true); inline void EnableTabWriting(bool enable = true); @@ -57,6 +57,7 @@ namespace Ndk inline bool HasSelection() const; + inline bool IsLineWrapEnabled() const; inline bool IsMultilineEnabled() const; inline bool IsReadOnly() const; inline bool IsTabWritingEnabled() const; @@ -122,6 +123,7 @@ namespace Ndk Nz::Vector2ui m_cursorPositionEnd; Nz::Vector2ui m_selectionCursor; std::vector m_cursorSprites; + bool m_isLineWrapEnabled; bool m_isMouseButtonDown; bool m_multiLineEnabled; bool m_readOnly; diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index a2e9f22c9..c66662f32 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -123,6 +123,11 @@ namespace Ndk return m_cursorPositionBegin != m_cursorPositionEnd; } + inline bool TextAreaWidget::IsLineWrapEnabled() const + { + return m_isLineWrapEnabled; + } + inline bool TextAreaWidget::IsMultilineEnabled() const { return m_multiLineEnabled; diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 84d9b08e4..4108cddc5 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -45,6 +45,7 @@ namespace Ndk // History m_history = Add(); m_history->EnableBackground(true); + m_history->EnableLineWrap(true); m_history->SetReadOnly(true); m_history->SetBackgroundColor(Nz::Color(80, 80, 160, 128)); diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 9b946eac1..9d695cf39 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -16,6 +16,7 @@ namespace Ndk m_echoMode(EchoMode_Normal), m_cursorPositionBegin(0U, 0U), m_cursorPositionEnd(0U, 0U), + m_isLineWrapEnabled(false), m_isMouseButtonDown(false), m_multiLineEnabled(false), m_readOnly(false), @@ -74,12 +75,26 @@ namespace Ndk } } - m_textSprite->Update(m_drawer); - SetPreferredSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths())); + UpdateTextSprite(); OnTextChanged(this, m_text); } + void TextAreaWidget::EnableLineWrap(bool enable) + { + if (m_isLineWrapEnabled != enable) + { + m_isLineWrapEnabled = enable; + + if (enable) + m_drawer.SetMaxLineWidth(GetWidth()); + else + m_drawer.SetMaxLineWidth(std::numeric_limits::infinity()); + + UpdateTextSprite(); + } + } + void TextAreaWidget::Erase(std::size_t firstGlyph, std::size_t lastGlyph) { if (firstGlyph > lastGlyph) @@ -188,6 +203,12 @@ namespace Ndk { BaseWidget::Layout(); + if (m_isLineWrapEnabled) + { + m_drawer.SetMaxLineWidth(GetWidth()); + UpdateTextSprite(); + } + RefreshCursor(); } @@ -607,9 +628,14 @@ namespace Ndk break; } - m_textSprite->Update(m_drawer); - SetPreferredSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths())); + UpdateTextSprite(); SetCursorPosition(m_cursorPositionBegin); //< Refresh cursor position (prevent it from being outside of the text) } + + void TextAreaWidget::UpdateTextSprite() + { + m_textSprite->Update(m_drawer); + SetPreferredSize(Nz::Vector2f(m_textSprite->GetBoundingVolume().obb.localBox.GetLengths())); + } } diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 5b4225805..a2fdebc3c 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -38,6 +38,7 @@ namespace Nz std::size_t GetGlyphCount() const override; const Line& GetLine(std::size_t index) const override; std::size_t GetLineCount() const override; + float GetMaxLineWidth() const; const Color& GetOutlineColor() const; float GetOutlineThickness() const; TextStyleFlags GetStyle() const; @@ -46,6 +47,7 @@ namespace Nz void SetCharacterSize(unsigned int characterSize); void SetColor(const Color& color); void SetFont(Font* font); + void SetMaxLineWidth(float lineWidth); void SetOutlineColor(const Color& color); void SetOutlineThickness(float thickness); void SetStyle(TextStyleFlags style); @@ -88,6 +90,7 @@ namespace Nz mutable Vector2ui m_drawPos; mutable bool m_colorUpdated; mutable bool m_glyphUpdated; + float m_maxLineWidth; float m_outlineThickness; unsigned int m_characterSize; }; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 86ba50764..88b954671 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include @@ -14,6 +15,7 @@ namespace Nz m_style(TextStyle_Regular), m_colorUpdated(true), m_glyphUpdated(true), + m_maxLineWidth(std::numeric_limits::infinity()), m_outlineThickness(0.f), m_characterSize(24) { @@ -27,6 +29,7 @@ namespace Nz m_colorUpdated(false), m_glyphUpdated(false), m_outlineColor(drawer.m_outlineColor), + m_maxLineWidth(drawer.m_maxLineWidth), m_outlineThickness(drawer.m_outlineThickness), m_characterSize(drawer.m_characterSize) { @@ -124,6 +127,11 @@ namespace Nz return m_lines.size(); } + float SimpleTextDrawer::GetMaxLineWidth() const + { + return m_maxLineWidth; + } + const Color& SimpleTextDrawer::GetOutlineColor() const { return m_outlineColor; @@ -173,6 +181,15 @@ namespace Nz } } + void SimpleTextDrawer::SetMaxLineWidth(float lineWidth) + { + NazaraAssert(m_maxLineWidth > 0.f, "Max line width must be positive"); + + m_maxLineWidth = lineWidth; + + m_glyphUpdated = false; + } + void SimpleTextDrawer::SetOutlineColor(const Color& color) { m_outlineColor = color; @@ -230,6 +247,7 @@ namespace Nz m_glyphs = std::move(drawer.m_glyphs); m_glyphUpdated = std::move(drawer.m_glyphUpdated); m_font = std::move(drawer.m_font); + m_maxLineWidth = drawer.m_maxLineWidth; m_outlineColor = std::move(drawer.m_outlineColor); m_outlineThickness = std::move(drawer.m_outlineThickness); m_style = std::move(drawer.m_style); @@ -365,7 +383,18 @@ namespace Nz break; } - auto GenerateGlyph = [this](Glyph& glyph, char32_t character, float outlineThickness, Nz::Color color, int renderOrder, int* advance) + auto AppendNewLine = [&]() + { + // Reset cursor + //advance = 0; + m_drawPos.x = 0; + m_drawPos.y += sizeInfo.lineHeight; + + m_workingBounds.ExtendTo(m_lines.back().bounds); + m_lines.emplace_back(Line{ Rectf(0.f, float(sizeInfo.lineHeight * m_lines.size()), 0.f, float(sizeInfo.lineHeight)), m_glyphs.size() + 1 }); + }; + + auto GenerateGlyph = [&](Glyph& glyph, char32_t character, float outlineThickness, Nz::Color color, int renderOrder, int* advance) { const Font::Glyph& fontGlyph = m_font->GetGlyph(m_characterSize, m_style, outlineThickness, character); if (fontGlyph.valid && fontGlyph.fauxOutlineThickness <= 0.f) @@ -377,6 +406,10 @@ namespace Nz glyph.renderOrder = renderOrder; glyph.bounds.Set(fontGlyph.aabb); + + if (m_lines.back().glyphIndex <= m_glyphs.size() && m_lines.back().bounds.GetMaximum().x + glyph.bounds.width > m_maxLineWidth) + AppendNewLine(); + glyph.bounds.x += m_drawPos.x; glyph.bounds.y += m_drawPos.y; @@ -435,13 +468,7 @@ namespace Nz { case '\n': { - // Reset cursor - advance = 0; - m_drawPos.x = 0; - m_drawPos.y += sizeInfo.lineHeight; - - m_workingBounds.ExtendTo(m_lines.back().bounds); - m_lines.emplace_back(Line{Rectf(0.f, float(sizeInfo.lineHeight * m_lines.size()), 0.f, float(sizeInfo.lineHeight)), m_glyphs.size() + 1}); + AppendNewLine(); break; } From e1621bc04415885ba825921c5533840d61cda2a5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Jul 2019 01:09:20 +0200 Subject: [PATCH 30/47] Fix build --- SDK/include/NDK/Widgets/TextAreaWidget.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index 069e89add..52d7a79ad 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -28,6 +28,8 @@ namespace Ndk void AppendText(const Nz::String& text); + void UpdateTextSprite(); + inline void Clear(); //virtual TextAreaWidget* Clone() const = 0; From 7f324dda9a24b2ffd53fcd080b16362634e612e7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Jul 2019 01:09:50 +0200 Subject: [PATCH 31/47] SDK/TextAreaWidget: Add text shifting by cursor position --- SDK/src/NDK/Widgets/TextAreaWidget.cpp | 100 ++++++++++++++++++------- 1 file changed, 74 insertions(+), 26 deletions(-) diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 9d695cf39..20395a2ed 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -10,6 +10,12 @@ namespace Ndk { + namespace + { + constexpr float paddingWidth = 5.f; + constexpr float paddingHeight = 3.f; + } + TextAreaWidget::TextAreaWidget(BaseWidget* parent) : BaseWidget(parent), m_characterFilter(), @@ -22,12 +28,6 @@ namespace Ndk m_readOnly(false), m_tabEnabled(false) { - m_cursorEntity = CreateEntity(); - m_cursorEntity->AddComponent(); - m_cursorEntity->AddComponent().SetParent(this); - m_cursorEntity->GetComponent().SetPosition(5.f, 3.f); - m_cursorEntity->Enable(false); - m_textSprite = Nz::TextSprite::New(); m_textEntity = CreateEntity(); @@ -35,7 +35,13 @@ namespace Ndk auto& textNode = m_textEntity->AddComponent(); textNode.SetParent(this); - textNode.SetPosition(5.f, 3.f); + textNode.SetPosition(paddingWidth, paddingHeight); + + m_cursorEntity = CreateEntity(); + m_cursorEntity->AddComponent(); + m_cursorEntity->AddComponent().SetParent(m_textEntity); + m_cursorEntity->GetComponent(); + m_cursorEntity->Enable(false); SetCursor(Nz::SystemCursor_Text); SetCharacterSize(GetCharacterSize()); //< Actualize minimum / preferred size @@ -134,6 +140,11 @@ namespace Ndk Nz::Vector2ui TextAreaWidget::GetHoveredGlyph(float x, float y) const { + auto& textNode = m_textEntity->GetComponent(); + Nz::Vector2f textPosition = Nz::Vector2f(textNode.GetPosition(Nz::CoordSys_Local)); + x -= textPosition.x; + y -= textPosition.y; + std::size_t glyphCount = m_drawer.GetGlyphCount(); if (glyphCount > 0) { @@ -401,14 +412,14 @@ namespace Ndk { Erase(firstGlyph); SetSelection(cursorPositionBegin - (cursorPositionBegin.y == line && cursorPositionBegin.x != 0U ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {}), - cursorPositionEnd - (cursorPositionEnd.y == line && cursorPositionEnd.x != 0U ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {})); + cursorPositionEnd - (cursorPositionEnd.y == line && cursorPositionEnd.x != 0U ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {})); } } else { Write(Nz::String('\t'), { 0U, line }); SetSelection(cursorPositionBegin + (cursorPositionBegin.y == line && cursorPositionBegin.x != 0U ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {}), - cursorPositionEnd + (cursorPositionEnd.y == line ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {})); + cursorPositionEnd + (cursorPositionEnd.y == line ? Nz::Vector2ui { 1U, 0U } : Nz::Vector2ui {})); } } } @@ -445,7 +456,7 @@ namespace Ndk { SetFocus(); - Nz::Vector2ui hoveredGlyph = GetHoveredGlyph(float(x) - 5.f, float(y) - 5.f); + Nz::Vector2ui hoveredGlyph = GetHoveredGlyph(float(x), float(y)); // Shift extends selection if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift)) @@ -475,7 +486,7 @@ namespace Ndk void TextAreaWidget::OnMouseMoved(int x, int y, int deltaX, int deltaY) { if (m_isMouseButtonDown) - SetSelection(m_selectionCursor, GetHoveredGlyph(float(x) - 5.f, float(y) - 3.f)); + SetSelection(m_selectionCursor, GetHoveredGlyph(float(x), float(y))); } void TextAreaWidget::OnTextEntered(char32_t character, bool /*repeated*/) @@ -552,6 +563,46 @@ namespace Ndk if (m_readOnly) return; + auto GetGlyph = [&](const Nz::Vector2ui& glyphPosition, std::size_t* glyphIndex) -> const Nz::AbstractTextDrawer::Glyph* + { + const auto& lineInfo = m_drawer.GetLine(glyphPosition.y); + + std::size_t cursorGlyph = GetGlyphIndex({ glyphPosition.x, glyphPosition.y }); + if (glyphIndex) + *glyphIndex = cursorGlyph; + + std::size_t glyphCount = m_drawer.GetGlyphCount(); + float position; + if (glyphCount > 0 && lineInfo.glyphIndex < cursorGlyph) + { + const auto& glyph = m_drawer.GetGlyph(std::min(cursorGlyph, glyphCount - 1)); + return &glyph; + } + else + return nullptr; + }; + + // Move text so that cursor is always visible + const auto* glyph = GetGlyph(m_cursorPositionEnd, nullptr); + float glyphPos = (glyph) ? glyph->bounds.x : 0.f; + float glyphWidth = (glyph) ? glyph->bounds.width : 0.f; + + auto& node = m_textEntity->GetComponent(); + float textPosition = node.GetPosition(Nz::CoordSys_Local).x - paddingWidth; + float cursorPosition = glyphPos + textPosition; + float width = GetWidth(); + + if (width <= m_drawer.GetBounds().width) + { + if (cursorPosition + glyphWidth > width) + node.Move(width - cursorPosition - glyphWidth, 0.f); + else if (cursorPosition - glyphWidth < 0.f) + node.Move(-cursorPosition + glyphWidth, 0.f); + } + else + node.Move(-textPosition, 0.f); // Reset text position if we have enough room to show everything + + // Show cursor/selection std::size_t selectionLineCount = m_cursorPositionEnd.y - m_cursorPositionBegin.y + 1; std::size_t oldSpriteCount = m_cursorSprites.size(); if (m_cursorSprites.size() != selectionLineCount) @@ -576,27 +627,24 @@ namespace Ndk Nz::SpriteRef& cursorSprite = m_cursorSprites[i - m_cursorPositionBegin.y]; if (i == m_cursorPositionBegin.y || i == m_cursorPositionEnd.y) { - auto GetGlyphPos = [&](unsigned int localGlyphPos) + auto GetGlyphPos = [&](const Nz::Vector2ui& glyphPosition) { - std::size_t cursorGlyph = GetGlyphIndex({ localGlyphPos, i }); - - std::size_t glyphCount = m_drawer.GetGlyphCount(); - float position; - if (glyphCount > 0 && lineInfo.glyphIndex < cursorGlyph) + std::size_t glyphIndex; + const auto* glyph = GetGlyph(glyphPosition, &glyphIndex); + if (glyph) { - const auto& glyph = m_drawer.GetGlyph(std::min(cursorGlyph, glyphCount - 1)); - position = glyph.bounds.x; - if (cursorGlyph >= glyphCount) - position += glyph.bounds.width; + float position = glyph->bounds.x; + if (glyphIndex >= m_drawer.GetGlyphCount()) + position += glyph->bounds.width; + + return position; } else - position = 0.f; - - return position; + return 0.f; }; - float beginX = (i == m_cursorPositionBegin.y) ? GetGlyphPos(m_cursorPositionBegin.x) : 0.f; - float endX = (i == m_cursorPositionEnd.y) ? GetGlyphPos(m_cursorPositionEnd.x) : lineInfo.bounds.width; + float beginX = (i == m_cursorPositionBegin.y) ? GetGlyphPos({ m_cursorPositionBegin.x, i }) : 0.f; + float endX = (i == m_cursorPositionEnd.y) ? GetGlyphPos({ m_cursorPositionEnd.x, i }) : lineInfo.bounds.width; float spriteSize = std::max(endX - beginX, 1.f); cursorSprite->SetColor((m_cursorPositionBegin == m_cursorPositionEnd) ? Nz::Color::Black : Nz::Color(0, 0, 0, 50)); From 3617f4054ad3ac78b3219bb389b728f697712ac6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Jul 2019 19:31:29 +0200 Subject: [PATCH 32/47] Update ChangeLog.md --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index 49790d33f..64e1718cd 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -277,6 +277,7 @@ Nazara Development Kit: - Added ScrollAreaWidget - Console has been remade with widgets (allowing to scroll back history, select text, etc.) - Added TextAreaWidget line wrap option +- TextAreaWidget will now shift the text to the left/right in order to keep the cursor visible # 0.4: From 55e3e05f0c8964de53300870a39c8df9b77cd330 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Jul 2019 19:32:11 +0200 Subject: [PATCH 33/47] Improve line wrap It will now try to separate at word separations --- include/Nazara/Utility/SimpleTextDrawer.hpp | 8 + src/Nazara/Utility/SimpleTextDrawer.cpp | 173 +++++++++++++------- 2 files changed, 125 insertions(+), 56 deletions(-) diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index a2fdebc3c..525f49cc5 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -62,21 +62,29 @@ namespace Nz static SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor); private: + void AppendNewLine() const; + void AppendNewLine(std::size_t glyphIndex, unsigned int glyphPosition) const; void ClearGlyphs() const; void ConnectFontSlots(); void DisconnectFontSlots(); + bool GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, Nz::Color color, int renderOrder, int* advance) const; void GenerateGlyphs(const String& text) const; void OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer); void OnFontInvalidated(const Font* font); void OnFontRelease(const Font* object); + bool ShouldLineWrap(Glyph& glyph, float size, bool checkFirstGlyph = true) const; void UpdateGlyphColor() const; void UpdateGlyphs() const; + static constexpr std::size_t InvalidGlyph = std::numeric_limits::max(); + NazaraSlot(Font, OnFontAtlasChanged, m_atlasChangedSlot); NazaraSlot(Font, OnFontAtlasLayerChanged, m_atlasLayerChangedSlot); NazaraSlot(Font, OnFontGlyphCacheCleared, m_glyphCacheClearedSlot); NazaraSlot(Font, OnFontRelease, m_fontReleaseSlot); + mutable std::size_t m_lastSeparatorGlyph; + mutable unsigned int m_lastSeparatorPosition; mutable std::vector m_glyphs; mutable std::vector m_lines; Color m_color; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 88b954671..6bf0830df 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -309,11 +309,66 @@ namespace Nz return drawer; } + void SimpleTextDrawer::AppendNewLine() const + { + AppendNewLine(InvalidGlyph, 0.f); + } + + void SimpleTextDrawer::AppendNewLine(std::size_t glyphIndex, unsigned int glyphPosition) const + { + // Ensure we're appending from last line + Line& lastLine = m_lines.back(); + + const Font::SizeInfo& sizeInfo = m_font->GetSizeInfo(m_characterSize); + + unsigned int previousDrawPos = m_drawPos.x; + + // Reset cursor + m_drawPos.x = 0; + m_drawPos.y += sizeInfo.lineHeight; + m_lastSeparatorGlyph = InvalidGlyph; + + m_workingBounds.ExtendTo(lastLine.bounds); + m_lines.emplace_back(Line{ Rectf(0.f, float(sizeInfo.lineHeight * m_lines.size()), 0.f, float(sizeInfo.lineHeight)), m_glyphs.size() + 1 }); + + if (glyphIndex != InvalidGlyph && glyphIndex > lastLine.glyphIndex) + { + Line& newLine = m_lines.back(); + newLine.glyphIndex = glyphIndex; + + for (std::size_t i = glyphIndex; i < m_glyphs.size(); ++i) + { + Glyph& glyph = m_glyphs[i]; + glyph.bounds.x -= glyphPosition; + glyph.bounds.y += sizeInfo.lineHeight; + + for (auto& corner : glyph.corners) + { + corner.x -= glyphPosition; + corner.y += sizeInfo.lineHeight; + } + + newLine.bounds.ExtendTo(glyph.bounds); + } + + assert(previousDrawPos >= glyphPosition); + m_drawPos.x += previousDrawPos - glyphPosition; + + lastLine.bounds.width -= lastLine.bounds.GetMaximum().x - m_lastSeparatorPosition; + + // Regenerate working bounds + m_workingBounds.MakeZero(); + for (std::size_t i = 0; i < m_lines.size(); ++i) + m_workingBounds.ExtendTo(m_lines[i].bounds); + } + } + void SimpleTextDrawer::ClearGlyphs() const { m_bounds.MakeZero(); m_colorUpdated = true; m_drawPos.Set(0, m_characterSize); //< Our draw "cursor" + m_lastSeparatorGlyph = InvalidGlyph; m_lines.clear(); m_glyphs.clear(); m_glyphUpdated = true; @@ -342,6 +397,46 @@ namespace Nz m_glyphCacheClearedSlot.Disconnect(); } + bool SimpleTextDrawer::GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, Nz::Color color, int renderOrder, int* advance) const + { + const Font::Glyph& fontGlyph = m_font->GetGlyph(m_characterSize, m_style, outlineThickness, character); + if (fontGlyph.valid && fontGlyph.fauxOutlineThickness <= 0.f) + { + glyph.atlas = m_font->GetAtlas()->GetLayer(fontGlyph.layerIndex); + glyph.atlasRect = fontGlyph.atlasRect; + glyph.color = color; + glyph.flipped = fontGlyph.flipped; + glyph.renderOrder = renderOrder; + + glyph.bounds.Set(fontGlyph.aabb); + + if (lineWrap && ShouldLineWrap(glyph, glyph.bounds.width)) + AppendNewLine(m_lastSeparatorGlyph, m_lastSeparatorPosition); + + glyph.bounds.x += m_drawPos.x; + glyph.bounds.y += m_drawPos.y; + + // Faux bold and faux outline thickness are not supported + + // We "lean" the glyph to simulate italics style + float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f; + float italicTop = italic * glyph.bounds.y; + float italicBottom = italic * glyph.bounds.GetMaximum().y; + + glyph.corners[0].Set(glyph.bounds.x - italicTop - outlineThickness, glyph.bounds.y - outlineThickness); + glyph.corners[1].Set(glyph.bounds.x + glyph.bounds.width - italicTop - outlineThickness, glyph.bounds.y - outlineThickness); + glyph.corners[2].Set(glyph.bounds.x - italicBottom - outlineThickness, glyph.bounds.y + glyph.bounds.height - outlineThickness); + glyph.corners[3].Set(glyph.bounds.x + glyph.bounds.width - italicBottom - outlineThickness, glyph.bounds.y + glyph.bounds.height - outlineThickness); + + if (advance) + *advance = fontGlyph.advance; + + return true; + } + else + return false; + }; + void SimpleTextDrawer::GenerateGlyphs(const String& text) const { if (text.IsEmpty()) @@ -383,78 +478,30 @@ namespace Nz break; } - auto AppendNewLine = [&]() - { - // Reset cursor - //advance = 0; - m_drawPos.x = 0; - m_drawPos.y += sizeInfo.lineHeight; - - m_workingBounds.ExtendTo(m_lines.back().bounds); - m_lines.emplace_back(Line{ Rectf(0.f, float(sizeInfo.lineHeight * m_lines.size()), 0.f, float(sizeInfo.lineHeight)), m_glyphs.size() + 1 }); - }; - - auto GenerateGlyph = [&](Glyph& glyph, char32_t character, float outlineThickness, Nz::Color color, int renderOrder, int* advance) - { - const Font::Glyph& fontGlyph = m_font->GetGlyph(m_characterSize, m_style, outlineThickness, character); - if (fontGlyph.valid && fontGlyph.fauxOutlineThickness <= 0.f) - { - glyph.atlas = m_font->GetAtlas()->GetLayer(fontGlyph.layerIndex); - glyph.atlasRect = fontGlyph.atlasRect; - glyph.color = color; - glyph.flipped = fontGlyph.flipped; - glyph.renderOrder = renderOrder; - - glyph.bounds.Set(fontGlyph.aabb); - - if (m_lines.back().glyphIndex <= m_glyphs.size() && m_lines.back().bounds.GetMaximum().x + glyph.bounds.width > m_maxLineWidth) - AppendNewLine(); - - glyph.bounds.x += m_drawPos.x; - glyph.bounds.y += m_drawPos.y; - - // Faux bold and faux outline thickness are not supported - - // We "lean" the glyph to simulate italics style - float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f; - float italicTop = italic * glyph.bounds.y; - float italicBottom = italic * glyph.bounds.GetMaximum().y; - - glyph.corners[0].Set(glyph.bounds.x - italicTop - outlineThickness, glyph.bounds.y - outlineThickness); - glyph.corners[1].Set(glyph.bounds.x + glyph.bounds.width - italicTop - outlineThickness, glyph.bounds.y - outlineThickness); - glyph.corners[2].Set(glyph.bounds.x - italicBottom - outlineThickness, glyph.bounds.y + glyph.bounds.height - outlineThickness); - glyph.corners[3].Set(glyph.bounds.x + glyph.bounds.width - italicBottom - outlineThickness, glyph.bounds.y + glyph.bounds.height - outlineThickness); - - if (advance) - *advance = fontGlyph.advance; - - return true; - } - else - return false; - }; - Glyph glyph; if (!whitespace) { - if (!GenerateGlyph(glyph, character, 0.f, m_color, 0, &advance)) + if (!GenerateGlyph(glyph, character, 0.f, true, m_color, 0, &advance)) continue; // Glyph failed to load, just skip it (can't do much) if (m_outlineThickness > 0.f) { Glyph outlineGlyph; - if (GenerateGlyph(outlineGlyph, character, m_outlineThickness, m_outlineColor, -1, nullptr)) + if (GenerateGlyph(outlineGlyph, character, m_outlineThickness, false, m_outlineColor, -1, nullptr)) { - m_lines.back().bounds.ExtendTo(outlineGlyph.bounds); m_glyphs.push_back(outlineGlyph); } } } else { - glyph.atlas = nullptr; + float glyphAdvance = advance; - glyph.bounds.Set(float(m_drawPos.x), m_lines.back().bounds.y, float(advance), float(sizeInfo.lineHeight)); + if (ShouldLineWrap(glyph, glyphAdvance)) + AppendNewLine(m_lastSeparatorGlyph, m_lastSeparatorPosition); + + glyph.atlas = nullptr; + glyph.bounds.Set(float(m_drawPos.x), m_lines.back().bounds.y, glyphAdvance, float(sizeInfo.lineHeight)); glyph.corners[0].Set(glyph.bounds.GetCorner(RectCorner_LeftTop)); glyph.corners[1].Set(glyph.bounds.GetCorner(RectCorner_RightTop)); @@ -477,6 +524,12 @@ namespace Nz break; } + if (whitespace) + { + m_lastSeparatorGlyph = m_glyphs.size(); + m_lastSeparatorPosition = m_drawPos.x; + } + m_glyphs.push_back(glyph); } @@ -540,6 +593,14 @@ namespace Nz SetFont(nullptr); } + bool SimpleTextDrawer::ShouldLineWrap(Glyph& glyph, float size, bool checkFirstGlyph) const + { + if (checkFirstGlyph && m_lines.back().glyphIndex > m_glyphs.size()) + return false; + + return m_lines.back().bounds.GetMaximum().x + size > m_maxLineWidth; + } + void SimpleTextDrawer::UpdateGlyphColor() const { if (m_outlineThickness > 0.f) From 8457cb4df7cf3627338d73c7bcaf95ca12534a17 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Jul 2019 00:23:49 +0200 Subject: [PATCH 34/47] SDK/TextAreaWidget: Add [Get|Set]TextFont --- ChangeLog.md | 1 + SDK/include/NDK/Widgets/TextAreaWidget.hpp | 2 ++ SDK/include/NDK/Widgets/TextAreaWidget.inl | 12 ++++++++++++ SDK/src/NDK/Console.cpp | 4 ++-- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 64e1718cd..077ae0ee7 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -278,6 +278,7 @@ Nazara Development Kit: - Console has been remade with widgets (allowing to scroll back history, select text, etc.) - Added TextAreaWidget line wrap option - TextAreaWidget will now shift the text to the left/right in order to keep the cursor visible +- Added TextAreaWidget::[Get|Set]TextFont # 0.4: diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index 52d7a79ad..223a3759f 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -52,6 +52,7 @@ namespace Ndk inline std::size_t GetGlyphIndex(const Nz::Vector2ui& cursorPosition) const; inline const Nz::String& GetText() const; inline const Nz::Color& GetTextColor() const; + inline Nz::Font* GetTextFont() const; inline const Nz::Color& GetTextOulineColor() const; inline float GetTextOulineThickness() const; @@ -76,6 +77,7 @@ namespace Ndk inline void SetSelection(Nz::Vector2ui fromPosition, Nz::Vector2ui toPosition); inline void SetText(const Nz::String& text); inline void SetTextColor(const Nz::Color& text); + inline void SetTextFont(Nz::FontRef font); inline void SetTextOutlineColor(const Nz::Color& color); inline void SetTextOutlineThickness(float thickness); diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index c66662f32..535936243 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -108,6 +108,11 @@ namespace Ndk return m_drawer.GetColor(); } + inline Nz::Font* TextAreaWidget::GetTextFont() const + { + return m_drawer.GetFont(); + } + inline const Nz::Color& TextAreaWidget::GetTextOulineColor() const { return m_drawer.GetOutlineColor(); @@ -265,6 +270,13 @@ namespace Ndk UpdateDisplayText(); } + inline void TextAreaWidget::SetTextFont(Nz::FontRef font) + { + m_drawer.SetFont(font); + + UpdateDisplayText(); + } + inline void TextAreaWidget::SetTextOutlineColor(const Nz::Color& color) { m_drawer.SetOutlineColor(color); diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 4108cddc5..8bfa48a0f 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -170,8 +170,8 @@ namespace Ndk NazaraAssert(font && font->IsValid(), "Invalid font"); m_defaultFont = std::move(font); - //m_historyDrawer.SetFont(m_defaultFont); - //m_inputDrawer.SetFont(m_defaultFont); + m_history->SetTextFont(m_defaultFont); + m_input->SetTextFont(m_defaultFont); Layout(); } From d8f6af319148db111867982b5f511eec4dde2f65 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Jul 2019 00:24:02 +0200 Subject: [PATCH 35/47] Fix some stuff --- SDK/include/NDK/Widgets/TextAreaWidget.hpp | 3 +-- SDK/src/NDK/Widgets/TextAreaWidget.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index 223a3759f..c89f46884 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -28,8 +28,6 @@ namespace Ndk void AppendText(const Nz::String& text); - void UpdateTextSprite(); - inline void Clear(); //virtual TextAreaWidget* Clone() const = 0; @@ -115,6 +113,7 @@ namespace Ndk void RefreshCursor(); void UpdateDisplayText(); + void UpdateTextSprite(); CharacterFilter m_characterFilter; EchoMode m_echoMode; diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 20395a2ed..3ab119a0a 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -168,7 +168,7 @@ namespace Ndk break; } - return Nz::Vector2ui(i - firstLineGlyph, line); + return Nz::Vector2ui(Nz::Vector2(i - firstLineGlyph, line)); } return Nz::Vector2ui::Zero(); @@ -572,7 +572,6 @@ namespace Ndk *glyphIndex = cursorGlyph; std::size_t glyphCount = m_drawer.GetGlyphCount(); - float position; if (glyphCount > 0 && lineInfo.glyphIndex < cursorGlyph) { const auto& glyph = m_drawer.GetGlyph(std::min(cursorGlyph, glyphCount - 1)); From 3bda97a60af7a53f9ef982b8754f01ea0a32ae07 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Jul 2019 00:27:20 +0200 Subject: [PATCH 36/47] SDK/TextAreaWidget: OnTextAreaCursorMove now uses a Vector2ui as its second argument Also add OnTextAreaSelection signal --- ChangeLog.md | 2 + SDK/include/NDK/Widgets/TextAreaWidget.hpp | 8 ++- SDK/include/NDK/Widgets/TextAreaWidget.inl | 71 ++++++++++++++-------- SDK/src/NDK/Console.cpp | 10 ++- 4 files changed, 62 insertions(+), 29 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 077ae0ee7..7100c7027 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -279,6 +279,8 @@ Nazara Development Kit: - Added TextAreaWidget line wrap option - TextAreaWidget will now shift the text to the left/right in order to keep the cursor visible - Added TextAreaWidget::[Get|Set]TextFont +- ⚠️ TextAreaWidget::OnTextAreaCursorMove signal now uses a Vector2ui* position as its second argument (instead of a std::size_t*) +- Added TextAreaWidget::OnTextAreaSelection # 0.4: diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.hpp b/SDK/include/NDK/Widgets/TextAreaWidget.hpp index c89f46884..ebce9e464 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/TextAreaWidget.hpp @@ -66,6 +66,8 @@ namespace Ndk inline void MoveCursor(int offset); inline void MoveCursor(const Nz::Vector2i& offset); + inline Nz::Vector2ui NormalizeCursorPosition(Nz::Vector2ui cursorPosition) const; + inline void SetCharacterFilter(CharacterFilter filter); void SetCharacterSize(unsigned int characterSize); inline void SetCursorPosition(std::size_t glyphIndex); @@ -86,7 +88,7 @@ namespace Ndk TextAreaWidget& operator=(const TextAreaWidget&) = delete; TextAreaWidget& operator=(TextAreaWidget&&) = default; - NazaraSignal(OnTextAreaCursorMove, const TextAreaWidget* /*textArea*/, std::size_t* /*newCursorPosition*/); + NazaraSignal(OnTextAreaCursorMove, const TextAreaWidget* /*textArea*/, Nz::Vector2ui* /*newCursorPosition*/); NazaraSignal(OnTextAreaKeyBackspace, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); NazaraSignal(OnTextAreaKeyDown, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); NazaraSignal(OnTextAreaKeyEnd, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); @@ -95,6 +97,7 @@ namespace Ndk NazaraSignal(OnTextAreaKeyReturn, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); NazaraSignal(OnTextAreaKeyRight, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); NazaraSignal(OnTextAreaKeyUp, const TextAreaWidget* /*textArea*/, bool* /*ignoreDefaultAction*/); + NazaraSignal(OnTextAreaSelection, const TextAreaWidget* /*textArea*/, Nz::Vector2ui* /*start*/, Nz::Vector2ui* /*end*/); NazaraSignal(OnTextChanged, const TextAreaWidget* /*textArea*/, const Nz::String& /*text*/); private: @@ -111,6 +114,9 @@ namespace Ndk void OnMouseMoved(int x, int y, int deltaX, int deltaY) override; void OnTextEntered(char32_t character, bool repeated) override; + inline void SetCursorPositionInternal(std::size_t glyphIndex); + inline void SetCursorPositionInternal(Nz::Vector2ui cursorPosition); + void RefreshCursor(); void UpdateDisplayText(); void UpdateTextSprite(); diff --git a/SDK/include/NDK/Widgets/TextAreaWidget.inl b/SDK/include/NDK/Widgets/TextAreaWidget.inl index 535936243..bdb95854e 100644 --- a/SDK/include/NDK/Widgets/TextAreaWidget.inl +++ b/SDK/include/NDK/Widgets/TextAreaWidget.inl @@ -186,29 +186,12 @@ namespace Ndk SetCursorPosition(cursorPosition); } - inline void TextAreaWidget::SetCharacterFilter(CharacterFilter filter) - { - m_characterFilter = std::move(filter); - } - - inline void TextAreaWidget::SetCursorPosition(std::size_t glyphIndex) - { - OnTextAreaCursorMove(this, &glyphIndex); - - m_cursorPositionBegin = GetCursorPosition(glyphIndex); - m_cursorPositionEnd = m_cursorPositionBegin; - - RefreshCursor(); - } - - inline void TextAreaWidget::SetCursorPosition(Nz::Vector2ui cursorPosition) + inline Nz::Vector2ui TextAreaWidget::NormalizeCursorPosition(Nz::Vector2ui cursorPosition) const { std::size_t lineCount = m_drawer.GetLineCount(); if (cursorPosition.y >= lineCount) cursorPosition.y = static_cast(lineCount - 1); - m_cursorPositionBegin = cursorPosition; - const auto& lineInfo = m_drawer.GetLine(cursorPosition.y); if (cursorPosition.y + 1 < lineCount) { @@ -216,13 +199,32 @@ namespace Ndk cursorPosition.x = std::min(cursorPosition.x, static_cast(nextLineInfo.glyphIndex - lineInfo.glyphIndex - 1)); } - m_cursorPositionEnd = m_cursorPositionBegin; + return cursorPosition; + } - std::size_t glyphIndex = lineInfo.glyphIndex + cursorPosition.x; + inline void TextAreaWidget::SetCharacterFilter(CharacterFilter filter) + { + m_characterFilter = std::move(filter); + } - OnTextAreaCursorMove(this, &glyphIndex); + inline void TextAreaWidget::SetCursorPosition(std::size_t glyphIndex) + { + Nz::Vector2ui position = GetCursorPosition(glyphIndex); + Nz::Vector2ui newPosition = position; - RefreshCursor(); + OnTextAreaCursorMove(this, &newPosition); + + if (position == newPosition) + SetCursorPositionInternal(position); + else + SetCursorPositionInternal(GetGlyphIndex(newPosition)); + } + + inline void TextAreaWidget::SetCursorPosition(Nz::Vector2ui cursorPosition) + { + OnTextAreaCursorMove(this, &cursorPosition); + + return SetCursorPositionInternal(NormalizeCursorPosition(cursorPosition)); } inline void TextAreaWidget::SetEchoMode(EchoMode echoMode) @@ -240,16 +242,20 @@ namespace Ndk inline void TextAreaWidget::SetSelection(Nz::Vector2ui fromPosition, Nz::Vector2ui toPosition) { - ///TODO: Check if position are valid - // Ensure begin is before end if (toPosition.y < fromPosition.y || (toPosition.y == fromPosition.y && toPosition.x < fromPosition.x)) std::swap(fromPosition, toPosition); if (m_cursorPositionBegin != fromPosition || m_cursorPositionEnd != toPosition) { - m_cursorPositionBegin = fromPosition; - m_cursorPositionEnd = toPosition; + OnTextAreaSelection(this, &fromPosition, &toPosition); + + // Ensure begin is before end a second time (in case signal changed it) + if (toPosition.y < fromPosition.y || (toPosition.y == fromPosition.y && toPosition.x < fromPosition.x)) + std::swap(fromPosition, toPosition); + + m_cursorPositionBegin = NormalizeCursorPosition(fromPosition); + m_cursorPositionEnd = NormalizeCursorPosition(toPosition); RefreshCursor(); } @@ -300,4 +306,17 @@ namespace Ndk { Write(text, GetGlyphIndex(glyphPosition)); } + + void TextAreaWidget::SetCursorPositionInternal(std::size_t glyphIndex) + { + return SetCursorPositionInternal(GetCursorPosition(glyphIndex)); + } + + inline void TextAreaWidget::SetCursorPositionInternal(Nz::Vector2ui cursorPosition) + { + m_cursorPositionBegin = cursorPosition; + m_cursorPositionEnd = m_cursorPositionBegin; + + RefreshCursor(); + } } diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 8bfa48a0f..088c29444 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -62,9 +62,15 @@ namespace Ndk // Protect input prefix from erasure/selection m_input->SetCursorPosition(s_inputPrefixSize); - m_input->OnTextAreaCursorMove.Connect([](const TextAreaWidget* textArea, std::size_t* newCursorPos) + m_input->OnTextAreaCursorMove.Connect([](const TextAreaWidget* textArea, Nz::Vector2ui* newCursorPos) { - *newCursorPos = std::max(*newCursorPos, s_inputPrefixSize); + newCursorPos->x = std::max(newCursorPos->x, static_cast(s_inputPrefixSize)); + }); + + m_input->OnTextAreaSelection.Connect([](const TextAreaWidget* textArea, Nz::Vector2ui* start, Nz::Vector2ui* end) + { + start->x = std::max(start->x, static_cast(s_inputPrefixSize)); + end->x = std::max(end->x, static_cast(s_inputPrefixSize)); }); m_input->OnTextAreaKeyBackspace.Connect([](const TextAreaWidget* textArea, bool* ignoreDefaultAction) From c6d601c42977969f1d1e9ed2d852f93c76f486e3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Jul 2019 00:28:51 +0200 Subject: [PATCH 37/47] SDK/Console: Add OnCommand signal and remove LuaState dependency --- ChangeLog.md | 1 + SDK/include/NDK/Console.hpp | 6 +++--- SDK/src/NDK/Application.cpp | 27 ++++++++++++++------------- SDK/src/NDK/Console.cpp | 11 +++-------- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 7100c7027..587e763bd 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -281,6 +281,7 @@ Nazara Development Kit: - Added TextAreaWidget::[Get|Set]TextFont - ⚠️ TextAreaWidget::OnTextAreaCursorMove signal now uses a Vector2ui* position as its second argument (instead of a std::size_t*) - Added TextAreaWidget::OnTextAreaSelection +- ⚠️ Console class is no longer bound to a LuaState and now has a OnCommand signal # 0.4: diff --git a/SDK/include/NDK/Console.hpp b/SDK/include/NDK/Console.hpp index cb79fcbee..32d0cd76a 100644 --- a/SDK/include/NDK/Console.hpp +++ b/SDK/include/NDK/Console.hpp @@ -19,7 +19,6 @@ namespace Nz { - class LuaState; struct WindowEvent; } @@ -35,7 +34,7 @@ namespace Ndk class NDK_API Console : public BaseWidget, public Nz::HandledObject { public: - Console(BaseWidget* parent, Nz::LuaState& state); + Console(BaseWidget* parent); Console(const Console& console) = delete; Console(Console&& console) = default; ~Console() = default; @@ -57,6 +56,8 @@ namespace Ndk Console& operator=(const Console& console) = delete; Console& operator=(Console&& console) = default; + NazaraSignal(OnCommand, Console* /*console*/, const Nz::String& /*command*/); + private: void ExecuteInput(const TextAreaWidget* textArea, bool* ignoreDefaultAction); void Layout() override; @@ -74,7 +75,6 @@ namespace Ndk TextAreaWidget* m_history; TextAreaWidget* m_input; Nz::FontRef m_defaultFont; - Nz::LuaState& m_state; unsigned int m_characterSize; unsigned int m_maxHistoryLines; }; diff --git a/SDK/src/NDK/Application.cpp b/SDK/src/NDK/Application.cpp index c26b1e7d2..cf6fcdbb5 100644 --- a/SDK/src/NDK/Application.cpp +++ b/SDK/src/NDK/Application.cpp @@ -151,7 +151,14 @@ namespace Ndk else windowDimensions.MakeZero(); - overlay->console = info.canvas->Add(overlay->lua); + Nz::LuaInstance& lua = overlay->lua; + + overlay->console = info.canvas->Add(); + overlay->console->OnCommand.Connect([&lua](Ndk::Console* console, const Nz::String& command) + { + if (!lua.Execute(command)) + console->AddLine(lua.GetLastError(), Nz::Color::Red); + }); Console& consoleRef = *overlay->console; consoleRef.Resize({float(windowDimensions.x), windowDimensions.y / 4.f}); @@ -163,11 +170,11 @@ namespace Ndk consoleRef.AddLine(str); }); - overlay->lua.LoadLibraries(); - LuaAPI::RegisterClasses(overlay->lua); + lua.LoadLibraries(); + LuaAPI::RegisterClasses(lua); // Override "print" function to add a line in the console - overlay->lua.PushFunction([&consoleRef] (Nz::LuaState& state) + lua.PushFunction([&consoleRef] (Nz::LuaState& state) { Nz::StringStream stream; @@ -191,21 +198,15 @@ namespace Ndk consoleRef.AddLine(stream); return 0; }); - overlay->lua.SetGlobal("print"); + lua.SetGlobal("print"); // Define a few base variables to allow our interface to interact with the application - overlay->lua.PushGlobal("Application", Ndk::Application::Instance()); - overlay->lua.PushGlobal("Console", consoleRef.CreateHandle()); + lua.PushGlobal("Application", Ndk::Application::Instance()); + lua.PushGlobal("Console", consoleRef.CreateHandle()); // Setup a few event callback to handle the console Nz::EventHandler& eventHandler = info.window->GetEventHandler(); - /*overlay->eventSlot.Connect(eventHandler.OnEvent, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent& event) - { - if (consoleRef.IsVisible()) - consoleRef.SendEvent(event); - });*/ - overlay->keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& event) { if (event.code == Nz::Keyboard::F9) diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 088c29444..964bb6b9c 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -35,11 +34,10 @@ namespace Ndk * \param instance Lua instance that will interact with the world */ - Console::Console(BaseWidget* parent, Nz::LuaState& state) : + Console::Console(BaseWidget* parent) : BaseWidget(parent), m_historyPosition(0), m_defaultFont(Nz::Font::GetDefault()), - m_state(state), m_characterSize(24) { // History @@ -185,8 +183,7 @@ namespace Ndk /*! * \brief Performs this action when an input is added to the console */ - - void Console::ExecuteInput(const TextAreaWidget* textArea, bool* ignoreDefaultAction) + void Console::ExecuteInput(const TextAreaWidget* textArea, bool* /*ignoreDefaultAction*/) { NazaraAssert(textArea == m_input, "Unexpected signal from an other text area"); @@ -201,14 +198,12 @@ namespace Ndk AddLine(input); //< With the input prefix - if (!m_state.Execute(inputCmd)) - AddLine(m_state.GetLastError(), Nz::Color::Red); + OnCommand(this, inputCmd); } /*! * \brief Places the console according to its layout */ - void Console::Layout() { Nz::Vector2f origin = Nz::Vector2f(GetPosition()); From f5dc27ba032ec02218847999ab420fb022c4b694 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Jul 2019 00:32:57 +0200 Subject: [PATCH 38/47] Fix unit test --- tests/Engine/Network/IpAddress.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Engine/Network/IpAddress.cpp b/tests/Engine/Network/IpAddress.cpp index abcb65909..571e7ec75 100644 --- a/tests/Engine/Network/IpAddress.cpp +++ b/tests/Engine/Network/IpAddress.cpp @@ -40,7 +40,9 @@ SCENARIO("IpAddress", "[NETWORK][IPADDRESS]") Nz::IpAddress google(8, 8, 8, 8); THEN("Google (DNS) is 8.8.8.8") { - CHECK(Nz::IpAddress::ResolveAddress(google) == "google-public-dns-a.google.com"); + Nz::String dnsAddress = Nz::IpAddress::ResolveAddress(google); + bool dnsCheck = dnsAddress == "google-public-dns-a.google.com" || dnsAddress == "dns.google"; + CHECK(dnsCheck); } } } From 7da8945c72e80fb1f0a82ecaeeac792af1fc4044 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Jul 2019 16:28:09 +0200 Subject: [PATCH 39/47] SDK/ScrollAreaWidget: Add EnableScrollbar --- SDK/include/NDK/Widgets/ScrollAreaWidget.hpp | 9 +++++- SDK/include/NDK/Widgets/ScrollAreaWidget.inl | 15 ++++++++++ SDK/src/NDK/Widgets/ScrollAreaWidget.cpp | 30 +++++++++++++++----- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/SDK/include/NDK/Widgets/ScrollAreaWidget.hpp b/SDK/include/NDK/Widgets/ScrollAreaWidget.hpp index 5b7106b1f..17ada16ef 100644 --- a/SDK/include/NDK/Widgets/ScrollAreaWidget.hpp +++ b/SDK/include/NDK/Widgets/ScrollAreaWidget.hpp @@ -21,9 +21,15 @@ namespace Ndk ScrollAreaWidget(ScrollAreaWidget&&) = default; ~ScrollAreaWidget() = default; + void EnableScrollbar(bool enable); + inline float GetScrollHeight() const; inline float GetScrollRatio() const; + inline bool HasScrollbar() const; + inline bool IsScrollbarEnabled() const; + inline bool IsScrollbarVisible() const; + inline void ScrollToHeight(float height); void ScrollToRatio(float ratio); @@ -57,7 +63,8 @@ namespace Ndk Nz::SpriteRef m_scrollbarSprite; Nz::Vector2i m_grabbedDelta; ScrollBarStatus m_scrollbarStatus; - bool m_isScrollBarVisible; + bool m_isScrollbarEnabled; + bool m_hasScrollbar; float m_scrollRatio; }; } diff --git a/SDK/include/NDK/Widgets/ScrollAreaWidget.inl b/SDK/include/NDK/Widgets/ScrollAreaWidget.inl index c98230180..89bea6d47 100644 --- a/SDK/include/NDK/Widgets/ScrollAreaWidget.inl +++ b/SDK/include/NDK/Widgets/ScrollAreaWidget.inl @@ -16,6 +16,21 @@ namespace Ndk return m_scrollRatio; } + inline bool ScrollAreaWidget::HasScrollbar() const + { + return m_hasScrollbar; + } + + inline bool ScrollAreaWidget::IsScrollbarEnabled() const + { + return m_isScrollbarEnabled; + } + + inline bool ScrollAreaWidget::IsScrollbarVisible() const + { + return HasScrollbar() && IsScrollbarEnabled(); + } + inline void ScrollAreaWidget::ScrollToHeight(float height) { float contentHeight = m_content->GetHeight(); diff --git a/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp b/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp index 4f5ca3f6b..b7ec0d020 100644 --- a/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp @@ -18,6 +18,7 @@ namespace Ndk BaseWidget(parent), m_content(content), m_scrollbarStatus(ScrollBarStatus::None), + m_isScrollbarEnabled(true), m_scrollRatio(0.f) { m_content->SetParent(this); @@ -42,6 +43,18 @@ namespace Ndk Resize(m_content->GetSize()); } + void ScrollAreaWidget::EnableScrollbar(bool enable) + { + if (m_isScrollbarEnabled != enable) + { + m_isScrollbarEnabled = enable; + + bool isVisible = IsScrollbarVisible(); + m_scrollbarEntity->Enable(isVisible); + m_scrollbarBackgroundEntity->Enable(isVisible); + } + } + void ScrollAreaWidget::ScrollToRatio(float ratio) { m_scrollRatio = Nz::Clamp(ratio, 0.f, 1.f); @@ -75,13 +88,16 @@ namespace Ndk if (contentHeight > areaHeight) { - m_isScrollBarVisible = true; + m_hasScrollbar = true; Nz::Vector2f contentSize(GetWidth() - scrollBarBackgroundWidth, contentHeight); m_content->Resize(contentSize); - m_scrollbarEntity->Enable(); - m_scrollbarBackgroundEntity->Enable(); + if (m_isScrollbarEnabled) + { + m_scrollbarEntity->Enable(); + m_scrollbarBackgroundEntity->Enable(); + } float scrollBarHeight = std::max(std::floor(areaHeight * (areaHeight / contentHeight)), 20.f); @@ -95,7 +111,7 @@ namespace Ndk } else { - m_isScrollBarVisible = false; + m_hasScrollbar = false; m_content->Resize(GetSize()); @@ -119,7 +135,7 @@ namespace Ndk auto& scrollbarNode = m_scrollbarEntity->GetComponent(); - m_grabbedDelta.Set(x, y - scrollbarNode.GetPosition(Nz::CoordSys_Local).y); + m_grabbedDelta.Set(x, int(y - scrollbarNode.GetPosition(Nz::CoordSys_Local).y)); } } @@ -131,7 +147,7 @@ namespace Ndk if (m_scrollbarStatus == ScrollBarStatus::Grabbed) { Nz::Rectf scrollBarRect = GetScrollbarRect(); - UpdateScrollbarStatus((scrollBarRect.Contains(Nz::Vector2f(x, y))) ? ScrollBarStatus::Hovered : ScrollBarStatus::None); + UpdateScrollbarStatus((scrollBarRect.Contains(Nz::Vector2f(float(x), float(y)))) ? ScrollBarStatus::Hovered : ScrollBarStatus::None); } } @@ -154,7 +170,7 @@ namespace Ndk else { Nz::Rectf scrollBarRect = GetScrollbarRect(); - UpdateScrollbarStatus((scrollBarRect.Contains(Nz::Vector2f(x, y))) ? ScrollBarStatus::Hovered : ScrollBarStatus::None); + UpdateScrollbarStatus((scrollBarRect.Contains(Nz::Vector2f(float(x), float(y)))) ? ScrollBarStatus::Hovered : ScrollBarStatus::None); } } From 8b30fafda68f571eaeba1fb29fdcfdd90de644b9 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Sun, 7 Jul 2019 17:21:25 +0200 Subject: [PATCH 40/47] assimp: fix harmful shadow variable and uniform indices naming --- plugins/Assimp/Plugin.cpp | 72 +++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 5295d2f5a..3f1e5200a 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -255,14 +255,14 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) bool animatedMesh = false; if (parameters.animated) { - for (unsigned int i = 0; i < scene->mNumMeshes; ++i) + for (unsigned int meshIdx = 0; meshIdx < scene->mNumMeshes; ++meshIdx) { - aiMesh* currentMesh = scene->mMeshes[i]; + aiMesh* currentMesh = scene->mMeshes[meshIdx]; if (currentMesh->HasBones()) // Inline functions can be safely called { animatedMesh = true; - for (unsigned int j = 0; j < currentMesh->mNumBones; ++j) - joints.insert(currentMesh->mBones[j]->mName.C_Str()); + for (unsigned int boneIdx = 0; boneIdx < currentMesh->mNumBones; ++boneIdx) + joints.insert(currentMesh->mBones[boneIdx]->mName.C_Str()); } } } @@ -284,9 +284,9 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) // aiMaterial index in scene => Material index and data in Mesh std::unordered_map> materials; - for (unsigned int i = 0; i < scene->mNumMeshes; ++i) + for (unsigned int meshIdx = 0; meshIdx < scene->mNumMeshes; ++meshIdx) { - aiMesh* iMesh = scene->mMeshes[i]; + aiMesh* iMesh = scene->mMeshes[meshIdx]; if (iMesh->HasBones()) { // For now, process only skeletal meshes @@ -303,9 +303,9 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); IndexIterator index = indexMapper.begin(); - for (unsigned int j = 0; j < iMesh->mNumFaces; ++j) + for (unsigned int faceIdx = 0; faceIdx < iMesh->mNumFaces; ++faceIdx) { - aiFace& face = iMesh->mFaces[j]; + aiFace& face = iMesh->mFaces[faceIdx]; if (face.mNumIndices != 3) NazaraWarning("Assimp plugin: This face is not a triangle!"); @@ -324,30 +324,30 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) BufferMapper vertexMapper(vertexBuffer, BufferAccess_ReadWrite); SkeletalMeshVertex* vertices = static_cast(vertexMapper.GetPointer()); - for (std::size_t i = 0; i < vertexCount; ++i) + for (std::size_t vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) { - aiVector3D normal = iMesh->mNormals[i]; - aiVector3D position = iMesh->mVertices[i]; - aiVector3D tangent = iMesh->mTangents[i]; - aiVector3D uv = iMesh->mTextureCoords[0][i]; + aiVector3D normal = iMesh->mNormals[vertexIdx]; + aiVector3D position = iMesh->mVertices[vertexIdx]; + aiVector3D tangent = iMesh->mTangents[vertexIdx]; + aiVector3D uv = iMesh->mTextureCoords[0][vertexIdx]; - vertices[i].weightCount = 0; - vertices[i].normal = normalTangentMatrix.Transform({ normal.x, normal.y, normal.z }, 0.f); - vertices[i].position = parameters.matrix * Vector3f(position.x, position.y, position.z); - vertices[i].tangent = normalTangentMatrix.Transform({ tangent.x, tangent.y, tangent.z }, 0.f); - vertices[i].uv = parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale; + vertices[vertexIdx].weightCount = 0; + vertices[vertexIdx].normal = normalTangentMatrix.Transform({ normal.x, normal.y, normal.z }, 0.f); + vertices[vertexIdx].position = parameters.matrix * Vector3f(position.x, position.y, position.z); + vertices[vertexIdx].tangent = normalTangentMatrix.Transform({ tangent.x, tangent.y, tangent.z }, 0.f); + vertices[vertexIdx].uv = parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale; } - for (unsigned int i = 0; i < iMesh->mNumBones; ++i) + for (unsigned int boneIdx = 0; boneIdx < iMesh->mNumBones; ++boneIdx) { - aiBone* bone = iMesh->mBones[i]; - for (unsigned int j = 0; j < bone->mNumWeights; ++j) + aiBone* bone = iMesh->mBones[boneIdx]; + for (unsigned int weightIdx = 0; weightIdx < bone->mNumWeights; ++weightIdx) { - aiVertexWeight& vertexWeight = bone->mWeights[j]; + aiVertexWeight& vertexWeight = bone->mWeights[weightIdx]; SkeletalMeshVertex& vertex = vertices[vertexWeight.mVertexId]; std::size_t weightIndex = vertex.weightCount++; - vertex.jointIndexes[weightIndex] = i; + vertex.jointIndexes[weightIndex] = boneIdx; vertex.weights[weightIndex] = vertexWeight.mWeight; } } @@ -445,9 +445,9 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) // aiMaterial index in scene => Material index and data in Mesh std::unordered_map> materials; - for (unsigned int i = 0; i < scene->mNumMeshes; ++i) + for (unsigned int meshIdx = 0; meshIdx < scene->mNumMeshes; ++meshIdx) { - aiMesh* iMesh = scene->mMeshes[i]; + aiMesh* iMesh = scene->mMeshes[meshIdx]; if (!iMesh->HasBones()) // Don't process skeletal meshs { unsigned int indexCount = iMesh->mNumFaces * 3; @@ -461,9 +461,9 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); IndexIterator index = indexMapper.begin(); - for (unsigned int j = 0; j < iMesh->mNumFaces; ++j) + for (unsigned int faceIdx = 0; faceIdx < iMesh->mNumFaces; ++faceIdx) { - aiFace& face = iMesh->mFaces[j]; + aiFace& face = iMesh->mFaces[faceIdx]; if (face.mNumIndices != 3) NazaraWarning("Assimp plugin: This face is not a triangle!"); @@ -485,17 +485,17 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) VertexMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); auto posPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); - for (unsigned int j = 0; j < vertexCount; ++j) + for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) { - aiVector3D position = iMesh->mVertices[j]; + aiVector3D position = iMesh->mVertices[vertexIdx]; *posPtr++ = parameters.matrix * Vector3f(position.x, position.y, position.z); } if (auto normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal)) { - for (unsigned int j = 0; j < vertexCount; ++j) + for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) { - aiVector3D normal = iMesh->mNormals[j]; + aiVector3D normal = iMesh->mNormals[vertexIdx]; *normalPtr++ = normalTangentMatrix.Transform({normal.x, normal.y, normal.z}, 0.f); } } @@ -505,9 +505,9 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) { if (iMesh->HasTangentsAndBitangents()) { - for (unsigned int j = 0; j < vertexCount; ++j) + for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) { - aiVector3D tangent = iMesh->mTangents[j]; + aiVector3D tangent = iMesh->mTangents[vertexIdx]; *tangentPtr++ = normalTangentMatrix.Transform({tangent.x, tangent.y, tangent.z}, 0.f); } } @@ -519,15 +519,15 @@ MeshRef LoadMesh(Stream& stream, const MeshParams& parameters) { if (iMesh->HasTextureCoords(0)) { - for (unsigned int j = 0; j < vertexCount; ++j) + for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) { - aiVector3D uv = iMesh->mTextureCoords[0][j]; + aiVector3D uv = iMesh->mTextureCoords[0][vertexIdx]; *uvPtr++ = parameters.texCoordOffset + Vector2f(uv.x, uv.y) * parameters.texCoordScale; } } else { - for (unsigned int j = 0; j < vertexCount; ++j) + for (unsigned int vertexIdx = 0; vertexIdx < vertexCount; ++vertexIdx) *uvPtr++ = Vector2f::Zero(); } } From 724adb599a8c89233267eaf82dfe6b7a17c02436 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Sun, 7 Jul 2019 17:24:04 +0200 Subject: [PATCH 41/47] SDK: BaseWidget: silence harmless shadow warnings --- SDK/src/NDK/BaseWidget.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 647f451c6..07f9afa9f 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -197,9 +197,9 @@ namespace Ndk newEntity->Enable(m_visible); m_entities.emplace_back(); - WidgetEntity& widgetEntity = m_entities.back(); - widgetEntity.handle = newEntity; - widgetEntity.onDisabledSlot.Connect(newEntity->OnEntityDisabled, [this](Entity* entity) + WidgetEntity& newWidgetEntity = m_entities.back(); + newWidgetEntity.handle = newEntity; + newWidgetEntity.onDisabledSlot.Connect(newEntity->OnEntityDisabled, [this](Entity* entity) { auto it = std::find_if(m_entities.begin(), m_entities.end(), [&](const WidgetEntity& widgetEntity) { return widgetEntity.handle == entity; }); NazaraAssert(it != m_entities.end(), "Entity does not belong to this widget"); @@ -207,7 +207,7 @@ namespace Ndk it->isEnabled = false; }); - widgetEntity.onEnabledSlot.Connect(newEntity->OnEntityEnabled, [this](Entity* entity) + newWidgetEntity.onEnabledSlot.Connect(newEntity->OnEntityEnabled, [this](Entity* entity) { auto it = std::find_if(m_entities.begin(), m_entities.end(), [&](const WidgetEntity& widgetEntity) { return widgetEntity.handle == entity; }); NazaraAssert(it != m_entities.end(), "Entity does not belong to this widget"); From e29f2f7a9203e8dce936b69325ede0231f93851a Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Sun, 7 Jul 2019 17:24:29 +0200 Subject: [PATCH 42/47] SDK: TextAreaWidget: silence harmless shadow warnings --- SDK/src/NDK/Widgets/TextAreaWidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 3ab119a0a..5f331f878 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -582,9 +582,9 @@ namespace Ndk }; // Move text so that cursor is always visible - const auto* glyph = GetGlyph(m_cursorPositionEnd, nullptr); - float glyphPos = (glyph) ? glyph->bounds.x : 0.f; - float glyphWidth = (glyph) ? glyph->bounds.width : 0.f; + const auto* lastGlyph = GetGlyph(m_cursorPositionEnd, nullptr); + float glyphPos = (lastGlyph) ? lastGlyph->bounds.x : 0.f; + float glyphWidth = (lastGlyph) ? lastGlyph->bounds.width : 0.f; auto& node = m_textEntity->GetComponent(); float textPosition = node.GetPosition(Nz::CoordSys_Local).x - paddingWidth; From 6b63679c73d1f64ab4737eeb3c0558fb56672a2d Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 9 Jul 2019 19:19:18 +0200 Subject: [PATCH 43/47] Canvas: Add OnUnhandledKeyPressed|`Released --- SDK/include/NDK/Canvas.hpp | 3 + SDK/src/NDK/Canvas.cpp | 8 +- SDK/src/NDK/Widgets/TextAreaWidget.cpp | 120 ++++++++++++------------- 3 files changed, 68 insertions(+), 63 deletions(-) diff --git a/SDK/include/NDK/Canvas.hpp b/SDK/include/NDK/Canvas.hpp index 1b0fbda4f..26cc36cbd 100644 --- a/SDK/include/NDK/Canvas.hpp +++ b/SDK/include/NDK/Canvas.hpp @@ -31,6 +31,9 @@ namespace Ndk Canvas& operator=(const Canvas&) = delete; Canvas& operator=(Canvas&&) = delete; + NazaraSignal(OnUnhandledKeyPressed, const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& /*event*/); + NazaraSignal(OnUnhandledKeyReleased, const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& /*event*/); + protected: inline void ClearKeyboardOwner(std::size_t canvasIndex); diff --git a/SDK/src/NDK/Canvas.cpp b/SDK/src/NDK/Canvas.cpp index aced59e4e..f6d27ad15 100644 --- a/SDK/src/NDK/Canvas.cpp +++ b/SDK/src/NDK/Canvas.cpp @@ -150,7 +150,7 @@ namespace Ndk } } - void Canvas::OnEventKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event) + void Canvas::OnEventKeyPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event) { if (m_keyboardOwner != InvalidCanvasIndex) { @@ -204,12 +204,16 @@ namespace Ndk } } } + + OnUnhandledKeyPressed(eventHandler, event); } - void Canvas::OnEventKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event) + void Canvas::OnEventKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event) { if (m_keyboardOwner != InvalidCanvasIndex) m_widgetEntries[m_keyboardOwner].widget->OnKeyReleased(event); + + OnUnhandledKeyReleased(eventHandler, event); } void Canvas::OnEventTextEntered(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::TextEvent& event) diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 3ab119a0a..e823e54e8 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -243,6 +243,39 @@ namespace Ndk { switch (key.code) { + case Nz::Keyboard::Backspace: + { + bool ignoreDefaultAction = false; + OnTextAreaKeyBackspace(this, &ignoreDefaultAction); + + std::size_t cursorGlyphBegin = GetGlyphIndex(m_cursorPositionBegin); + std::size_t cursorGlyphEnd = GetGlyphIndex(m_cursorPositionEnd); + + if (ignoreDefaultAction || cursorGlyphEnd == 0) + return true; + + // When a text is selected, delete key does the same as delete and leave the character behind it + if (HasSelection()) + EraseSelection(); + else + { + Nz::String newText; + + if (cursorGlyphBegin > 1) + newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyphBegin - 1) - 1)); + + if (cursorGlyphEnd < m_text.GetLength()) + newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyphEnd))); + + // Move cursor before setting text (to prevent SetText to move our cursor) + MoveCursor(-1); + + SetText(newText); + } + + return true; + } + case Nz::Keyboard::Delete: { if (HasSelection()) @@ -335,6 +368,24 @@ namespace Ndk return true; } + case Nz::Keyboard::Return: + { + bool ignoreDefaultAction = false; + OnTextAreaKeyReturn(this, &ignoreDefaultAction); + + if (ignoreDefaultAction) + return true; + + if (!m_multiLineEnabled) + break; + + if (HasSelection()) + EraseSelection(); + + Write(Nz::String('\n')); + return true;; + } + case Nz::Keyboard::Right: { bool ignoreDefaultAction = false; @@ -442,8 +493,10 @@ namespace Ndk } default: - return false; + break; } + + return false; } void TextAreaWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/) @@ -494,68 +547,13 @@ namespace Ndk if (m_readOnly) return; - switch (character) - { - case '\b': - { - bool ignoreDefaultAction = false; - OnTextAreaKeyBackspace(this, &ignoreDefaultAction); + if (Nz::Unicode::GetCategory(character) == Nz::Unicode::Category_Other_Control || (m_characterFilter && !m_characterFilter(character))) + return; - std::size_t cursorGlyphBegin = GetGlyphIndex(m_cursorPositionBegin); - std::size_t cursorGlyphEnd = GetGlyphIndex(m_cursorPositionEnd); + if (HasSelection()) + EraseSelection(); - if (ignoreDefaultAction || cursorGlyphEnd == 0) - break; - - // When a text is selected, delete key does the same as delete and leave the character behind it - if (HasSelection()) - EraseSelection(); - else - { - Nz::String newText; - - if (cursorGlyphBegin > 1) - newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyphBegin - 1) - 1)); - - if (cursorGlyphEnd < m_text.GetLength()) - newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyphEnd))); - - // Move cursor before setting text (to prevent SetText to move our cursor) - MoveCursor(-1); - - SetText(newText); - } - break; - } - - case '\r': - case '\n': - { - bool ignoreDefaultAction = false; - OnTextAreaKeyReturn(this, &ignoreDefaultAction); - - if (ignoreDefaultAction || !m_multiLineEnabled) - break; - - if (HasSelection()) - EraseSelection(); - - Write(Nz::String('\n')); - break; - } - - default: - { - if (Nz::Unicode::GetCategory(character) == Nz::Unicode::Category_Other_Control || (m_characterFilter && !m_characterFilter(character))) - break; - - if (HasSelection()) - EraseSelection(); - - Write(Nz::String::Unicode(character)); - break; - } - } + Write(Nz::String::Unicode(character)); } void TextAreaWidget::RefreshCursor() From 71ca599869ae499bcd4e03d6cc46100249ed6ba5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 9 Jul 2019 19:19:35 +0200 Subject: [PATCH 44/47] SDK/Console: Fix history lines handling --- SDK/src/NDK/Console.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 964bb6b9c..abd333bd3 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -38,7 +38,8 @@ namespace Ndk BaseWidget(parent), m_historyPosition(0), m_defaultFont(Nz::Font::GetDefault()), - m_characterSize(24) + m_characterSize(24), + m_maxHistoryLines(200) { // History m_history = Add(); @@ -107,6 +108,9 @@ namespace Ndk */ void Console::AddLine(const Nz::String& text, const Nz::Color& color) { + if (m_historyLines.size() >= m_maxHistoryLines) + m_historyLines.erase(m_historyLines.begin()); + m_historyLines.emplace_back(Line{ color, text }); m_history->AppendText(text + '\n'); m_history->Resize(m_history->GetPreferredSize()); @@ -183,10 +187,12 @@ namespace Ndk /*! * \brief Performs this action when an input is added to the console */ - void Console::ExecuteInput(const TextAreaWidget* textArea, bool* /*ignoreDefaultAction*/) + void Console::ExecuteInput(const TextAreaWidget* textArea, bool* ignoreDefaultAction) { NazaraAssert(textArea == m_input, "Unexpected signal from an other text area"); + *ignoreDefaultAction = true; + Nz::String input = m_input->GetText(); Nz::String inputCmd = input.SubString(s_inputPrefixSize); m_input->SetText(s_inputPrefix); @@ -212,11 +218,8 @@ namespace Ndk unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight; float historyHeight = size.y - lineHeight; - m_maxHistoryLines = static_cast(std::ceil(historyHeight / lineHeight)); - float diff = historyHeight - m_maxHistoryLines * lineHeight; - - m_historyArea->SetPosition(origin.x, origin.y + diff); - m_historyArea->Resize({ size.x, historyHeight - diff - 4.f }); + m_historyArea->SetPosition(origin.x, origin.y); + m_historyArea->Resize({ size.x, historyHeight - 4.f }); m_input->Resize({size.x, size.y - historyHeight}); m_input->SetPosition(origin.x, origin.y + historyHeight); From 161dc5d6c294290e39e00e903e276d1358ebcb62 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 12 Jul 2019 21:17:25 +0200 Subject: [PATCH 45/47] Update ScrollAreaWidget.cpp --- SDK/src/NDK/Widgets/ScrollAreaWidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp b/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp index b7ec0d020..434071f02 100644 --- a/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp @@ -26,7 +26,7 @@ namespace Ndk m_scrollbarBackgroundSprite = Nz::Sprite::New(); m_scrollbarBackgroundSprite->SetColor(Nz::Color(62, 62, 62)); - m_scrollbarBackgroundSprite->SetMaterial("Basic2D"); + m_scrollbarBackgroundSprite->SetMaterial(Nz::Material::New("Basic2D")); m_scrollbarBackgroundEntity = CreateEntity(); m_scrollbarBackgroundEntity->AddComponent().SetParent(this); @@ -34,7 +34,7 @@ namespace Ndk m_scrollbarSprite = Nz::Sprite::New(); m_scrollbarSprite->SetColor(Nz::Color(104, 104, 104)); - m_scrollbarSprite->SetMaterial("Basic2D"); + m_scrollbarSprite->SetMaterial(Nz::Material::New("Basic2D")); m_scrollbarEntity = CreateEntity(); m_scrollbarEntity->AddComponent().SetParent(this); From 9a8ccee04125317806d1f57c92a69634ed4d87f4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 13 Jul 2019 20:12:13 +0200 Subject: [PATCH 46/47] Update ScrollAreaWidget.cpp --- SDK/src/NDK/Widgets/ScrollAreaWidget.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp b/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp index 434071f02..0d7c1f934 100644 --- a/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/ScrollAreaWidget.cpp @@ -26,7 +26,6 @@ namespace Ndk m_scrollbarBackgroundSprite = Nz::Sprite::New(); m_scrollbarBackgroundSprite->SetColor(Nz::Color(62, 62, 62)); - m_scrollbarBackgroundSprite->SetMaterial(Nz::Material::New("Basic2D")); m_scrollbarBackgroundEntity = CreateEntity(); m_scrollbarBackgroundEntity->AddComponent().SetParent(this); @@ -34,7 +33,6 @@ namespace Ndk m_scrollbarSprite = Nz::Sprite::New(); m_scrollbarSprite->SetColor(Nz::Color(104, 104, 104)); - m_scrollbarSprite->SetMaterial(Nz::Material::New("Basic2D")); m_scrollbarEntity = CreateEntity(); m_scrollbarEntity->AddComponent().SetParent(this); From 6d417c6e54d5fe107a5d9fe09af86742b8efb34c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 13 Jul 2019 23:52:31 +0200 Subject: [PATCH 47/47] SDK/BaseWidget: Fix entity activation of disabled widgets --- SDK/src/NDK/BaseWidget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SDK/src/NDK/BaseWidget.cpp b/SDK/src/NDK/BaseWidget.cpp index 07f9afa9f..be7049938 100644 --- a/SDK/src/NDK/BaseWidget.cpp +++ b/SDK/src/NDK/BaseWidget.cpp @@ -212,6 +212,9 @@ namespace Ndk auto it = std::find_if(m_entities.begin(), m_entities.end(), [&](const WidgetEntity& widgetEntity) { return widgetEntity.handle == entity; }); NazaraAssert(it != m_entities.end(), "Entity does not belong to this widget"); + if (!IsVisible()) + entity->Disable(); // Next line will override isEnabled status + it->isEnabled = true; });