Merge branch 'master' into vulkan

This commit is contained in:
Lynix
2017-08-20 21:35:51 +02:00
57 changed files with 904 additions and 197 deletions

View File

@@ -44,13 +44,13 @@ namespace Ndk
void UnregisterWidget(std::size_t index);
private:
void OnMouseButtonPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event);
void OnMouseButtonRelease(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event);
void OnMouseMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseMoveEvent& event);
void OnMouseLeft(const Nz::EventHandler* eventHandler);
void OnKeyPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
void OnKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
void OnTextEntered(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::TextEvent& event);
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 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);
struct WidgetBox
{

View File

@@ -20,13 +20,13 @@ namespace Ndk
RegisterToCanvas();
// Connect to every meaningful event
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, this, &Canvas::OnKeyPressed);
m_keyReleasedSlot.Connect(eventHandler.OnKeyReleased, this, &Canvas::OnKeyReleased);
m_mouseButtonPressedSlot.Connect(eventHandler.OnMouseButtonPressed, this, &Canvas::OnMouseButtonPressed);
m_mouseButtonReleasedSlot.Connect(eventHandler.OnMouseButtonReleased, this, &Canvas::OnMouseButtonRelease);
m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, this, &Canvas::OnMouseMoved);
m_mouseLeftSlot.Connect(eventHandler.OnMouseLeft, this, &Canvas::OnMouseLeft);
m_textEnteredSlot.Connect(eventHandler.OnTextEntered, this, &Canvas::OnTextEntered);
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, this, &Canvas::OnEventKeyPressed);
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_textEnteredSlot.Connect(eventHandler.OnTextEntered, this, &Canvas::OnEventTextEntered);
// Disable padding by default
SetPadding(0.f, 0.f, 0.f, 0.f);

View File

@@ -24,7 +24,7 @@ namespace Ndk
ParticleEmitterComponent(ParticleEmitterComponent&& emitter) = default;
~ParticleEmitterComponent() = default;
void Enable(bool active = true);
inline void Enable(bool active = true);
inline bool IsActive() const;

View File

