Utility/Cursor: Rework Cursor as a handled object

This commit is contained in:
Lynix
2017-01-19 21:38:56 +01:00
parent c4574ed7ec
commit 670199b557
8 changed files with 92 additions and 50 deletions

View File

@@ -8,28 +8,34 @@
#define NAZARA_CURSOR_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ObjectRef.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/Image.hpp>
#include <array>
namespace Nz
{
class CursorImpl;
class NAZARA_UTILITY_API Cursor
class Cursor;
using CursorConstRef = ObjectRef<const Cursor>;
using CursorRef = ObjectRef<Cursor>;
class NAZARA_UTILITY_API Cursor : public RefCounted
{
friend class Utility;
friend class WindowImpl;
public:
inline Cursor();
inline Cursor(SystemCursor systemCursor); //< implicit conversion intended
inline Cursor(const Image& cursor, const Vector2i& hotSpot, SystemCursor placeholder);
Cursor(const Cursor&) = delete;
inline Cursor(Cursor&& cursor) noexcept;
Cursor(Cursor&&) = delete;
inline ~Cursor();
bool Create(const Image& cursor, const Vector2i& hotSpot);
bool Create(SystemCursor cursor);
bool Create(const Image& cursor, const Vector2i& hotSpot, SystemCursor placeholder);
void Destroy();
@@ -39,16 +45,24 @@ namespace Nz
inline bool IsValid() const;
Cursor& operator=(const Cursor&) = delete;
inline Cursor& operator=(Cursor&& cursor);
Cursor& operator=(Cursor&&) = delete;
static inline Cursor* Get(SystemCursor cursor);
template<typename... Args> static CursorRef New(Args&&... args);
private:
inline explicit Cursor(SystemCursor systemCursor);
bool Create(SystemCursor cursor);
static bool Initialize();
static void Uninitialize();
Image m_cursorImage;
SystemCursor m_systemCursor;
CursorImpl* m_impl;
bool m_usesSystemCursor;
static std::array<Cursor, SystemCursor_Max + 1> s_systemCursors;
};
}

View File

@@ -9,11 +9,21 @@
namespace Nz
{
inline Cursor::Cursor() :
m_impl(nullptr),
m_usesSystemCursor(false)
m_impl(nullptr)
{
}
inline Cursor::Cursor(const Image& cursor, const Vector2i& hotSpot, SystemCursor placeholder)
{
ErrorFlags flags(ErrorFlag_ThrowException, true);
Create(cursor, hotSpot, placeholder);
}
inline Cursor* Cursor::Get(SystemCursor cursor)
{
return &s_systemCursors[cursor];
}
inline Cursor::Cursor(SystemCursor systemCursor) :
Cursor()
{
@@ -21,12 +31,6 @@ namespace Nz
Create(systemCursor);
}
inline Cursor::Cursor(Cursor&& cursor) noexcept :
Cursor()
{
operator=(std::move(cursor));
}
inline Cursor::~Cursor()
{
Destroy();
@@ -35,7 +39,7 @@ namespace Nz
inline const Image& Cursor::GetImage() const
{
NazaraAssert(IsValid(), "Invalid cursor");
NazaraAssert(!m_usesSystemCursor, "System cursors have no image");
NazaraAssert(m_cursorImage.IsValid(), "System cursors have no image");
return m_cursorImage;
}
@@ -43,7 +47,6 @@ namespace Nz
inline SystemCursor Cursor::GetSystemCursor() const
{
NazaraAssert(IsValid(), "Invalid cursor");
NazaraAssert(m_usesSystemCursor, "Custom cursor uses an image");
return m_systemCursor;
}
@@ -53,16 +56,13 @@ namespace Nz
return m_impl != nullptr;
}
inline Cursor& Cursor::operator=(Cursor&& cursor)
template<typename... Args>
CursorRef Cursor::New(Args&&... args)
{
m_cursorImage = std::move(cursor.m_cursorImage);
m_systemCursor = cursor.m_systemCursor;
m_impl = cursor.m_impl;
m_usesSystemCursor = cursor.m_usesSystemCursor;
std::unique_ptr<Cursor> object(new Cursor(std::forward<Args>(args)...));
object->SetPersistent(false);
cursor.m_impl = nullptr;
return *this;
return object.release();
}
}

View File

@@ -28,12 +28,12 @@ namespace Nz
CursorController(CursorController&&) = default;
~CursorController() = default;
inline void UpdateCursor(const Cursor& cursor);
inline void UpdateCursor(const CursorRef& cursor);
CursorController& operator=(const CursorController&) = delete;
CursorController& operator=(CursorController&&) = default;
NazaraSignal(OnCursorUpdated, const CursorController* /*cursorController*/, const Cursor& /*cursor*/);
NazaraSignal(OnCursorUpdated, const CursorController* /*cursorController*/, const CursorRef& /*cursor*/);
};
}

View File

@@ -7,7 +7,7 @@
namespace Nz
{
inline void CursorController::UpdateCursor(const Cursor& cursor)
inline void CursorController::UpdateCursor(const CursorRef& cursor)
{
OnCursorUpdated(this, cursor);
}

View File

@@ -58,6 +58,7 @@ namespace Nz
void EnableKeyRepeat(bool enable);
void EnableSmoothScrolling(bool enable);
inline const CursorRef& GetCursor() const;
inline CursorController& GetCursorController();
inline EventHandler& GetEventHandler();
WindowHandle GetHandle() const;
@@ -81,7 +82,8 @@ namespace Nz
void ProcessEvents(bool block = false);
void SetCursor(const Cursor& cursor);
void SetCursor(CursorRef cursor);
inline void SetCursor(SystemCursor systemCursor);
void SetEventListener(bool listener);
void SetFocus();
void SetIcon(const Icon& icon);
@@ -122,6 +124,7 @@ namespace Nz
std::vector<WindowEvent> m_pendingEvents;
ConditionVariable m_eventCondition;
CursorController m_cursorController;
CursorRef m_cursor;
EventHandler m_eventHandler;
Mutex m_eventMutex;
Mutex m_eventConditionMutex;

View File

@@ -67,6 +67,11 @@ namespace Nz
}
}
inline const CursorRef& Window::GetCursor() const
{
return m_cursor;
}
inline CursorController& Nz::Window::GetCursorController()
{
return m_cursorController;
@@ -101,6 +106,11 @@ namespace Nz
return m_impl != nullptr;
}
inline void Window::SetCursor(SystemCursor systemCursor)
{
SetCursor(Cursor::Get(systemCursor));
}
inline void Window::HandleEvent(const WindowEvent& event)
{
if (m_eventPolling)