Utility: Rework cursors
-Rename WindowCursor to SystemCursor -Merged Cursor class with SystemCursor enum
This commit is contained in:
parent
954298dc1e
commit
f406068c45
|
|
@ -251,7 +251,7 @@ int main()
|
|||
}
|
||||
|
||||
// On fait disparaître le curseur de la souris
|
||||
window.SetCursor(Nz::WindowCursor_None);
|
||||
window.SetCursor(Nz::SystemCursor_None);
|
||||
|
||||
// On lie la caméra à la fenêtre
|
||||
cameraComp.SetTarget(&window);
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ void SpacebattleExample::Enter(Ndk::StateMachine& fsm)
|
|||
m_turretReloadSound.LoadFromFile("resources/turretReload.wav");
|
||||
|
||||
//m_onMouseMoved.Connect(m_shared.target->GetEventHandler().OnMouseMoved, this, &SpacebattleExample::OnMouseMoved);
|
||||
//m_shared.target->SetCursor(Nz::WindowCursor_None);
|
||||
//m_shared.target->SetCursor(Nz::SystemCursor_None);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
|||
|
|
@ -22,18 +22,32 @@ namespace Nz
|
|||
|
||||
public:
|
||||
inline Cursor();
|
||||
inline Cursor(SystemCursor systemCursor); //< implicit conversion intended
|
||||
Cursor(const Cursor&) = delete;
|
||||
inline Cursor(Cursor&& cursor) noexcept;
|
||||
inline ~Cursor();
|
||||
|
||||
bool Create(const Image& cursor, int hotSpotX = 0, int hotSpotY = 0);
|
||||
bool Create(const Image& cursor, const Vector2i& hotSpot);
|
||||
bool Create(SystemCursor cursor);
|
||||
|
||||
void Destroy();
|
||||
|
||||
inline const Image& GetImage() const;
|
||||
inline SystemCursor GetSystemCursor() const;
|
||||
|
||||
inline bool IsValid() const;
|
||||
|
||||
Cursor& operator=(const Cursor&) = delete;
|
||||
inline Cursor& operator=(Cursor&& cursor);
|
||||
|
||||
private:
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
Image m_cursorImage;
|
||||
SystemCursor m_systemCursor;
|
||||
CursorImpl* m_impl;
|
||||
bool m_usesSystemCursor;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,30 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Cursor.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline Cursor::Cursor() :
|
||||
m_impl(nullptr)
|
||||
m_impl(nullptr),
|
||||
m_usesSystemCursor(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline Cursor::Cursor(SystemCursor systemCursor) :
|
||||
Cursor()
|
||||
{
|
||||
ErrorFlags flags(ErrorFlag_ThrowException, true);
|
||||
Create(systemCursor);
|
||||
}
|
||||
|
||||
inline Cursor::Cursor(Cursor&& cursor) noexcept :
|
||||
Cursor()
|
||||
{
|
||||
operator=(std::move(cursor));
|
||||
}
|
||||
|
||||
inline Cursor::~Cursor()
|
||||
{
|
||||
Destroy();
|
||||
|
|
@ -19,13 +34,36 @@ namespace Nz
|
|||
|
||||
inline const Image& Cursor::GetImage() const
|
||||
{
|
||||
NazaraAssert(IsValid(), "Invalid cursor");
|
||||
NazaraAssert(!m_usesSystemCursor, "System cursors have no image");
|
||||
|
||||
return m_cursorImage;
|
||||
}
|
||||
|
||||
inline SystemCursor Cursor::GetSystemCursor() const
|
||||
{
|
||||
NazaraAssert(IsValid(), "Invalid cursor");
|
||||
NazaraAssert(m_usesSystemCursor, "Custom cursor uses an image");
|
||||
|
||||
return m_systemCursor;
|
||||
}
|
||||
|
||||
inline bool Cursor::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
inline Cursor& Cursor::operator=(Cursor&& cursor)
|
||||
{
|
||||
m_cursorImage = std::move(cursor.m_cursorImage);
|
||||
m_systemCursor = cursor.m_systemCursor;
|
||||
m_impl = cursor.m_impl;
|
||||
m_usesSystemCursor = cursor.m_usesSystemCursor;
|
||||
|
||||
cursor.m_impl = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -307,6 +307,31 @@ namespace Nz
|
|||
SamplerWrap_Max = SamplerWrap_Repeat
|
||||
};
|
||||
|
||||
enum SystemCursor
|
||||
{
|
||||
SystemCursor_None,
|
||||
SystemCursor_Default,
|
||||
|
||||
SystemCursor_Crosshair,
|
||||
SystemCursor_Hand,
|
||||
SystemCursor_Help,
|
||||
SystemCursor_Move,
|
||||
SystemCursor_Pointer,
|
||||
SystemCursor_Progress,
|
||||
SystemCursor_ResizeE,
|
||||
SystemCursor_ResizeN,
|
||||
SystemCursor_ResizeNE,
|
||||
SystemCursor_ResizeNW,
|
||||
SystemCursor_ResizeS,
|
||||
SystemCursor_ResizeSE,
|
||||
SystemCursor_ResizeSW,
|
||||
SystemCursor_ResizeW,
|
||||
SystemCursor_Text,
|
||||
SystemCursor_Wait,
|
||||
|
||||
SystemCursor_Max = SystemCursor_Wait
|
||||
};
|
||||
|
||||
enum StencilOperation
|
||||
{
|
||||
StencilOperation_Decrement,
|
||||
|
|
@ -393,31 +418,6 @@ namespace Nz
|
|||
VertexLayout_Max = VertexLayout_Matrix4
|
||||
};
|
||||
|
||||
enum WindowCursor
|
||||
{
|
||||
WindowCursor_None,
|
||||
WindowCursor_Default,
|
||||
|
||||
WindowCursor_Crosshair,
|
||||
WindowCursor_Hand,
|
||||
WindowCursor_Help,
|
||||
WindowCursor_Move,
|
||||
WindowCursor_Pointer,
|
||||
WindowCursor_Progress,
|
||||
WindowCursor_ResizeE,
|
||||
WindowCursor_ResizeN,
|
||||
WindowCursor_ResizeNE,
|
||||
WindowCursor_ResizeNW,
|
||||
WindowCursor_ResizeS,
|
||||
WindowCursor_ResizeSE,
|
||||
WindowCursor_ResizeSW,
|
||||
WindowCursor_ResizeW,
|
||||
WindowCursor_Text,
|
||||
WindowCursor_Wait,
|
||||
|
||||
WindowCursor_Max = WindowCursor_Wait
|
||||
};
|
||||
|
||||
enum WindowEventType
|
||||
{
|
||||
WindowEventType_GainedFocus,
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ namespace Nz
|
|||
|
||||
void ProcessEvents(bool block = false);
|
||||
|
||||
void SetCursor(WindowCursor cursor);
|
||||
void SetCursor(const Cursor& cursor);
|
||||
void SetEventListener(bool listener);
|
||||
void SetFocus();
|
||||
|
|
|
|||
|
|
@ -16,28 +16,39 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
bool Cursor::Create(const Image& cursor, int hotSpotX, int hotSpotY)
|
||||
bool Cursor::Create(const Image& cursor, const Vector2i& hotSpot)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_impl = new CursorImpl;
|
||||
if (!m_impl->Create(cursor, hotSpotX, hotSpotY))
|
||||
std::unique_ptr<CursorImpl> impl(new CursorImpl);
|
||||
if (!impl->Create(cursor, hotSpot.x, hotSpot.y))
|
||||
{
|
||||
NazaraError("Failed to create cursor implementation");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cursorImage = cursor;
|
||||
m_impl = impl.release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cursor::Create(const Image& cursor, const Vector2i& hotSpot)
|
||||
inline bool Cursor::Create(SystemCursor cursor)
|
||||
{
|
||||
return Create(cursor, hotSpot.x, hotSpot.y);
|
||||
Destroy();
|
||||
|
||||
std::unique_ptr<CursorImpl> impl(new CursorImpl);
|
||||
if (!impl->Create(cursor))
|
||||
{
|
||||
NazaraError("Failed to create cursor implementation");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = impl.release();
|
||||
m_systemCursor = cursor;
|
||||
m_usesSystemCursor = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cursor::Destroy()
|
||||
|
|
@ -49,5 +60,17 @@ namespace Nz
|
|||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
m_usesSystemCursor = false;
|
||||
}
|
||||
|
||||
bool Cursor::Initialize()
|
||||
{
|
||||
return CursorImpl::Initialize();
|
||||
}
|
||||
|
||||
void Cursor::Uninitialize()
|
||||
{
|
||||
CursorImpl::Uninitialize();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,27 +30,77 @@ namespace Nz
|
|||
iconInfo.hbmMask = monoBitmap;
|
||||
iconInfo.hbmColor = bitmap;
|
||||
|
||||
m_cursor = CreateIconIndirect(&iconInfo);
|
||||
m_icon = CreateIconIndirect(&iconInfo);
|
||||
|
||||
DeleteObject(bitmap);
|
||||
DeleteObject(monoBitmap);
|
||||
|
||||
if (!m_cursor)
|
||||
if (!m_icon)
|
||||
{
|
||||
NazaraError("Failed to create cursor: " + Error::GetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cursor = m_icon;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CursorImpl::Create(SystemCursor cursor)
|
||||
{
|
||||
if (cursor != SystemCursor_Move)
|
||||
m_cursor = static_cast<HCURSOR>(LoadImage(nullptr, s_systemCursorIds[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
else
|
||||
m_cursor = nullptr;
|
||||
|
||||
// No need to free the cursor if shared
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
|
||||
m_icon = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CursorImpl::Destroy()
|
||||
{
|
||||
DestroyIcon(m_cursor);
|
||||
if (m_icon)
|
||||
DestroyIcon(m_icon);
|
||||
}
|
||||
|
||||
HCURSOR CursorImpl::GetCursor()
|
||||
{
|
||||
return m_cursor;
|
||||
}
|
||||
|
||||
bool CursorImpl::Initialize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CursorImpl::Uninitialize()
|
||||
{
|
||||
}
|
||||
|
||||
std::array<LPTSTR, SystemCursor_Max + 1> CursorImpl::s_systemCursorIds =
|
||||
{
|
||||
IDC_CROSS, // SystemCursor_Crosshair
|
||||
IDC_ARROW, // SystemCursor_Default
|
||||
IDC_HAND, // SystemCursor_Hand
|
||||
IDC_HELP, // SystemCursor_Help
|
||||
IDC_SIZEALL, // SystemCursor_Move
|
||||
nullptr, // SystemCursor_None
|
||||
IDC_HAND, // SystemCursor_Pointer
|
||||
IDC_APPSTARTING, // SystemCursor_Progress
|
||||
IDC_SIZEWE, // SystemCursor_ResizeE
|
||||
IDC_SIZENS, // SystemCursor_ResizeN
|
||||
IDC_SIZENESW, // SystemCursor_ResizeNE
|
||||
IDC_SIZENWSE, // SystemCursor_ResizeNW
|
||||
IDC_SIZENS, // SystemCursor_ResizeS
|
||||
IDC_SIZENWSE, // SystemCursor_ResizeSE
|
||||
IDC_SIZENESW, // SystemCursor_ResizeSW
|
||||
IDC_SIZEWE, // SystemCursor_ResizeW
|
||||
IDC_IBEAM, // SystemCursor_Text
|
||||
IDC_WAIT // SystemCursor_Wait
|
||||
};
|
||||
|
||||
static_assert(SystemCursor_Max + 1 == 18, "System cursor array is incomplete");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#define NAZARA_CURSORIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <array>
|
||||
#include <windows.h>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -16,14 +18,24 @@ namespace Nz
|
|||
|
||||
class CursorImpl
|
||||
{
|
||||
friend class Cursor;
|
||||
|
||||
public:
|
||||
bool Create(const Image& image, int hotSpotX, int hotSpotY);
|
||||
bool Create(SystemCursor cursor);
|
||||
|
||||
void Destroy();
|
||||
|
||||
HCURSOR GetCursor();
|
||||
|
||||
private:
|
||||
HICON m_cursor = nullptr;
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
HCURSOR m_cursor = nullptr;
|
||||
HICON m_icon = nullptr;
|
||||
|
||||
static std::array<LPTSTR, SystemCursor_Max + 1> s_systemCursorIds;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
// Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation
|
||||
|
||||
#define OEMRESOURCE
|
||||
|
||||
#include <Nazara/Utility/Win32/WindowImpl.hpp>
|
||||
#include <Nazara/Core/ConditionVariable.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
|
|
@ -38,30 +36,6 @@ namespace Nz
|
|||
{
|
||||
namespace
|
||||
{
|
||||
LPTSTR windowsCursors[] =
|
||||
{
|
||||
IDC_CROSS, // WindowCursor_Crosshair
|
||||
IDC_ARROW, // WindowCursor_Default
|
||||
IDC_HAND, // WindowCursor_Hand
|
||||
IDC_HAND, // WindowCursor_Pointer
|
||||
IDC_HELP, // WindowCursor_Help
|
||||
IDC_SIZEALL, // WindowCursor_Move
|
||||
nullptr, // WindowCursor_None
|
||||
IDC_APPSTARTING, // WindowCursor_Progress
|
||||
IDC_SIZENS, // WindowCursor_ResizeN
|
||||
IDC_SIZENS, // WindowCursor_ResizeS
|
||||
IDC_SIZENWSE, // WindowCursor_ResizeNW
|
||||
IDC_SIZENWSE, // WindowCursor_ResizeSE
|
||||
IDC_SIZENESW, // WindowCursor_ResizeNE
|
||||
IDC_SIZENESW, // WindowCursor_ResizeSW
|
||||
IDC_SIZEWE, // WindowCursor_ResizeE
|
||||
IDC_SIZEWE, // WindowCursor_ResizeW
|
||||
IDC_IBEAM, // WindowCursor_Text
|
||||
IDC_WAIT // WindowCursor_Wait
|
||||
};
|
||||
|
||||
static_assert(sizeof(windowsCursors)/sizeof(LPTSTR) == WindowCursor_Max+1, "Cursor type array is incomplete");
|
||||
|
||||
const wchar_t* className = L"Nazara Window";
|
||||
WindowImpl* fullscreenWindow = nullptr;
|
||||
}
|
||||
|
|
@ -321,26 +295,6 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void WindowImpl::SetCursor(WindowCursor cursor)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (cursor > WindowCursor_Max)
|
||||
{
|
||||
NazaraError("Window cursor out of enum");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cursor != WindowCursor_None)
|
||||
m_cursor = static_cast<HCURSOR>(LoadImage(nullptr, windowsCursors[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
else
|
||||
m_cursor = nullptr;
|
||||
|
||||
// Pas besoin de libérer le curseur par la suite s'il est partagé
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
|
||||
::SetCursor(m_cursor);
|
||||
}
|
||||
|
||||
void WindowImpl::SetCursor(const Cursor& cursor)
|
||||
{
|
||||
m_cursor = cursor.m_impl->GetCursor();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Nz
|
|||
class Mutex;
|
||||
class Window;
|
||||
|
||||
#undef IsMinimized // Conflit avec la méthode du même nom
|
||||
#undef IsMinimized // Conflits with windows.h redefinition
|
||||
|
||||
class WindowImpl
|
||||
{
|
||||
|
|
@ -62,7 +62,6 @@ namespace Nz
|
|||
|
||||
void ProcessEvents(bool block);
|
||||
|
||||
void SetCursor(WindowCursor cursor);
|
||||
void SetCursor(const Cursor& cursor);
|
||||
void SetEventListener(bool listener);
|
||||
void SetFocus();
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ namespace Nz
|
|||
// Paramètres par défaut
|
||||
m_impl->EnableKeyRepeat(true);
|
||||
m_impl->EnableSmoothScrolling(false);
|
||||
m_impl->SetCursor(WindowCursor_Default);
|
||||
m_impl->SetCursor(SystemCursor_Default);
|
||||
m_impl->SetMaximumSize(-1, -1);
|
||||
m_impl->SetMinimumSize(-1, -1);
|
||||
m_impl->SetVisible(true);
|
||||
|
|
@ -350,34 +350,10 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void Window::SetCursor(WindowCursor cursor)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetCursor(cursor);
|
||||
}
|
||||
|
||||
void Window::SetCursor(const Cursor& cursor)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cursor.IsValid())
|
||||
{
|
||||
NazaraError("Cursor is not valid");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Window not created");
|
||||
NazaraAssert(cursor.IsValid(), "Invalid cursor");
|
||||
|
||||
m_impl->SetCursor(cursor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,16 +159,96 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CursorImpl::Create(SystemCursor cursor)
|
||||
{
|
||||
ScopedXCBConnection connection;
|
||||
|
||||
if (xcb_cursor_context_new(connection, m_screen, &m_cursorContext) >= 0)
|
||||
m_cursor = xcb_cursor_load_cursor(ctx, s_systemCursorIds[cursor]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CursorImpl::Destroy()
|
||||
{
|
||||
ScopedXCBConnection connection;
|
||||
|
||||
xcb_free_cursor(connection, m_cursor);
|
||||
m_cursor = 0;
|
||||
if (m_cursorContext)
|
||||
xcb_cursor_context_free(m_cursorContext);
|
||||
}
|
||||
|
||||
xcb_cursor_t CursorImpl::GetCursor()
|
||||
{
|
||||
return m_cursor;
|
||||
}
|
||||
|
||||
bool CursorImpl::Initialize()
|
||||
{
|
||||
ScopedXCBConnection connection;
|
||||
XCBPixmap cursorPixmap(connection);
|
||||
|
||||
xcb_window_t window = X11::XCBDefaultRootWindow(connection);
|
||||
|
||||
if (!cursorPixmap.Create(1, window, 1, 1))
|
||||
{
|
||||
NazaraError("Failed to create pixmap for hidden cursor");
|
||||
return false;
|
||||
}
|
||||
|
||||
hiddenCursor = xcb_generate_id(connection);
|
||||
|
||||
// Create the cursor, using the pixmap as both the shape and the mask of the cursor
|
||||
if (!X11::CheckCookie(
|
||||
connection, xcb_create_cursor(connection,
|
||||
hiddenCursor,
|
||||
cursorPixmap,
|
||||
cursorPixmap,
|
||||
0, 0, 0, // Foreground RGB color
|
||||
0, 0, 0, // Background RGB color
|
||||
0, // X
|
||||
0 // Y
|
||||
)))
|
||||
{
|
||||
NazaraError("Failed to create hidden cursor");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CursorImpl::Uninitialize()
|
||||
{
|
||||
if (s_hiddenCursor)
|
||||
{
|
||||
ScopedXCBConnection connection;
|
||||
xcb_free_cursor(connection, s_hiddenCursor);
|
||||
s_hiddenCursor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::array<const char*, SystemCursor_Max + 1> CursorImpl::s_systemCursorIds =
|
||||
{
|
||||
// http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6
|
||||
"crosshair", // SystemCursor_Crosshair
|
||||
"left_ptr", // SystemCursor_Default
|
||||
"hand", // SystemCursor_Hand
|
||||
"help", // SystemCursor_Help
|
||||
"fleur", // SystemCursor_Move
|
||||
nullptr, // SystemCursor_None
|
||||
"hand", // SystemCursor_Pointer
|
||||
"watch", // SystemCursor_Progress
|
||||
"right_side", // SystemCursor_ResizeE
|
||||
"top_side", // SystemCursor_ResizeN
|
||||
"top_right_corner", // SystemCursor_ResizeNE
|
||||
"top_left_corner", // SystemCursor_ResizeNW
|
||||
"bottom_side", // SystemCursor_ResizeS
|
||||
"bottom_right_corner", // SystemCursor_ResizeSE
|
||||
"bottom_left_corner", // SystemCursor_ResizeSW
|
||||
"left_side", // SystemCursor_ResizeW
|
||||
"xterm", // SystemCursor_Text
|
||||
"watch" // SystemCursor_Wait
|
||||
};
|
||||
|
||||
static_assert(SystemCursor_Max + 1 == 18, "System cursor array is incomplete");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_CURSORIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <xcb/xcb_cursor.h>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -16,14 +17,24 @@ namespace Nz
|
|||
|
||||
class CursorImpl
|
||||
{
|
||||
friend class Cursor;
|
||||
|
||||
public:
|
||||
bool Create(const Image& image, int hotSpotX, int hotSpotY);
|
||||
bool Create(SystemCursor cursor);
|
||||
|
||||
void Destroy();
|
||||
|
||||
xcb_cursor_t GetCursor();
|
||||
|
||||
private:
|
||||
xcb_cursor_t m_cursor;
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
xcb_cursor_t m_cursor = 0;
|
||||
xcb_cursor_context_t* m_cursorContext = nullptr;
|
||||
|
||||
static std::array<const char*, SystemCursor_Max + 1> s_systemCursorIds;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,45 +50,7 @@ namespace Nz
|
|||
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
||||
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW;
|
||||
|
||||
xcb_cursor_t hiddenCursor = 0;
|
||||
|
||||
xcb_connection_t* connection = nullptr;
|
||||
|
||||
void CreateHiddenCursor()
|
||||
{
|
||||
XCBPixmap cursorPixmap(connection);
|
||||
|
||||
xcb_window_t window = X11::XCBDefaultRootWindow(connection);
|
||||
|
||||
if (!cursorPixmap.Create(
|
||||
1,
|
||||
window,
|
||||
1,
|
||||
1
|
||||
))
|
||||
{
|
||||
NazaraError("Failed to create pixmap for hidden cursor");
|
||||
return;
|
||||
}
|
||||
|
||||
hiddenCursor = xcb_generate_id(connection);
|
||||
|
||||
// Create the cursor, using the pixmap as both the shape and the mask of the cursor
|
||||
if (!X11::CheckCookie(
|
||||
connection,
|
||||
xcb_create_cursor(
|
||||
connection,
|
||||
hiddenCursor,
|
||||
cursorPixmap,
|
||||
cursorPixmap,
|
||||
0, 0, 0, // Foreground RGB color
|
||||
0, 0, 0, // Background RGB color
|
||||
0, // X
|
||||
0 // Y
|
||||
))
|
||||
)
|
||||
NazaraError("Failed to create hidden cursor");
|
||||
}
|
||||
}
|
||||
|
||||
WindowImpl::WindowImpl(Window* parent) :
|
||||
|
|
@ -452,34 +414,13 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void WindowImpl::SetCursor(Nz::WindowCursor windowCursor)
|
||||
{
|
||||
if (windowCursor == Nz::WindowCursor_None)
|
||||
SetCursor(hiddenCursor);
|
||||
else
|
||||
{
|
||||
const char* name = ConvertWindowCursorToXName(windowCursor);
|
||||
|
||||
xcb_cursor_context_t* ctx;
|
||||
if (xcb_cursor_context_new(connection, m_screen, &ctx) >= 0)
|
||||
{
|
||||
xcb_cursor_t cursor = xcb_cursor_load_cursor(ctx, name);
|
||||
SetCursor(cursor);
|
||||
xcb_free_cursor(connection, cursor);
|
||||
xcb_cursor_context_free(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WindowImpl::SetCursor(const Cursor& cursor)
|
||||
{
|
||||
if (!cursor.IsValid())
|
||||
{
|
||||
NazaraError("Cursor is not valid");
|
||||
return;
|
||||
}
|
||||
xcb_cursor_t cursorImpl = cursor.m_impl->GetCursor();
|
||||
if (!X11::CheckCookie(connection, xcb_change_window_attributes(connection, m_window, XCB_CW_CURSOR, &cursor)))
|
||||
NazaraError("Failed to change mouse cursor");
|
||||
|
||||
SetCursor(cursor.m_impl->GetCursor());
|
||||
xcb_flush(connection);
|
||||
}
|
||||
|
||||
void WindowImpl::SetEventListener(bool listener)
|
||||
|
|
@ -998,7 +939,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
const char* WindowImpl::ConvertWindowCursorToXName(Nz::WindowCursor cursor)
|
||||
const char* WindowImpl::ConvertWindowCursorToXName(SystemCursor cursor)
|
||||
{
|
||||
// http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6
|
||||
switch (cursor)
|
||||
|
|
@ -1444,22 +1385,6 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void WindowImpl::SetCursor(xcb_cursor_t cursor)
|
||||
{
|
||||
if (!X11::CheckCookie(
|
||||
connection,
|
||||
xcb_change_window_attributes(
|
||||
connection,
|
||||
m_window,
|
||||
XCB_CW_CURSOR,
|
||||
&cursor
|
||||
))
|
||||
)
|
||||
NazaraError("Failed to change mouse cursor");
|
||||
|
||||
xcb_flush(connection);
|
||||
}
|
||||
|
||||
void WindowImpl::SetMotifHints()
|
||||
{
|
||||
ScopedXCB<xcb_generic_error_t> error(nullptr);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ namespace Nz
|
|||
|
||||
void ProcessEvents(bool block);
|
||||
|
||||
void SetCursor(WindowCursor cursor);
|
||||
void SetCursor(const Cursor& cursor);
|
||||
void SetEventListener(bool listener);
|
||||
void SetFocus();
|
||||
|
|
@ -84,7 +83,7 @@ namespace Nz
|
|||
void CleanUp();
|
||||
xcb_keysym_t ConvertKeyCodeToKeySym(xcb_keycode_t keycode, uint16_t state);
|
||||
Keyboard::Key ConvertVirtualKey(xcb_keysym_t symbol);
|
||||
const char* ConvertWindowCursorToXName(WindowCursor cursor);
|
||||
const char* ConvertWindowCursorToXName(SystemCursor cursor);
|
||||
void CommonInitialize();
|
||||
|
||||
char32_t GetRepresentation(xcb_keysym_t keysym) const;
|
||||
|
|
@ -93,7 +92,6 @@ namespace Nz
|
|||
|
||||
void ResetVideoMode();
|
||||
|
||||
void SetCursor(xcb_cursor_t cursor);
|
||||
void SetMotifHints();
|
||||
void SetVideoMode(const VideoMode& mode);
|
||||
void SwitchToFullscreen();
|
||||
|
|
|
|||
Loading…
Reference in New Issue