@@ -6,6 +6,35 @@
namespace Ndk
{
namespace Detail
{
template<bool HasDefaultConstructor>
struct AddComponentIf;
template<>
struct AddComponentIf<true>
{
template<typename T>
static int AddComponent(Nz::LuaState& lua, EntityHandle& handle)
{
T& component = handle->AddComponent<T>();
lua.Push(component.CreateHandle());
return 1;
}
};
template<>
struct AddComponentIf<false>
{
template<typename T>
static int AddComponent(Nz::LuaState& lua, EntityHandle& /*handle*/)
{
lua.Error("Component has no default constructor and cannot be created from Lua yet");
return 0;
}
};
}
/*!
* \brief Binds a component to a name
*
@@ -13,14 +42,15 @@ namespace Ndk
*
* \remark Produces a NazaraAssert if name is empty
*/
template<typename T>
void LuaBinding::BindComponent(const Nz::String& name)
{
NazaraAssert(!name.IsEmpty(), "Component name cannot be empty");
static_assert(std::is_base_of<BaseComponent, T>::value, "ComponentType must inherit BaseComponent");
ComponentBinding binding;
binding.adder = &AddComponentOfType<T>;
binding.adder = &Detail::AddComponentIf<std::is_default_constructible<T>::value>::template AddComponent<T>;
binding.getter = &PushComponentOfType<T>;
binding.index = T::componentIndex;
binding.name = name;
@@ -32,21 +62,9 @@ namespace Ndk
m_componentBindingByName[name] = T::componentIndex;
}
template<typename T>
int LuaBinding::AddComponentOfType(Nz::LuaState& lua, EntityHandle& handle)
{
static_assert(std::is_base_of<BaseComponent, T>::value, "ComponentType must inherit BaseComponent");
T& component = handle->AddComponent<T>();
lua.Push(component.CreateHandle());
return 1;
}
template<typename T>
int LuaBinding::PushComponentOfType(Nz::LuaState& lua, BaseComponent& component)
{
static_assert(std::is_base_of<BaseComponent, T>::value, "ComponentType must inherit BaseComponent");
T& rightComponent = static_cast<T&>(component);
lua.Push(rightComponent.CreateHandle());
return 1;

View File

@@ -9,5 +9,7 @@ namespace Ndk
inline void ButtonWidget::UpdateText(const Nz::AbstractTextDrawer& drawer)
{
m_textSprite->Update(drawer);
Layout();
}
}

View File

@@ -32,7 +32,8 @@ namespace Ndk
inline void EnableMultiline(bool enable = true);
inline std::size_t GetCursorPosition() const;
inline const Nz::Vector2ui& GetCursorPosition() const;
inline std::size_t GetGlyphUnderCursor() const;
inline std::size_t GetLineCount() const;
inline const Nz::String& GetText() const;
inline const Nz::Color& GetTextColor() const;
@@ -43,10 +44,12 @@ namespace Ndk
inline bool IsReadOnly() const;
inline void MoveCursor(int offset);
inline void MoveCursor(const Nz::Vector2i& offset);
void ResizeToContent() override;
inline void SetCursorPosition(std::size_t cursorPosition);
inline void SetCursorPosition(std::size_t glyphIndex);
inline void SetCursorPosition(Nz::Vector2ui cursorPosition);
inline void SetReadOnly(bool readOnly = true);
inline void SetText(const Nz::String& text);
inline void SetTextColor(const Nz::Color& text);
@@ -82,7 +85,8 @@ namespace Ndk
Nz::SimpleTextDrawer m_drawer;
Nz::SpriteRef m_cursorSprite;
Nz::TextSpriteRef m_textSprite;
std::size_t m_cursorPosition;
Nz::Vector2ui m_cursorPosition;
std::size_t m_cursorGlyph;
bool m_multiLineEnabled;
bool m_readOnly;
};

View File

@@ -20,11 +20,16 @@ namespace Ndk
m_multiLineEnabled = enable;
}
inline std::size_t TextAreaWidget::GetCursorPosition() const
inline const Nz::Vector2ui& TextAreaWidget::GetCursorPosition() const
{
return m_cursorPosition;
}
inline std::size_t Ndk::TextAreaWidget::GetGlyphUnderCursor() const
{
return m_cursorGlyph;
}
inline std::size_t TextAreaWidget::GetLineCount() const
{
return m_drawer.GetLineCount();
@@ -53,22 +58,84 @@ namespace Ndk
inline void TextAreaWidget::MoveCursor(int offset)
{
if (offset >= 0)
SetCursorPosition(m_cursorPosition += static_cast<std::size_t>(offset));
SetCursorPosition(m_cursorGlyph + static_cast<std::size_t>(offset));
else
{
std::size_t nOffset = static_cast<std::size_t>(-offset);
if (nOffset >= m_cursorPosition)
if (nOffset >= m_cursorGlyph)
SetCursorPosition(0);
else
SetCursorPosition(m_cursorPosition - nOffset);
SetCursorPosition(m_cursorGlyph - nOffset);
}
}
inline void TextAreaWidget::SetCursorPosition(std::size_t cursorPosition)
inline void TextAreaWidget::MoveCursor(const Nz::Vector2i& offset)
{
OnTextAreaCursorMove(this, &cursorPosition);
auto BoundOffset = [] (unsigned int cursorPosition, int offset) -> unsigned int
{
if (offset >= 0)
return cursorPosition + offset;
else
{
unsigned int nOffset = static_cast<unsigned int>(-offset);
if (nOffset >= cursorPosition)
return 0;
else
return cursorPosition - nOffset;
}
};
m_cursorPosition = std::min(cursorPosition, m_drawer.GetGlyphCount());
Nz::Vector2ui cursorPosition = m_cursorPosition;
cursorPosition.x = BoundOffset(static_cast<unsigned int>(cursorPosition.x), offset.x);
cursorPosition.y = BoundOffset(static_cast<unsigned int>(cursorPosition.y), offset.y);
SetCursorPosition(cursorPosition);
}
inline void TextAreaWidget::SetCursorPosition(std::size_t glyphIndex)
{
OnTextAreaCursorMove(this, &glyphIndex);
m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount());
std::size_t lineCount = m_drawer.GetLineCount();
std::size_t line = 0U;
for (std::size_t i = line + 1; i < lineCount; ++i)
{
if (m_drawer.GetLine(i).glyphIndex > m_cursorGlyph)
break;
line = i;
}
const auto& lineInfo = m_drawer.GetLine(line);
m_cursorPosition.y = line;
m_cursorPosition.x = m_cursorGlyph - lineInfo.glyphIndex;
RefreshCursor();
}
inline void TextAreaWidget::SetCursorPosition(Nz::Vector2ui cursorPosition)
{
std::size_t lineCount = m_drawer.GetLineCount();
if (cursorPosition.y >= lineCount)
cursorPosition.y = static_cast<unsigned int>(lineCount - 1);
m_cursorPosition = cursorPosition;
const auto& lineInfo = m_drawer.GetLine(cursorPosition.y);
if (cursorPosition.y + 1 < lineCount)
{
const auto& nextLineInfo = m_drawer.GetLine(cursorPosition.y + 1);
cursorPosition.x = std::min(cursorPosition.x, static_cast<unsigned int>(nextLineInfo.glyphIndex - lineInfo.glyphIndex - 1));
}
std::size_t glyphIndex = lineInfo.glyphIndex + cursorPosition.x;
OnTextAreaCursorMove(this, &glyphIndex);
m_cursorGlyph = std::min(glyphIndex, m_drawer.GetGlyphCount());
RefreshCursor();
}

View File

@@ -11,6 +11,20 @@
namespace Ndk
{
/*!
* \ingroup NDK
* \class Ndk::BaseWidget
* \brief Abstract class serving as a base class for all widgets
*/
/*!
* \brief Constructs a BaseWidget object using another widget as its parent
*
* \param parent Parent widget, must be valid and attached to a canvas
*
* Constructs a BaseWidget object using another widget as a base.
* This will also register the widget to the canvas owning the top-most widget.
*/
BaseWidget::BaseWidget(BaseWidget* parent) :
BaseWidget()
{
@@ -24,11 +38,19 @@ namespace Ndk
RegisterToCanvas();
}
/*!
* \brief Frees the widget, unregistering it from its canvas
*/
BaseWidget::~BaseWidget()
{
UnregisterFromCanvas();
}
/*!
* \brief Destroy the widget, deleting it in the process.
*
* Calling this function immediately destroys the widget, freeing its memory.
*/
void BaseWidget::Destroy()
{
NazaraAssert(this != m_canvas, "Canvas cannot be destroyed by calling Destroy()");
@@ -36,6 +58,9 @@ namespace Ndk
m_widgetParent->DestroyChild(this); //< This does delete us
}
/*!
* \brief Enable or disables the widget background.
*/
void BaseWidget::EnableBackground(bool enable)
{
if (m_backgroundEntity.IsValid() == enable)
@@ -142,11 +167,11 @@ namespace Ndk
m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex);
}
void BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key)
void BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& /*key*/)
{
}
void BaseWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& key)
void BaseWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/)
{
}
@@ -154,15 +179,15 @@ namespace Ndk
{
}
void BaseWidget::OnMouseMoved(int x, int y, int deltaX, int deltaY)
void BaseWidget::OnMouseMoved(int /*x*/, int /*y*/, int /*deltaX*/, int /*deltaY*/)
{
}
void BaseWidget::OnMouseButtonPress(int x, int y, Nz::Mouse::Button button)
void BaseWidget::OnMouseButtonPress(int /*x*/, int /*y*/, Nz::Mouse::Button /*button*/)
{
}
void BaseWidget::OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button)
void BaseWidget::OnMouseButtonRelease(int /*x*/, int /*y*/, Nz::Mouse::Button /*button*/)
{
}
@@ -170,11 +195,11 @@ namespace Ndk
{
}
void BaseWidget::OnParentResized(const Nz::Vector2f& newSize)
void BaseWidget::OnParentResized(const Nz::Vector2f& /*newSize*/)
{
}
void BaseWidget::OnTextEntered(char32_t character, bool repeated)
void BaseWidget::OnTextEntered(char32_t /*character*/, bool /*repeated*/)
{
}

