Merge pull request #205 from DigitalPulseSoftware/console-widget
Switch console to widgets
This commit is contained in:
commit
b41637c990
|
|
@ -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)
|
||||
|
|
@ -267,6 +268,13 @@ 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
|
||||
- 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)
|
||||
- Added ScrollAreaWidget
|
||||
- Console has been remade with widgets (allowing to scroll back history, select text, etc.)
|
||||
|
||||
# 0.4:
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <set>
|
||||
|
||||
#ifndef NDK_SERVER
|
||||
#include <NDK/Canvas.hpp>
|
||||
#include <NDK/Console.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Lua/LuaInstance.hpp>
|
||||
|
|
@ -81,7 +82,7 @@ namespace Ndk
|
|||
#ifndef NDK_SERVER
|
||||
struct ConsoleOverlay
|
||||
{
|
||||
std::unique_ptr<Console> console;
|
||||
Console* console;
|
||||
Nz::LuaInstance lua;
|
||||
|
||||
NazaraSlot(Nz::EventHandler, OnEvent, eventSlot);
|
||||
|
|
@ -114,10 +115,11 @@ namespace Ndk
|
|||
Nz::RenderTarget* renderTarget;
|
||||
std::unique_ptr<Nz::Window> window;
|
||||
std::unique_ptr<ConsoleOverlay> console;
|
||||
std::unique_ptr<Canvas> canvas;
|
||||
std::unique_ptr<FPSCounterOverlay> fpsCounter;
|
||||
std::unique_ptr<World> overlayWorld;
|
||||
};
|
||||
|
||||
|
||||
void SetupConsole(WindowInfo& info);
|
||||
void SetupFPSCounter(WindowInfo& info);
|
||||
void SetupOverlay(WindowInfo& info);
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ namespace Ndk
|
|||
}
|
||||
|
||||
m_overlayFlags |= OverlayFlags_Console;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ namespace Ndk
|
|||
friend Canvas;
|
||||
|
||||
public:
|
||||
struct Padding;
|
||||
|
||||
BaseWidget(BaseWidget* parent);
|
||||
BaseWidget(const BaseWidget&) = delete;
|
||||
BaseWidget(BaseWidget&&) = delete;
|
||||
|
|
@ -41,6 +39,7 @@ namespace Ndk
|
|||
inline void CenterVertical();
|
||||
|
||||
void ClearFocus();
|
||||
inline void ClearRenderingRect();
|
||||
|
||||
void Destroy();
|
||||
|
||||
|
|
@ -68,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;
|
||||
|
|
@ -81,6 +82,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);
|
||||
|
|
@ -94,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;
|
||||
|
|
@ -115,6 +119,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);
|
||||
|
|
@ -136,6 +141,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<std::size_t>::max();
|
||||
|
|
@ -147,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;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <NDK/BaseWidget.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <limits>
|
||||
|
||||
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<float>::infinity(), -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity()),
|
||||
m_cursor(Nz::SystemCursor_Default),
|
||||
m_size(50.f, 50.f),
|
||||
m_maximumSize(std::numeric_limits<float>::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<float>::infinity(), -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity()));
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
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());
|
||||
|
|
@ -237,7 +249,7 @@ namespace Ndk
|
|||
{
|
||||
m_preferredSize = preferredSize;
|
||||
|
||||
Resize(m_preferredSize);
|
||||
//Resize(m_preferredSize);
|
||||
}
|
||||
|
||||
inline bool BaseWidget::IsRegisteredToCanvas() const
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <Nazara/Graphics/TextSprite.hpp>
|
||||
#include <Nazara/Utility/Node.hpp>
|
||||
#include <Nazara/Utility/SimpleTextDrawer.hpp>
|
||||
#include <NDK/BaseWidget.hpp>
|
||||
#include <NDK/EntityOwner.hpp>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -25,13 +26,16 @@ namespace Nz
|
|||
namespace Ndk
|
||||
{
|
||||
class Console;
|
||||
class Entity;
|
||||
class ScrollAreaWidget;
|
||||
class TextAreaWidget;
|
||||
|
||||
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:
|
||||
Console(World& world, const Nz::Vector2f& size, Nz::LuaState& state);
|
||||
Console(BaseWidget* parent, Nz::LuaState& state);
|
||||
Console(const Console& console) = delete;
|
||||
Console(Console&& console) = default;
|
||||
~Console() = default;
|
||||
|
|
@ -39,34 +43,23 @@ 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 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 SetCharacterSize(unsigned int size);
|
||||
void SetSize(const Nz::Vector2f& size);
|
||||
void SetFocus();
|
||||
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 RefreshHistory();
|
||||
void ExecuteInput(const TextAreaWidget* textArea, bool* ignoreDefaultAction);
|
||||
void Layout() override;
|
||||
|
||||
struct Line
|
||||
{
|
||||
|
|
@ -77,20 +70,11 @@ namespace Ndk
|
|||
std::size_t m_historyPosition;
|
||||
std::vector<Nz::String> m_commandHistory;
|
||||
std::vector<Line> m_historyLines;
|
||||
EntityOwner m_historyBackground;
|
||||
EntityOwner m_history;
|
||||
EntityOwner m_input;
|
||||
EntityOwner m_inputBackground;
|
||||
ScrollAreaWidget* m_historyArea;
|
||||
TextAreaWidget* m_history;
|
||||
TextAreaWidget* m_input;
|
||||
Nz::FontRef m_defaultFont;
|
||||
Nz::LuaState& m_state;
|
||||
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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,51 +19,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
|
||||
|
|
@ -73,14 +43,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <NDK/Widgets/ImageWidget.hpp>
|
||||
#include <NDK/Widgets/LabelWidget.hpp>
|
||||
#include <NDK/Widgets/ProgressBarWidget.hpp>
|
||||
#include <NDK/Widgets/ScrollAreaWidget.hpp>
|
||||
#include <NDK/Widgets/TextAreaWidget.hpp>
|
||||
|
||||
#endif // NDK_WIDGETS_GLOBAL_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 <NDK/Prerequisites.hpp>
|
||||
#include <NDK/BaseWidget.hpp>
|
||||
#include <Nazara/Graphics/TextSprite.hpp>
|
||||
|
||||
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 <NDK/Widgets/ScrollAreaWidget.inl>
|
||||
|
||||
#endif // NDK_WIDGETS_SCROLLAREAWIDGET_HPP
|
||||
|
|
@ -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 <NDK/Widgets/ScrollAreaWidget.hpp>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -46,7 +46,8 @@ namespace Ndk
|
|||
inline Nz::Vector2ui GetCursorPosition(std::size_t glyphIndex) 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;
|
||||
inline const Nz::Color& GetTextOulineColor() const;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -76,7 +77,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_cursorPositionBegin);
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -87,11 +98,6 @@ namespace Ndk
|
|||
return glyphIndex;
|
||||
}
|
||||
|
||||
inline EchoMode TextAreaWidget::GetEchoMode() const
|
||||
{
|
||||
return m_echoMode;
|
||||
}
|
||||
|
||||
inline const Nz::String& TextAreaWidget::GetText() const
|
||||
{
|
||||
return m_text;
|
||||
|
|
|
|||
|
|
@ -147,16 +147,15 @@ namespace Ndk
|
|||
|
||||
Nz::Vector2ui windowDimensions;
|
||||
if (info.window->IsValid())
|
||||
{
|
||||
windowDimensions = info.window->GetSize();
|
||||
windowDimensions.y /= 4;
|
||||
}
|
||||
else
|
||||
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;
|
||||
consoleRef.Resize({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)
|
||||
|
|
@ -201,22 +200,34 @@ 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
|
@ -238,6 +249,9 @@ namespace Ndk
|
|||
{
|
||||
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(), info.window->GetCursorController().CreateHandle());
|
||||
|
||||
RenderSystem& renderSystem = info.overlayWorld->AddSystem<RenderSystem>();
|
||||
renderSystem.ChangeRenderTechnique<Nz::ForwardRenderTechnique>();
|
||||
renderSystem.SetDefaultBackground(nullptr);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -157,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);
|
||||
|
|
@ -172,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;
|
||||
}
|
||||
|
|
@ -237,6 +279,10 @@ namespace Ndk
|
|||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseWheelMoved(int /*x*/, int /*y*/, float /*delta*/)
|
||||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseExit()
|
||||
{
|
||||
}
|
||||
|
|
@ -290,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;
|
||||
|
|
|
|||
|
|
@ -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<int>(std::round(event.x - hoveredWidget.box.x));
|
||||
int y = static_cast<int>(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)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <Nazara/Platform/Event.hpp>
|
||||
#include <NDK/Components/GraphicsComponent.hpp>
|
||||
#include <NDK/Components/NodeComponent.hpp>
|
||||
#include <NDK/Widgets.hpp>
|
||||
#include <NDK/World.hpp>
|
||||
|
||||
///TODO: For now is unable to display different color in the history, it needs a RichTextDrawer to do so
|
||||
|
|
@ -34,71 +35,63 @@ namespace Ndk
|
|||
* \param instance Lua instance that will interact with the world
|
||||
*/
|
||||
|
||||
Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaState& state) :
|
||||
Console::Console(BaseWidget* parent, Nz::LuaState& state) :
|
||||
BaseWidget(parent),
|
||||
m_historyPosition(0),
|
||||
m_defaultFont(Nz::Font::GetDefault()),
|
||||
m_state(state),
|
||||
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<Ndk::GraphicsComponent>().Attach(m_historyBackgroundSprite, -1);
|
||||
m_historyBackground->AddComponent<Ndk::NodeComponent>().SetParent(this);
|
||||
|
||||
// History
|
||||
m_historyDrawer.SetCharacterSize(m_characterSize);
|
||||
m_historyDrawer.SetColor(Nz::Color(200, 200, 200));
|
||||
m_historyDrawer.SetFont(m_defaultFont);
|
||||
m_history = Add<TextAreaWidget>();
|
||||
m_history->EnableBackground(true);
|
||||
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);
|
||||
m_historyArea = Add<ScrollAreaWidget>(m_history);
|
||||
|
||||
// Input
|
||||
m_inputDrawer.SetColor(Nz::Color::Black);
|
||||
m_inputDrawer.SetCharacterSize(m_characterSize);
|
||||
m_inputDrawer.SetFont(m_defaultFont);
|
||||
m_inputDrawer.SetText(s_inputPrefix);
|
||||
m_input = Add<TextAreaWidget>();
|
||||
m_input->EnableBackground(true);
|
||||
m_input->SetText(s_inputPrefix);
|
||||
m_input->SetTextColor(Nz::Color::Black);
|
||||
|
||||
m_inputTextSprite = Nz::TextSprite::New();
|
||||
m_inputTextSprite->Update(m_inputDrawer);
|
||||
m_input->OnTextAreaKeyReturn.Connect(this, &Console::ExecuteInput);
|
||||
|
||||
m_input = world.CreateEntity();
|
||||
m_input->Enable(m_opened);
|
||||
m_input->AddComponent<Ndk::GraphicsComponent>().Attach(m_inputTextSprite);
|
||||
// Protect input prefix from erasure/selection
|
||||
m_input->SetCursorPosition(s_inputPrefixSize);
|
||||
|
||||
Ndk::NodeComponent& inputNode = m_input->AddComponent<Ndk::NodeComponent>();
|
||||
inputNode.SetParent(this);
|
||||
m_input->OnTextAreaCursorMove.Connect([](const TextAreaWidget* textArea, std::size_t* newCursorPos)
|
||||
{
|
||||
*newCursorPos = std::max(*newCursorPos, s_inputPrefixSize);
|
||||
});
|
||||
|
||||
Layout();
|
||||
m_input->OnTextAreaKeyBackspace.Connect([](const TextAreaWidget* textArea, bool* ignoreDefaultAction)
|
||||
{
|
||||
if (textArea->GetGlyphIndex() <= s_inputPrefixSize)
|
||||
*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]);
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -107,110 +100,37 @@ 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)
|
||||
{
|
||||
AddLineInternal(text, color);
|
||||
RefreshHistory();
|
||||
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);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clears the console
|
||||
*
|
||||
* Clears the console history and input
|
||||
*/
|
||||
|
||||
void Console::Clear()
|
||||
{
|
||||
m_historyLines.clear();
|
||||
RefreshHistory();
|
||||
m_history->Clear();
|
||||
m_history->Resize(m_history->GetPreferredSize());
|
||||
m_historyArea->Resize(m_historyArea->GetSize());
|
||||
m_input->SetText(s_inputPrefix);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sends a character to the console
|
||||
* \brief Clears the console focus
|
||||
*
|
||||
* \param character Character that will be added to the console
|
||||
* Clear console input widget focus (if owned)
|
||||
*/
|
||||
|
||||
void Console::SendCharacter(char32_t character)
|
||||
void Console::ClearFocus()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!m_commandHistory.empty())
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_input->ClearFocus();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -218,30 +138,23 @@ namespace Ndk
|
|||
*
|
||||
* \param size Size of the font
|
||||
*/
|
||||
|
||||
void Console::SetCharacterSize(unsigned int size)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the console size
|
||||
* \brief Give the console input focus
|
||||
*
|
||||
* \param size (Width, Height) of the console
|
||||
*/
|
||||
|
||||
void Console::SetSize(const Nz::Vector2f& size)
|
||||
void Console::SetFocus()
|
||||
{
|
||||
m_size = size;
|
||||
m_historyBackgroundSprite->SetSize(m_size);
|
||||
Layout();
|
||||
m_input->SetFocus();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -251,70 +164,38 @@ namespace Ndk
|
|||
*
|
||||
* \remark Produces a NazaraAssert if font is invalid or null
|
||||
*/
|
||||
|
||||
void Console::SetTextFont(Nz::FontRef font)
|
||||
{
|
||||
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
|
||||
*
|
||||
* \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
|
||||
*/
|
||||
|
||||
void Console::ExecuteInput()
|
||||
void Console::ExecuteInput(const TextAreaWidget* textArea, bool* ignoreDefaultAction)
|
||||
{
|
||||
Nz::String input = m_inputDrawer.GetText();
|
||||
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_inputDrawer.SetText(s_inputPrefix);
|
||||
m_input->SetText(s_inputPrefix);
|
||||
|
||||
if (m_commandHistory.empty() || m_commandHistory.back() != inputCmd)
|
||||
m_commandHistory.push_back(inputCmd);
|
||||
|
||||
m_historyPosition = 0;
|
||||
m_historyPosition = m_commandHistory.size();
|
||||
|
||||
AddLineInternal(input); //< With the input prefix
|
||||
AddLine(input); //< With the input prefix
|
||||
|
||||
if (!m_state.Execute(inputCmd))
|
||||
AddLineInternal(m_state.GetLastError(), Nz::Color::Red);
|
||||
|
||||
RefreshHistory();
|
||||
AddLine(m_state.GetLastError(), Nz::Color::Red);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -323,49 +204,19 @@ namespace Ndk
|
|||
|
||||
void Console::Layout()
|
||||
{
|
||||
Nz::Vector2f origin = Nz::Vector2f(GetPosition());
|
||||
const Nz::Vector2f& size = GetSize();
|
||||
|
||||
unsigned int lineHeight = m_defaultFont->GetSizeInfo(m_characterSize).lineHeight;
|
||||
|
||||
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);
|
||||
float historyHeight = size.y - lineHeight;
|
||||
|
||||
m_maxHistoryLines = static_cast<unsigned int>(std::ceil(historyHeight / lineHeight));
|
||||
float diff = historyHeight - m_maxHistoryLines * lineHeight;
|
||||
|
||||
Ndk::NodeComponent& historyNode = m_history->GetComponent<Ndk::NodeComponent>();
|
||||
historyNode.SetPosition(0.f, historyHeight - m_maxHistoryLines * lineHeight);
|
||||
m_historyArea->SetPosition(origin.x, origin.y + diff);
|
||||
m_historyArea->Resize({ size.x, historyHeight - diff - 4.f });
|
||||
|
||||
Ndk::NodeComponent& inputBackgroundNode = m_inputBackground->GetComponent<Ndk::NodeComponent>();
|
||||
inputBackgroundNode.SetPosition(0.f, historyHeight + 2.f);
|
||||
|
||||
m_inputBackgroundSprite->SetSize(m_size.x, m_size.y - historyHeight);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Refreshes the history of the console
|
||||
*/
|
||||
|
||||
void Console::RefreshHistory()
|
||||
{
|
||||
m_historyDrawer.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_historyDrawer.AppendText(it->text);
|
||||
++it;
|
||||
}
|
||||
|
||||
m_historyDrawer.AppendText(Nz::String('\n'));
|
||||
}
|
||||
|
||||
m_historyTextSprite->Update(m_historyDrawer);
|
||||
m_input->Resize({size.x, size.y - historyHeight});
|
||||
m_input->SetPosition(origin.x, origin.y + historyHeight);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -62,24 +62,14 @@ 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("IsValidHandle", &ConsoleHandle::IsValid);
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <NDK/Widgets/ScrollAreaWidget.hpp>
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <NDK/Components/GraphicsComponent.hpp>
|
||||
#include <NDK/Components/NodeComponent.hpp>
|
||||
|
||||
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<NodeComponent>().SetParent(this);
|
||||
m_scrollbarBackgroundEntity->AddComponent<GraphicsComponent>().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<NodeComponent>().SetParent(this);
|
||||
m_scrollbarEntity->AddComponent<GraphicsComponent>().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<Ndk::NodeComponent>();
|
||||
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<float>::infinity(), -contentPosition, std::numeric_limits<float>::infinity(), widgetHeight));
|
||||
}
|
||||
|
||||
Nz::Rectf ScrollAreaWidget::GetScrollbarRect() const
|
||||
{
|
||||
Nz::Vector2f scrollBarPosition = Nz::Vector2f(m_scrollbarEntity->GetComponent<Ndk::NodeComponent>().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<Ndk::NodeComponent>().SetPosition(contentSize.x, 0.f);
|
||||
m_scrollbarEntity->GetComponent<Ndk::NodeComponent>().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<Ndk::NodeComponent>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,8 +31,10 @@ namespace Ndk
|
|||
|
||||
m_textEntity = CreateEntity();
|
||||
m_textEntity->AddComponent<GraphicsComponent>().Attach(m_textSprite);
|
||||
m_textEntity->AddComponent<NodeComponent>().SetParent(this);
|
||||
m_textEntity->GetComponent<NodeComponent>().SetPosition(5.f, 3.f);
|
||||
|
||||
auto& textNode = m_textEntity->AddComponent<NodeComponent>();
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ namespace Nz
|
|||
struct MouseWheelEvent
|
||||
{
|
||||
float delta;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
// Used by:
|
||||
|
|
|
|||
|
|
@ -712,7 +712,10 @@ namespace Nz
|
|||
{
|
||||
WindowEvent event;
|
||||
event.type = WindowEventType_MouseWheelMoved;
|
||||
event.mouseWheel.delta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wParam))/WHEEL_DELTA;
|
||||
event.mouseWheel.delta = static_cast<float>(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<float>(m_scrolling/WHEEL_DELTA);
|
||||
event.mouseWheel.delta = static_cast<float>(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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue