Sdk/Console: Turn console into a widget (WIP)

This commit is contained in:
Lynix 2017-01-15 13:25:12 +01:00
parent c9458eeb17
commit dc439d69a5
7 changed files with 58 additions and 286 deletions

View File

@ -17,6 +17,7 @@
#include <vector> #include <vector>
#ifndef NDK_SERVER #ifndef NDK_SERVER
#include <NDK/Canvas.hpp>
#include <NDK/Console.hpp> #include <NDK/Console.hpp>
#include <Nazara/Core/Log.hpp> #include <Nazara/Core/Log.hpp>
#include <Nazara/Lua/LuaInstance.hpp> #include <Nazara/Lua/LuaInstance.hpp>
@ -83,7 +84,7 @@ namespace Ndk
#ifndef NDK_SERVER #ifndef NDK_SERVER
struct ConsoleOverlay struct ConsoleOverlay
{ {
std::unique_ptr<Console> console; Console* console;
Nz::LuaInstance lua; Nz::LuaInstance lua;
NazaraSlot(Nz::EventHandler, OnEvent, eventSlot); NazaraSlot(Nz::EventHandler, OnEvent, eventSlot);
@ -116,10 +117,11 @@ namespace Ndk
Nz::RenderTarget* renderTarget; Nz::RenderTarget* renderTarget;
std::unique_ptr<Nz::Window> window; std::unique_ptr<Nz::Window> window;
std::unique_ptr<ConsoleOverlay> console; std::unique_ptr<ConsoleOverlay> console;
std::unique_ptr<Canvas> canvas;
std::unique_ptr<FPSCounterOverlay> fpsCounter; std::unique_ptr<FPSCounterOverlay> fpsCounter;
std::unique_ptr<World> overlayWorld; std::unique_ptr<World> overlayWorld;
}; };
void SetupConsole(WindowInfo& info); void SetupConsole(WindowInfo& info);
void SetupFPSCounter(WindowInfo& info); void SetupFPSCounter(WindowInfo& info);
void SetupOverlay(WindowInfo& info); void SetupOverlay(WindowInfo& info);

View File

