Fix some minor stuff

This commit is contained in:
Jérôme Leclercq 2020-09-06 17:09:39 +02:00
parent 67b0d70b7c
commit 193deb6c04
10 changed files with 96 additions and 94 deletions

View File

@ -39,7 +39,7 @@ namespace Ndk
void SetGeomOffset(const Nz::Vector2f& geomOffset); void SetGeomOffset(const Nz::Vector2f& geomOffset);
CollisionComponent2D& operator=(Nz::Collider2DRef geom); CollisionComponent2D& operator=(Nz::Collider2DRef geom);
CollisionComponent2D& operator=(CollisionComponent2D&& collision) = default; CollisionComponent2D& operator=(CollisionComponent2D&& collision) = delete;
static ComponentIndex componentIndex; static ComponentIndex componentIndex;

View File

@ -24,8 +24,6 @@ namespace Ndk
LightComponent(const LightComponent& light) = default; LightComponent(const LightComponent& light) = default;
~LightComponent() = default; ~LightComponent() = default;
LightComponent& operator=(const LightComponent& light) = default;
static ComponentIndex componentIndex; static ComponentIndex componentIndex;
}; };
} }

View File

@ -10,34 +10,27 @@
#include <NDK/Prerequisites.hpp> #include <NDK/Prerequisites.hpp>
#include <NDK/BaseWidget.hpp> #include <NDK/BaseWidget.hpp>
#include <NDK/Widgets/Enums.hpp> #include <NDK/Widgets/Enums.hpp>
#include <vector> #include <memory>
namespace Ndk namespace Ndk
{ {
class NDK_API BoxLayout : public BaseWidget class NDK_API BoxLayout : public BaseWidget
{ {
public: public:
inline BoxLayout(BaseWidget* parent, BoxLayoutOrientation orientation); BoxLayout(BaseWidget* parent, BoxLayoutOrientation orientation);
BoxLayout(const BoxLayout&) = delete; BoxLayout(const BoxLayout&) = delete;
BoxLayout(BoxLayout&&) = default; BoxLayout(BoxLayout&&) = delete;
~BoxLayout() = default; ~BoxLayout();
void Layout() override; void Layout() override;
BoxLayout& operator=(const BoxLayout&) = delete; BoxLayout& operator=(const BoxLayout&) = delete;
BoxLayout& operator=(BoxLayout&&) = default; BoxLayout& operator=(BoxLayout&&) = delete;
private: private:
struct ChildInfo struct State;
{
BaseWidget* widget;
bool isConstrained;
float maximumSize;
float minimumSize;
float size;
};
std::vector<ChildInfo> m_childInfos; std::unique_ptr<State> m_state;
BoxLayoutOrientation m_orientation; BoxLayoutOrientation m_orientation;
float m_spacing; float m_spacing;
}; };

View File

@ -6,10 +6,4 @@
namespace Ndk namespace Ndk
{ {
BoxLayout::BoxLayout(BaseWidget* parent, BoxLayoutOrientation orientation) :
BaseWidget(parent),
m_orientation(orientation),
m_spacing(5.f)
{
}
} }

View File

@ -4,25 +4,43 @@
#include <NDK/Widgets/BoxLayout.hpp> #include <NDK/Widgets/BoxLayout.hpp>
#include <Nazara/Core/Log.hpp> #include <Nazara/Core/Log.hpp>
#include <Nazara/Core/MemoryHelper.hpp> #include <Nazara/Core/StackVector.hpp>
#include <kiwi/kiwi.h>
#include <cassert> #include <cassert>
#include <vector>
namespace Ndk namespace Ndk
{ {
struct BoxLayout::State
{
std::vector<kiwi::Variable> sizeVar;
kiwi::Solver solver;
};
BoxLayout::BoxLayout(BaseWidget* parent, BoxLayoutOrientation orientation) :
BaseWidget(parent),
m_orientation(orientation),
m_spacing(5.f)
{
m_state = std::make_unique<State>();
}
BoxLayout::~BoxLayout() = default;
void BoxLayout::Layout() void BoxLayout::Layout()
{ {
std::size_t axis1, axis2; BaseWidget::Layout();
std::size_t axis;
switch (m_orientation) switch (m_orientation)
{ {
case BoxLayoutOrientation_Horizontal: case BoxLayoutOrientation_Horizontal:
axis1 = 0; //< x axis = 0; //< x
axis2 = 1; //< y
break; break;
case BoxLayoutOrientation_Vertical: case BoxLayoutOrientation_Vertical:
axis1 = 1; //< y axis = 1; //< y
axis2 = 0; //< x
break; break;
default: default:
@ -30,7 +48,21 @@ namespace Ndk
break; break;
} }
m_childInfos.clear(); //TODO: Keep solver state when widgets don't change
std::size_t widgetChildCount = GetWidgetChildCount();
if (widgetChildCount == 0)
return;
m_state->solver.reset();
m_state->sizeVar.clear();
m_state->sizeVar.reserve(widgetChildCount);
kiwi::Expression sizeSum;
Nz::Vector2f layoutSize = GetSize();
float availableSpace = layoutSize[axis] - m_spacing * (widgetChildCount - 1);
float perfectSpacePerWidget = availableSpace / widgetChildCount;
// Handle size // Handle size
ForEachWidgetChild([&](BaseWidget* child) ForEachWidgetChild([&](BaseWidget* child)
@ -38,73 +70,55 @@ namespace Ndk
if (!child->IsVisible()) if (!child->IsVisible())
return; return;
m_childInfos.emplace_back(); float maximumSize = child->GetMaximumSize()[axis];
auto& info = m_childInfos.back(); float minimumSize = child->GetMinimumSize()[axis];
info.isConstrained = false;
info.maximumSize = child->GetMaximumSize()[axis1]; m_state->sizeVar.emplace_back();
info.minimumSize = child->GetMinimumSize()[axis1]; auto& sizeVar = m_state->sizeVar.back();
info.size = info.minimumSize;
info.widget = child; m_state->solver.addConstraint({ sizeVar >= minimumSize | kiwi::strength::required });
if (maximumSize < std::numeric_limits<float>::infinity())
m_state->solver.addConstraint({ sizeVar <= maximumSize | kiwi::strength::required });
m_state->solver.addConstraint({ sizeVar == perfectSpacePerWidget | kiwi::strength::medium });
sizeSum = sizeSum + sizeVar;
}); });
Nz::Vector2f layoutSize = GetSize(); kiwi::Variable targetSize("LayoutSize");
m_state->solver.addConstraint(sizeSum <= targetSize | kiwi::strength::strong);
m_state->solver.addEditVariable(targetSize, kiwi::strength::strong);
m_state->solver.suggestValue(targetSize, availableSpace);
m_state->solver.updateVariables();
std::size_t varIndex = 0;
float availableSpace = layoutSize[axis1] - m_spacing * (m_childInfos.size() - 1);
float remainingSize = availableSpace; float remainingSize = availableSpace;
for (auto& info : m_childInfos)
remainingSize -= info.minimumSize;
// Okay this algorithm is FAR from perfect but I couldn't figure a way other than this one ForEachWidgetChild([&](BaseWidget* child)
std::size_t unconstrainedChildCount = m_childInfos.size();
bool hasUnconstrainedChilds = false;
for (std::size_t i = 0; i < m_childInfos.size(); ++i)
{ {
if (remainingSize <= 0.0001f) if (!child->IsVisible())
break; return;
float evenSize = remainingSize / unconstrainedChildCount; Nz::Vector2f newSize = layoutSize;
newSize[axis] = m_state->sizeVar[varIndex].value();
for (auto& info : m_childInfos) child->Resize(newSize);
{ remainingSize -= newSize[axis];
if (info.isConstrained)
continue;
float previousSize = info.size; varIndex++;
});
info.size += evenSize; float spacing = m_spacing + remainingSize / (widgetChildCount - 1);
if (info.size > info.maximumSize)
{
unconstrainedChildCount--;
evenSize += (info.size - info.maximumSize) / unconstrainedChildCount;
info.isConstrained = true;
info.size = info.maximumSize;
}
else
hasUnconstrainedChilds = true;
remainingSize -= info.size - previousSize;
}
if (!hasUnconstrainedChilds)
break;
}
float spacing = m_spacing + remainingSize / (m_childInfos.size() - 1);
for (auto& info : m_childInfos)
{
Nz::Vector2f newSize = info.widget->GetSize();
newSize[axis1] = info.size;
info.widget->Resize(newSize);
}
// Handle position // Handle position
float cursor = 0.f; float cursor = 0.f;
bool first = true; bool first = true;
for (auto& info : m_childInfos) ForEachWidgetChild([&](BaseWidget* child)
{ {
if (first) if (first)
first = false; first = false;
@ -112,11 +126,11 @@ namespace Ndk
cursor += spacing; cursor += spacing;
Nz::Vector2f position = Nz::Vector2f(0.f, 0.f); Nz::Vector2f position = Nz::Vector2f(0.f, 0.f);
position[axis1] = cursor; position[axis] = cursor;
info.widget->SetPosition(position); child->SetPosition(position);
cursor += info.size; cursor += child->GetSize()[axis];
}; });
} }
} }

View File

@ -26,7 +26,7 @@ namespace Nz
{ {
public: public:
AbstractBackground() = default; AbstractBackground() = default;
AbstractBackground(const AbstractBackground&) = default; AbstractBackground(const AbstractBackground&) = delete;
AbstractBackground(AbstractBackground&&) = delete; AbstractBackground(AbstractBackground&&) = delete;
virtual ~AbstractBackground(); virtual ~AbstractBackground();
@ -34,7 +34,7 @@ namespace Nz
virtual BackgroundType GetBackgroundType() const = 0; virtual BackgroundType GetBackgroundType() const = 0;
AbstractBackground& operator=(const AbstractBackground&) = default; AbstractBackground& operator=(const AbstractBackground&) = delete;
AbstractBackground& operator=(AbstractBackground&&) = delete; AbstractBackground& operator=(AbstractBackground&&) = delete;
private: private:

View File

@ -126,7 +126,7 @@ namespace Nz
template<typename T> template<typename T>
void SinCos(std::enable_if_t<std::is_same<T, long double>::value, long double> x, long double* s, long double* c) void SinCos(std::enable_if_t<std::is_same<T, long double>::value, long double> x, long double* s, long double* c)
{ {
::sincosl(x, sin, cos); ::sincosl(x, s, c);
} }
#else #else
// Naive implementation, hopefully optimized by the compiler // Naive implementation, hopefully optimized by the compiler

View File

@ -22,7 +22,7 @@ namespace Nz
AbstractSocket(AbstractSocket&& abstractSocket) noexcept; AbstractSocket(AbstractSocket&& abstractSocket) noexcept;
virtual ~AbstractSocket(); virtual ~AbstractSocket();
void Close(); void Close() noexcept;
void EnableBlocking(bool blocking); void EnableBlocking(bool blocking);
@ -41,7 +41,7 @@ namespace Nz
void SetSendBufferSize(std::size_t size); void SetSendBufferSize(std::size_t size);
AbstractSocket& operator=(const AbstractSocket&) = delete; AbstractSocket& operator=(const AbstractSocket&) = delete;
AbstractSocket& operator=(AbstractSocket&& abstractSocket); AbstractSocket& operator=(AbstractSocket&& abstractSocket) noexcept;
// Signals: // Signals:
NazaraSignal(OnStateChanged, const AbstractSocket* /*socket*/, SocketState /*oldState*/, SocketState /*newState*/); NazaraSignal(OnStateChanged, const AbstractSocket* /*socket*/, SocketState /*oldState*/, SocketState /*newState*/);

View File

@ -46,6 +46,9 @@ namespace Nz
bool SendMultiple(const IpAddress& to, const NetBuffer* buffers, std::size_t bufferCount, std::size_t* sent); bool SendMultiple(const IpAddress& to, const NetBuffer* buffers, std::size_t bufferCount, std::size_t* sent);
bool SendPacket(const IpAddress& to, const NetPacket& packet); bool SendPacket(const IpAddress& to, const NetPacket& packet);
UdpSocket& operator=(const UdpSocket& udpSocket) = delete;
UdpSocket& operator=(UdpSocket && udpSocket) noexcept = default;
private: private:
void OnClose() override; void OnClose() override;
void OnOpened() override; void OnOpened() override;

View File

@ -71,7 +71,7 @@ namespace Nz
* \brief Closes the socket * \brief Closes the socket
*/ */
void AbstractSocket::Close() void AbstractSocket::Close() noexcept
{ {
if (m_handle != SocketImpl::InvalidHandle) if (m_handle != SocketImpl::InvalidHandle)
{ {
@ -237,7 +237,7 @@ namespace Nz
* \param abstractSocket AbstractSocket to move in this * \param abstractSocket AbstractSocket to move in this
*/ */
AbstractSocket& AbstractSocket::operator=(AbstractSocket&& abstractSocket) AbstractSocket& AbstractSocket::operator=(AbstractSocket&& abstractSocket) noexcept
{ {
Close(); Close();