View File

@@ -48,7 +48,7 @@ namespace Ndk
m_widgetBoxes.pop_back();
}
void Canvas::OnMouseButtonPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent& event)
void Canvas::OnEventMouseButtonPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent& event)
{
if (m_hoveredWidget)
{
@@ -59,7 +59,7 @@ namespace Ndk
}
}
void Canvas::OnMouseButtonRelease(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent & event)
void Canvas::OnEventMouseButtonRelease(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseButtonEvent & event)
{
if (m_hoveredWidget)
{
@@ -70,7 +70,7 @@ namespace Ndk
}
}
void Canvas::OnMouseMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event)
void Canvas::OnEventMouseMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event)
{
const WidgetBox* bestEntry = nullptr;
float bestEntryArea = std::numeric_limits<float>::infinity();
@@ -120,7 +120,7 @@ namespace Ndk
}
}
void Canvas::OnMouseLeft(const Nz::EventHandler* /*eventHandler*/)
void Canvas::OnEventMouseLeft(const Nz::EventHandler* /*eventHandler*/)
{
if (m_hoveredWidget)
{
@@ -129,19 +129,19 @@ namespace Ndk
}
}
void Canvas::OnKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
void Canvas::OnEventKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
{
if (m_keyboardOwner)
m_keyboardOwner->OnKeyPressed(event);
}
void Canvas::OnKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
void Canvas::OnEventKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
{
if (m_keyboardOwner)
m_keyboardOwner->OnKeyReleased(event);
}
void Canvas::OnTextEntered(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::TextEvent& event)
void Canvas::OnEventTextEntered(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::TextEvent& event)
{
if (m_keyboardOwner)
m_keyboardOwner->OnTextEntered(event.character, event.repeated);

View File

@@ -321,10 +321,11 @@ namespace Ndk
state.SetGlobal("CursorPosition");
// Nz::HashType
static_assert(Nz::HashType_Max + 1 == 9, "Nz::HashType has been updated but change was not reflected to Lua binding");
state.PushTable(0, 9);
static_assert(Nz::HashType_Max + 1 == 10, "Nz::HashType has been updated but change was not reflected to Lua binding");
state.PushTable(0, 10);
{
state.PushField("CRC32", Nz::HashType_CRC32);
state.PushField("CRC64", Nz::HashType_CRC64);
state.PushField("Fletcher16", Nz::HashType_Fletcher16);
state.PushField("MD5", Nz::HashType_MD5);
state.PushField("SHA1", Nz::HashType_SHA1);

View File

@@ -61,7 +61,6 @@ namespace Ndk
m_gradientSprite->SetColor(Nz::Color(128, 128, 128));
}
void ButtonWidget::OnMouseExit()
{
m_gradientSprite->SetColor(Nz::Color(74, 74, 74));

View File

@@ -13,7 +13,8 @@ namespace Ndk
{
TextAreaWidget::TextAreaWidget(BaseWidget* parent) :
BaseWidget(parent),
m_cursorPosition(0U),
m_cursorPosition(0U, 0U),
m_cursorGlyph(0),
m_multiLineEnabled(false),
m_readOnly(false)
{
@@ -81,7 +82,7 @@ namespace Ndk
void TextAreaWidget::Write(const Nz::String& text)
{
if (m_cursorPosition >= m_drawer.GetGlyphCount())
if (m_cursorGlyph >= m_drawer.GetGlyphCount())
{
AppendText(text);
SetCursorPosition(m_drawer.GetGlyphCount());
@@ -89,10 +90,10 @@ namespace Ndk
else
{
Nz::String currentText = m_drawer.GetText();
currentText.Insert(currentText.GetCharacterPosition(m_cursorPosition), text);
currentText.Insert(currentText.GetCharacterPosition(m_cursorGlyph), text);
SetText(currentText);
SetCursorPosition(m_cursorPosition + text.GetLength());
SetCursorPosition(m_cursorGlyph + text.GetLength());
}
}
@@ -114,11 +115,11 @@ namespace Ndk
const Nz::String& text = m_drawer.GetText();
Nz::String newText;
if (m_cursorPosition > 0)
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorPosition) - 1));
if (m_cursorGlyph > 0)
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorGlyph) - 1));
if (m_cursorPosition < m_drawer.GetGlyphCount())
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorPosition + 1)));
if (m_cursorGlyph < m_drawer.GetGlyphCount())
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorGlyph + 1)));
m_drawer.SetText(newText);
m_textSprite->Update(m_drawer);
@@ -133,7 +134,7 @@ namespace Ndk
if (ignoreDefaultAction)
break;
//TODO
MoveCursor({0, 1});
break;
}
@@ -145,7 +146,7 @@ namespace Ndk
if (ignoreDefaultAction)
break;
MoveCursor(-1);
MoveCursor({-1, 0});
break;
}
@@ -157,7 +158,7 @@ namespace Ndk
if (ignoreDefaultAction)
break;
MoveCursor(1);
MoveCursor({1, 0});
break;
}
@@ -169,7 +170,7 @@ namespace Ndk
if (ignoreDefaultAction)
break;
//TODO
MoveCursor({0, -1});
break;
}
}
@@ -221,13 +222,13 @@ namespace Ndk
const Nz::String& text = m_drawer.GetText();
Nz::String newText;
if (m_cursorPosition > 1)
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorPosition - 1) - 1));
if (m_cursorGlyph > 1)
newText.Append(text.SubString(0, text.GetCharacterPosition(m_cursorGlyph - 1) - 1));
if (m_cursorPosition < m_drawer.GetGlyphCount())
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorPosition)));
if (m_cursorGlyph < m_drawer.GetGlyphCount())
newText.Append(text.SubString(text.GetCharacterPosition(m_cursorGlyph)));
MoveCursor(-1);
MoveCursor({-1, 0});
SetText(newText);
break;
}
@@ -258,25 +259,15 @@ namespace Ndk
void TextAreaWidget::RefreshCursor()
{
std::size_t lineCount = m_drawer.GetLineCount();
std::size_t line = 0U;
for (std::size_t i = line + 1; i < lineCount; ++i)
{
if (m_drawer.GetLine(i).glyphIndex > m_cursorPosition)
break;
line = i;
}
const auto& lineInfo = m_drawer.GetLine(line);
const auto& lineInfo = m_drawer.GetLine(m_cursorPosition.y);
std::size_t glyphCount = m_drawer.GetGlyphCount();
float position;
if (glyphCount > 0 && lineInfo.glyphIndex < m_cursorPosition)
if (glyphCount > 0 && lineInfo.glyphIndex < m_cursorGlyph)
{
const auto& glyph = m_drawer.GetGlyph(std::min(m_cursorPosition, glyphCount - 1));
const auto& glyph = m_drawer.GetGlyph(std::min(m_cursorGlyph, glyphCount - 1));
position = glyph.bounds.x;
if (m_cursorPosition >= glyphCount)
if (m_cursorGlyph >= glyphCount)
position += glyph.bounds.width;
}
else

View File

@@ -119,6 +119,7 @@ namespace Ndk
// This is made to avoid that handle warn uselessly entities before their destruction
m_entities.clear();
m_entityBlocks.clear();
m_freeIdList.clear();
m_waitingEntities.clear();
m_aliveEntities.Clear();