@ -114,7 +114,6 @@ namespace Ndk
} }
m_overlayFlags |= OverlayFlags_Console; m_overlayFlags |= OverlayFlags_Console;
} }
else else
{ {

View File

@ -15,6 +15,7 @@
#include <Nazara/Utility/Event.hpp> #include <Nazara/Utility/Event.hpp>
#include <Nazara/Utility/Node.hpp> #include <Nazara/Utility/Node.hpp>
#include <Nazara/Utility/SimpleTextDrawer.hpp> #include <Nazara/Utility/SimpleTextDrawer.hpp>
#include <NDK/BaseWidget.hpp>
#include <NDK/EntityOwner.hpp> #include <NDK/EntityOwner.hpp>
namespace Nz namespace Nz
@ -26,13 +27,14 @@ namespace Ndk
{ {
class Console; class Console;
class Entity; class Entity;
class TextAreaWidget;
using ConsoleHandle = Nz::ObjectHandle<Console>; using ConsoleHandle = Nz::ObjectHandle<Console>;
class NDK_API Console : public Nz::Node, public Nz::HandledObject<Console> class NDK_API Console : public BaseWidget, public Nz::HandledObject<Console>
{ {
public: public:
Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance); Console(BaseWidget* parent, Nz::LuaInstance& instance);
Console(const Console& console) = delete; Console(const Console& console) = delete;
Console(Console&& console) = default; Console(Console&& console) = default;
~Console() = default; ~Console() = default;
@ -42,31 +44,22 @@ namespace Ndk
void Clear(); void Clear();
inline unsigned int GetCharacterSize() const; inline unsigned int GetCharacterSize() const;
inline const EntityHandle& GetHistory() const; inline const TextAreaWidget* GetHistory() const;
inline const EntityHandle& GetHistoryBackground() const; inline const TextAreaWidget* GetInput() const;
inline const EntityHandle& GetInput() const;
inline const EntityHandle& GetInputBackground() const;
inline const Nz::Vector2f& GetSize() const;
inline const Nz::FontRef& GetTextFont() const; inline const Nz::FontRef& GetTextFont() const;
inline bool IsVisible() const; void ResizeToContent() override;
void SendCharacter(char32_t character);
void SendEvent(const Nz::WindowEvent& event);
void SetCharacterSize(unsigned int size); void SetCharacterSize(unsigned int size);
void SetSize(const Nz::Vector2f& size);
void SetTextFont(Nz::FontRef font); void SetTextFont(Nz::FontRef font);
void Show(bool show = true);
Console& operator=(const Console& console) = delete; Console& operator=(const Console& console) = delete;
Console& operator=(Console&& console) = default; Console& operator=(Console&& console) = default;
private: private:
void AddLineInternal(const Nz::String& text, const Nz::Color& color = Nz::Color::White); void AddLineInternal(const Nz::String& text, const Nz::Color& color = Nz::Color::White);
void ExecuteInput(); void ExecuteInput();
void Layout(); void Layout() override;
void RefreshHistory(); void RefreshHistory();
struct Line struct Line
@ -78,20 +71,10 @@ namespace Ndk
std::size_t m_historyPosition; std::size_t m_historyPosition;
std::vector<Nz::String> m_commandHistory; std::vector<Nz::String> m_commandHistory;
std::vector<Line> m_historyLines; std::vector<Line> m_historyLines;
EntityOwner m_historyBackground; TextAreaWidget* m_history;
EntityOwner m_history; TextAreaWidget* m_input;
EntityOwner m_input;
EntityOwner m_inputBackground;
Nz::FontRef m_defaultFont; Nz::FontRef m_defaultFont;
Nz::LuaInstance& m_instance; 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_characterSize;
unsigned int m_maxHistoryLines; unsigned int m_maxHistoryLines;
}; };

View File

@ -22,51 +22,21 @@ namespace Ndk
* \return History of the console * \return History of the console
*/ */
inline const EntityHandle& Console::GetHistory() const inline const TextAreaWidget* Console::GetHistory() const
{ {
return m_history; 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 * \brief Gets the entity representing the input of the console
* \return Input of the console * \return Input of the console
*/ */
inline const EntityHandle& Console::GetInput() const inline const TextAreaWidget* Console::GetInput() const
{ {
return m_input; 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 * \brief Gets the font used by the console
* \return A reference to the font currenty used * \return A reference to the font currenty used
@ -76,14 +46,4 @@ namespace Ndk
{ {
return m_defaultFont; 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;
}
} }

View File

@ -147,13 +147,15 @@ namespace Ndk
Nz::Vector2ui windowDimensions; Nz::Vector2ui windowDimensions;
if (info.window->IsValid()) if (info.window->IsValid())
windowDimensions.Set(info.window->GetWidth(), info.window->GetHeight() / 4); windowDimensions.Set(info.window->GetWidth(), info.window->GetHeight());
else else
windowDimensions.MakeZero(); windowDimensions.MakeZero();
overlay->console = std::make_unique<Console>(*info.overlayWorld, Nz::Vector2f(windowDimensions), overlay->lua); overlay->console = info.canvas->Add<Console>(overlay->lua);
Console& consoleRef = *overlay->console; Console& consoleRef = *overlay->console;
consoleRef.SetSize({float(windowDimensions.x), windowDimensions.y / 4.f});
consoleRef.Show(false);
// Redirect logs toward the console // Redirect logs toward the console
overlay->logSlot.Connect(Nz::Log::OnLogWrite, [&consoleRef] (const Nz::String& str) 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 // Setup a few event callback to handle the console
Nz::EventHandler& eventHandler = info.window->GetEventHandler(); 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()) if (consoleRef.IsVisible())
consoleRef.SendEvent(event); consoleRef.SendEvent(event);
}); });*/
overlay->keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& 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<World>(false); //< No default system info.overlayWorld = std::make_unique<World>(false); //< No default system
if (info.window->IsValid())
info.canvas = std::make_unique<Canvas>(info.overlayWorld->CreateHandle(), info.window->GetEventHandler());
RenderSystem& renderSystem = info.overlayWorld->AddSystem<RenderSystem>(); RenderSystem& renderSystem = info.overlayWorld->AddSystem<RenderSystem>();
renderSystem.ChangeRenderTechnique<Nz::ForwardRenderTechnique>(); renderSystem.ChangeRenderTechnique<Nz::ForwardRenderTechnique>();
renderSystem.SetDefaultBackground(nullptr); renderSystem.SetDefaultBackground(nullptr);

View File

@ -7,6 +7,7 @@
#include <Nazara/Lua/LuaInstance.hpp> #include <Nazara/Lua/LuaInstance.hpp>
#include <NDK/Components/GraphicsComponent.hpp> #include <NDK/Components/GraphicsComponent.hpp>
#include <NDK/Components/NodeComponent.hpp> #include <NDK/Components/NodeComponent.hpp>
#include <NDK/Widgets.hpp>
#include <NDK/World.hpp> #include <NDK/World.hpp>
///TODO: For now is unable to display different color in the history, it needs a RichTextDrawer to do so ///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 * \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_historyPosition(0),
m_defaultFont(Nz::Font::GetDefault()), m_defaultFont(Nz::Font::GetDefault()),
m_instance(instance), m_instance(instance),
m_size(size),
m_opened(false),
m_characterSize(24) 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<Ndk::GraphicsComponent>().Attach(m_historyBackgroundSprite, -1);
m_historyBackground->AddComponent<Ndk::NodeComponent>().SetParent(this);
// History // History
m_historyDrawer.SetCharacterSize(m_characterSize); m_history = Add<TextAreaWidget>();
m_historyDrawer.SetColor(Nz::Color(200, 200, 200)); m_history->EnableBackground(true);
m_historyDrawer.SetFont(m_defaultFont); m_history->SetReadOnly(true);
m_history->SetBackgroundColor(Nz::Color(80, 80, 160, 128));
m_historyTextSprite = Nz::TextSprite::New();
m_history = world.CreateEntity();
m_history->Enable(m_opened);
m_history->AddComponent<Ndk::GraphicsComponent>().Attach(m_historyTextSprite);
Ndk::NodeComponent& historyNode = m_history->AddComponent<Ndk::NodeComponent>();
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<Ndk::GraphicsComponent>().Attach(m_inputBackgroundSprite, -1);
m_inputBackground->AddComponent<Ndk::NodeComponent>().SetParent(this);
// Input // Input
m_inputDrawer.SetColor(Nz::Color::Black); m_input = Add<TextAreaWidget>();
m_inputDrawer.SetCharacterSize(m_characterSize); m_input->EnableBackground(true);
m_inputDrawer.SetFont(m_defaultFont); m_input->SetText(s_inputPrefix);
m_inputDrawer.SetText(s_inputPrefix); m_input->SetTextColor(Nz::Color::Black);
m_inputTextSprite = Nz::TextSprite::New();
m_inputTextSprite->Update(m_inputDrawer);
m_input = world.CreateEntity();
m_input->Enable(m_opened);
m_input->AddComponent<Ndk::GraphicsComponent>().Attach(m_inputTextSprite);
Ndk::NodeComponent& inputNode = m_input->AddComponent<Ndk::NodeComponent>();
inputNode.SetParent(this);
Layout();
} }
/*! /*!
@ -123,90 +77,8 @@ namespace Ndk
RefreshHistory(); RefreshHistory();
} }
/*! void Console::ResizeToContent()
* \brief Sends a character to the console
*
* \param character Character that will be added to the console
*/
void Console::SendCharacter(char32_t character)
{ {
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<std::size_t>(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_characterSize = size;
m_historyDrawer.SetCharacterSize(m_characterSize); //m_historyDrawer.SetCharacterSize(m_characterSize);
m_historyTextSprite->Update(m_historyDrawer); //m_historyTextSprite->Update(m_historyDrawer);
m_inputDrawer.SetCharacterSize(m_characterSize); //m_inputDrawer.SetCharacterSize(m_characterSize);
m_inputTextSprite->Update(m_inputDrawer); //m_inputTextSprite->Update(m_inputDrawer);
Layout(); 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 * \brief Sets the text font
* *
@ -253,31 +112,12 @@ namespace Ndk
NazaraAssert(font && font->IsValid(), "Invalid font"); NazaraAssert(font && font->IsValid(), "Invalid font");
m_defaultFont = std::move(font); m_defaultFont = std::move(font);
m_historyDrawer.SetFont(m_defaultFont); //m_historyDrawer.SetFont(m_defaultFont);
m_inputDrawer.SetFont(m_defaultFont); //m_inputDrawer.SetFont(m_defaultFont);
Layout(); 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 * \brief Adds a line to the history of the console
* *
@ -296,7 +136,7 @@ namespace Ndk
void Console::ExecuteInput() void Console::ExecuteInput()
{ {
Nz::String input = m_inputDrawer.GetText(); /*Nz::String input = m_inputDrawer.GetText();
Nz::String inputCmd = input.SubString(s_inputPrefixSize);; Nz::String inputCmd = input.SubString(s_inputPrefixSize);;
m_inputDrawer.SetText(s_inputPrefix); m_inputDrawer.SetText(s_inputPrefix);
@ -310,7 +150,7 @@ namespace Ndk
if (!m_instance.Execute(inputCmd)) if (!m_instance.Execute(inputCmd))
AddLineInternal(m_instance.GetLastError(), Nz::Color::Red); AddLineInternal(m_instance.GetLastError(), Nz::Color::Red);
RefreshHistory(); RefreshHistory();*/
} }
/*! /*!
@ -319,23 +159,18 @@ namespace Ndk
void Console::Layout() void Console::Layout()
{ {
const Nz::Vector2f& size = GetContentSize();
unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight; unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight;
float historyHeight = size.y - lineHeight - 5.f - 2.f;
Ndk::NodeComponent& inputNode = m_input->GetComponent<Ndk::NodeComponent>();
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);
m_maxHistoryLines = static_cast<unsigned int>(std::ceil(historyHeight / lineHeight)); m_maxHistoryLines = static_cast<unsigned int>(std::ceil(historyHeight / lineHeight));
Ndk::NodeComponent& historyNode = m_history->GetComponent<Ndk::NodeComponent>(); m_history->SetSize({size.x, historyHeight});
historyNode.SetPosition(0.f, historyHeight - m_maxHistoryLines * lineHeight); m_history->SetPosition(0.f, historyHeight - m_maxHistoryLines * lineHeight);
Ndk::NodeComponent& inputBackgroundNode = m_inputBackground->GetComponent<Ndk::NodeComponent>(); m_input->SetPosition(0.f, historyHeight + 2.f);
inputBackgroundNode.SetPosition(0.f, historyHeight + 2.f); m_input->SetSize({size.x, size.y - historyHeight});
m_inputBackgroundSprite->SetSize(m_size.x, m_size.y - historyHeight);
} }
/*! /*!
@ -344,7 +179,8 @@ namespace Ndk
void Console::RefreshHistory() void Console::RefreshHistory()
{ {
m_historyDrawer.Clear(); m_history->Clear();
auto it = m_historyLines.end(); auto it = m_historyLines.end();
if (m_historyLines.size() > m_maxHistoryLines) if (m_historyLines.size() > m_maxHistoryLines)
it -= m_maxHistoryLines; it -= m_maxHistoryLines;
@ -355,13 +191,11 @@ namespace Ndk
{ {
if (m_maxHistoryLines - i <= m_historyLines.size() && it != m_historyLines.end()) if (m_maxHistoryLines - i <= m_historyLines.size() && it != m_historyLines.end())
{ {
m_historyDrawer.AppendText(it->text); m_history->AppendText(it->text);
++it; ++it;
} }
m_historyDrawer.AppendText(Nz::String('\n')); m_history->AppendText(Nz::String('\n'));
} }
m_historyTextSprite->Update(m_historyDrawer);
} }
} }

View File

@ -62,23 +62,12 @@ namespace Ndk
console.BindMethod("AddLine", &Console::AddLine, Nz::Color::White); console.BindMethod("AddLine", &Console::AddLine, Nz::Color::White);
console.BindMethod("Clear", &Console::Clear); console.BindMethod("Clear", &Console::Clear);
console.BindMethod("GetCharacterSize", &Console::GetCharacterSize); console.BindMethod("GetCharacterSize", &Console::GetCharacterSize);
console.BindMethod("GetHistory", &Console::GetHistory); //console.BindMethod("GetHistory", &Console::GetHistory);
console.BindMethod("GetHistoryBackground", &Console::GetHistoryBackground); //console.BindMethod("GetInput", &Console::GetInput);
console.BindMethod("GetInput", &Console::GetInput);
console.BindMethod("GetInputBackground", &Console::GetInputBackground);
console.BindMethod("GetSize", &Console::GetSize);
console.BindMethod("GetTextFont", &Console::GetTextFont); 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("SetCharacterSize", &Console::SetCharacterSize);
console.BindMethod("SetSize", &Console::SetSize);
console.BindMethod("SetTextFont", &Console::SetTextFont); console.BindMethod("SetTextFont", &Console::SetTextFont);
console.BindMethod("Show", &Console::Show, true);
} }
#endif #endif