Implemented methods to set the displayed cursor to a system cursor type or custom bitmap image.

This commit is contained in:
binary1248 2015-03-15 03:30:01 +01:00 committed by Lukas Dürrenberger
parent bd479c4454
commit 6f5a7d1b1b
14 changed files with 631 additions and 12 deletions

View File

@ -56,6 +56,29 @@ class Event;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
class SFML_WINDOW_API Window : GlResource, NonCopyable class SFML_WINDOW_API Window : GlResource, NonCopyable
{ {
public:
////////////////////////////////////////////////////////////
/// \brief Enumeration of the native system cursor types
///
////////////////////////////////////////////////////////////
enum Cursor
{
Arrow, ///< Arrow cursor (default)
ArrowWait, ///< Busy arrow cursor
Wait, ///< Busy cursor
Text, ///< I-beam, cursor when hovering over a field allowing text entry
Hand, ///< Pointing hand cursor
SizeHorizontal, ///< Horizontal double arrow cursor
SizeVertical, ///< Vertical double arrow cursor
SizeTopLeftBottomRight, ///< Double arrow cursor going from top-left to bottom-right
SizeBottomLeftTopRight, ///< Double arrow cursor going from bottom-left to top-right
SizeAll, ///< Combination of CursorSizeHorizontal and CursorSizeVertical
Cross, ///< Crosshair cursor
Help, ///< Help cursor
NotAllowed ///< Action not allowed cursor
};
public: public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -361,6 +384,43 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void setMouseCursorGrabbed(bool grabbed); void setMouseCursorGrabbed(bool grabbed);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to a native system cursor
///
/// Upon window creation, the arrow cursor is used by default.
///
/// \param cursor Native system cursor type to display
///
////////////////////////////////////////////////////////////
void setMouseCursor(Cursor cursor);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to the provided image
///
/// \a pixels must be an array of \a width x \a height pixels
/// in 32-bit RGBA format. If not, this will cause undefined behavior.
///
/// If \a pixels is null or either \a width or \a height are 0,
/// the current cursor is left unchanged.
///
/// In addition to specifying the pixel data, you can also
/// specify the location of the hotspot of the cursor. The
/// hotspot is the pixel coordinate within the cursor image
/// which will be located exactly where the mouse pointer
/// position is. Any mouse actions that are performed will
/// return the window/screen location of the hotspot.
///
/// Upon window creation, the arrow cursor is used by default.
///
/// \param pixels Array of pixels of the image
/// \param width Width of the image
/// \param height Height of the image
/// \param hotspotX X location of the hotspot
/// \param hotspotY Y location of the hotspot
///
////////////////////////////////////////////////////////////
void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat /// \brief Enable or disable automatic key-repeat
/// ///

View File

@ -185,6 +185,20 @@ void WindowImplAndroid::setMouseCursorGrabbed(bool grabbed)
} }
////////////////////////////////////////////////////////////
void WindowImplAndroid::setMouseCursor(Window::Cursor cursor)
{
// Not applicable
}
////////////////////////////////////////////////////////////
void WindowImplAndroid::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY)
{
// Not applicable
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void WindowImplAndroid::setKeyRepeatEnabled(bool enabled) void WindowImplAndroid::setKeyRepeatEnabled(bool enabled)
{ {

View File

@ -154,6 +154,26 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void setMouseCursorGrabbed(bool grabbed); virtual void setMouseCursorGrabbed(bool grabbed);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to a native system cursor
///
/// \param cursor Native system cursor type to display
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(Window::Cursor cursor);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to the provided image
///
/// \param pixels Array of pixels of the image
/// \param width Width of the image
/// \param height Height of the image
/// \param hotspotX X location of the hotspot
/// \param hotspotY Y location of the hotspot
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat /// \brief Enable or disable automatic key-repeat
/// ///

View File

@ -321,6 +321,26 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void setMouseCursorGrabbed(bool grabbed); virtual void setMouseCursorGrabbed(bool grabbed);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to a native system cursor
///
/// \param cursor Native system cursor type to display
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(Window::Cursor cursor);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to the provided image
///
/// \param pixels Array of pixels of the image
/// \param width Width of the image
/// \param height Height of the image
/// \param hotspotX X location of the hotspot
/// \param hotspotY Y location of the hotspot
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat /// \brief Enable or disable automatic key-repeat
/// ///

View File

@ -493,6 +493,20 @@ void WindowImplCocoa::setMouseCursorGrabbed(bool grabbed)
} }
////////////////////////////////////////////////////////////
void WindowImplCocoa::setMouseCursor(Window::Cursor cursor)
{
// TODO: Implement OS X cursor setting
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY)
{
// TODO: Implement OS X cursor setting
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled) void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
{ {

View File

@ -25,8 +25,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/Unix/WindowImplX11.hpp> // important to be included first (conflict with None)
#include <SFML/Window/Unix/GlxContext.hpp> #include <SFML/Window/Unix/GlxContext.hpp>
#include <SFML/Window/Unix/WindowImplX11.hpp>
#include <SFML/Window/Unix/Display.hpp> #include <SFML/Window/Unix/Display.hpp>
#include <SFML/System/Mutex.hpp> #include <SFML/System/Mutex.hpp>
#include <SFML/System/Lock.hpp> #include <SFML/System/Lock.hpp>

View File

@ -900,6 +900,250 @@ void WindowImplX11::setMouseCursorVisible(bool visible)
} }
////////////////////////////////////////////////////////////
void WindowImplX11::setMouseCursor(Window::Cursor cursor)
{
xcb_cursor_t newCursor = 0;
xcb_cursor_context_t* cursorContext = NULL;
if (xcb_cursor_context_new(m_connection, m_screen, &cursorContext) < 0)
{
err() << "Could not create XCB cursor context" << std::endl;
return;
}
switch(cursor)
{
case Window::Arrow: newCursor = xcb_cursor_load_cursor(cursorContext, "left_ptr"); break;
case Window::ArrowWait: newCursor = xcb_cursor_load_cursor(cursorContext, "left_ptr"); break;
case Window::Wait: newCursor = xcb_cursor_load_cursor(cursorContext, "watch"); break;
case Window::Text: newCursor = xcb_cursor_load_cursor(cursorContext, "xterm"); break;
case Window::Hand: newCursor = xcb_cursor_load_cursor(cursorContext, "hand2"); break;
case Window::SizeHorizontal: newCursor = xcb_cursor_load_cursor(cursorContext, "sb_h_double_arrow"); break;
case Window::SizeVertical: newCursor = xcb_cursor_load_cursor(cursorContext, "sb_v_double_arrow"); break;
case Window::SizeTopLeftBottomRight: newCursor = xcb_cursor_load_cursor(cursorContext, "fleur"); break;
case Window::SizeBottomLeftTopRight: newCursor = xcb_cursor_load_cursor(cursorContext, "fleur"); break;
case Window::SizeAll: newCursor = xcb_cursor_load_cursor(cursorContext, "fleur"); break;
case Window::Cross: newCursor = xcb_cursor_load_cursor(cursorContext, "crosshair"); break;
case Window::Help: newCursor = xcb_cursor_load_cursor(cursorContext, "question_arrow"); break;
case Window::NotAllowed: newCursor = xcb_cursor_load_cursor(cursorContext, "left_ptr"); break;
default: break;
}
xcb_cursor_context_free(cursorContext);
if (m_loadedCursor)
xcb_free_cursor(m_connection, m_loadedCursor);
if (!newCursor)
return;
m_loadedCursor = newCursor;
if (!m_cursor)
return;
ScopedXcbPtr<xcb_generic_error_t> changeAttributesError(xcb_request_check(
m_connection,
xcb_change_window_attributes(
m_connection,
m_window,
XCB_CW_CURSOR,
&m_loadedCursor
)
));
if (changeAttributesError)
{
err() << "Failed to change window attributes" << std::endl;
return;
}
m_cursor = m_loadedCursor;
}
////////////////////////////////////////////////////////////
void WindowImplX11::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY)
{
// Get the picture format from XCB
ScopedXcbPtr<xcb_render_query_pict_formats_reply_t> pictFormatsreply(xcb_render_query_pict_formats_reply(
m_connection,
xcb_render_query_pict_formats(
m_connection
),
NULL
));
xcb_render_pictformat_t pictureFormat = xcb_render_util_find_standard_format(pictFormatsreply.get(), XCB_PICT_STANDARD_ARGB_32)->id;
if (!pictureFormat)
{
err() << "Failed to get picture format from XCB" << std::endl;
return;
}
// X11 wants BGRA pixels: swap red and blue channels
Uint8 cursorPixels[width * height * 4];
for (std::size_t i = 0; i < width * height; ++i)
{
cursorPixels[i * 4 + 0] = pixels[i * 4 + 2];
cursorPixels[i * 4 + 1] = pixels[i * 4 + 1];
cursorPixels[i * 4 + 2] = pixels[i * 4 + 0];
cursorPixels[i * 4 + 3] = pixels[i * 4 + 3];
}
xcb_pixmap_t cursorPixmap = xcb_generate_id(m_connection);
ScopedXcbPtr<xcb_generic_error_t> pixmapError(xcb_request_check(
m_connection,
xcb_create_pixmap(
m_connection,
32,
cursorPixmap,
m_window,
width,
height
)
));
if (pixmapError)
{
err() << "Failed to create XCB cursor pixmap" << std::endl;
return;
}
xcb_gcontext_t cursorGC = xcb_generate_id(m_connection);
ScopedXcbPtr<xcb_generic_error_t> gcError(xcb_request_check(
m_connection,
xcb_create_gc(
m_connection,
cursorGC,
cursorPixmap,
0,
NULL
)
));
if (gcError)
{
err() << "Failed to create XCB graphics context" << std::endl;
xcb_free_pixmap(m_connection, cursorPixmap);
return;
}
xcb_image_t* cursorImage = xcb_image_create_native(
m_connection,
width,
height,
XCB_IMAGE_FORMAT_Z_PIXMAP,
32,
NULL,
width * height * 4,
cursorPixels
);
if (!cursorImage)
{
err() << "Failed to create XCB cursor image" << std::endl;
xcb_free_gc(m_connection, cursorGC);
xcb_free_pixmap(m_connection, cursorPixmap);
return;
}
ScopedXcbPtr<xcb_generic_error_t> imagePutError(xcb_request_check(
m_connection,
xcb_image_put(
m_connection,
cursorPixmap,
cursorGC,
cursorImage,
0,
0,
0
)
));
if (imagePutError)
{
err() << "Failed to put XCB image on the X server" << std::endl;
xcb_image_destroy(cursorImage);
xcb_free_gc(m_connection, cursorGC);
xcb_free_pixmap(m_connection, cursorPixmap);
return;
}
xcb_render_picture_t cursorPicture = xcb_generate_id(m_connection);
ScopedXcbPtr<xcb_generic_error_t> createPictureError(xcb_request_check(
m_connection,
xcb_render_create_picture(
m_connection,
cursorPicture,
cursorPixmap,
pictureFormat,
0,
NULL
)
));
if (createPictureError)
{
err() << "Failed to create XCB cursor picture" << std::endl;
xcb_image_destroy(cursorImage);
xcb_free_gc(m_connection, cursorGC);
xcb_free_pixmap(m_connection, cursorPixmap);
return;
}
xcb_cursor_t newCursor = xcb_generate_id(m_connection);
ScopedXcbPtr<xcb_generic_error_t> createCursorError(xcb_request_check(
m_connection,
xcb_render_create_cursor(
m_connection,
newCursor,
cursorPicture,
hotspotX,
hotspotY
)
));
xcb_render_free_picture(m_connection, cursorPicture);
xcb_image_destroy(cursorImage);
xcb_free_gc(m_connection, cursorGC);
xcb_free_pixmap(m_connection, cursorPixmap);
if (createCursorError)
{
err() << "Failed to create XCB cursor" << std::endl;
return;
}
xcb_free_cursor(m_connection, m_loadedCursor);
m_loadedCursor = newCursor;
if (!m_cursor)
return;
ScopedXcbPtr<xcb_generic_error_t> changeAttributesError(xcb_request_check(
m_connection,
xcb_change_window_attributes(
m_connection,
m_window,
XCB_CW_CURSOR,
&m_loadedCursor
)
));
if (changeAttributesError)
{
err() << "Failed to change window attributes" << std::endl;
return;
}
m_cursor = m_loadedCursor;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void WindowImplX11::setMouseCursorGrabbed(bool grabbed) void WindowImplX11::setMouseCursorGrabbed(bool grabbed)
{ {
@ -1306,9 +1550,6 @@ void WindowImplX11::initialize()
// Raise the window and grab input focus // Raise the window and grab input focus
grabFocus(); grabFocus();
// Create the hidden cursor
createHiddenCursor();
// Flush the commands queue // Flush the commands queue
XFlush(m_display); XFlush(m_display);

View File

@ -154,6 +154,26 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void setMouseCursorGrabbed(bool grabbed); virtual void setMouseCursorGrabbed(bool grabbed);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to a native system cursor
///
/// \param cursor Native system cursor type to display
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(Window::Cursor cursor);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to the provided image
///
/// \param pixels Array of pixels of the image
/// \param width Width of the image
/// \param height Height of the image
/// \param hotspotX X location of the hotspot
/// \param hotspotY Y location of the hotspot
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat /// \brief Enable or disable automatic key-repeat
/// ///
@ -233,12 +253,6 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void initialize(); void initialize();
////////////////////////////////////////////////////////////
/// \brief Create a transparent mouse cursor
///
////////////////////////////////////////////////////////////
void createHiddenCursor();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Cleanup graphical resources attached to the window /// \brief Cleanup graphical resources attached to the window
/// ///

View File

@ -40,6 +40,7 @@
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <SFML/System/Utf.hpp> #include <SFML/System/Utf.hpp>
#include <vector> #include <vector>
#include <cstring>
// MinGW lacks the definition of some Win32 constants // MinGW lacks the definition of some Win32 constants
#ifndef XBUTTON1 #ifndef XBUTTON1
@ -132,6 +133,7 @@ WindowImplWin32::WindowImplWin32(WindowHandle handle) :
m_handle (handle), m_handle (handle),
m_callback (0), m_callback (0),
m_cursor (NULL), m_cursor (NULL),
m_loadedCursor (NULL),
m_icon (NULL), m_icon (NULL),
m_keyRepeatEnabled(true), m_keyRepeatEnabled(true),
m_lastSize (0, 0), m_lastSize (0, 0),
@ -164,6 +166,7 @@ WindowImplWin32::WindowImplWin32(VideoMode mode, const String& title, Uint32 sty
m_handle (NULL), m_handle (NULL),
m_callback (0), m_callback (0),
m_cursor (NULL), m_cursor (NULL),
m_loadedCursor (NULL),
m_icon (NULL), m_icon (NULL),
m_keyRepeatEnabled(true), m_keyRepeatEnabled(true),
m_lastSize (mode.width, mode.height), m_lastSize (mode.width, mode.height),
@ -238,6 +241,10 @@ m_cursorGrabbed (m_fullscreen)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
WindowImplWin32::~WindowImplWin32() WindowImplWin32::~WindowImplWin32()
{ {
// Destroy the cursor
if (m_loadedCursor)
DestroyCursor(m_loadedCursor);
// Destroy the custom icon, if any // Destroy the custom icon, if any
if (m_icon) if (m_icon)
DestroyIcon(m_icon); DestroyIcon(m_icon);
@ -389,8 +396,12 @@ void WindowImplWin32::setVisible(bool visible)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void WindowImplWin32::setMouseCursorVisible(bool visible) void WindowImplWin32::setMouseCursorVisible(bool visible)
{ {
// Set the default mouse cursor if none has been loaded yet
if (!m_loadedCursor)
setMouseCursor(Window::Arrow);
if (visible) if (visible)
m_cursor = LoadCursorW(NULL, IDC_ARROW); m_cursor = m_loadedCursor;
else else
m_cursor = NULL; m_cursor = NULL;
@ -406,6 +417,139 @@ void WindowImplWin32::setMouseCursorGrabbed(bool grabbed)
} }
////////////////////////////////////////////////////////////
void WindowImplWin32::setMouseCursor(Window::Cursor cursor)
{
HCURSOR newCursor = NULL;
switch (cursor)
{
case Window::Arrow: newCursor = LoadCursor(NULL, IDC_ARROW); break;
case Window::ArrowWait: newCursor = LoadCursor(NULL, IDC_APPSTARTING); break;
case Window::Wait: newCursor = LoadCursor(NULL, IDC_WAIT); break;
case Window::Text: newCursor = LoadCursor(NULL, IDC_IBEAM); break;
case Window::Hand: newCursor = LoadCursor(NULL, IDC_HAND); break;
case Window::SizeHorizontal: newCursor = LoadCursor(NULL, IDC_SIZEWE); break;
case Window::SizeVertical: newCursor = LoadCursor(NULL, IDC_SIZENS); break;
case Window::SizeTopLeftBottomRight: newCursor = LoadCursor(NULL, IDC_SIZENWSE); break;
case Window::SizeBottomLeftTopRight: newCursor = LoadCursor(NULL, IDC_SIZENESW); break;
case Window::SizeAll: newCursor = LoadCursor(NULL, IDC_SIZEALL); break;
case Window::Cross: newCursor = LoadCursor(NULL, IDC_CROSS); break;
case Window::Help: newCursor = LoadCursor(NULL, IDC_HELP); break;
case Window::NotAllowed: newCursor = LoadCursor(NULL, IDC_NO); break;
default: return;
}
// Create a copy of the shared system cursor that we can destroy later
newCursor = CopyCursor(newCursor);
if (!newCursor)
{
err() << "Could not create copy of a system cursor" << std::endl;
return;
}
HCURSOR oldCursor = m_loadedCursor;
m_loadedCursor = newCursor;
if (m_cursor)
{
m_cursor = m_loadedCursor;
SetCursor(m_cursor);
}
if (oldCursor)
DestroyCursor(oldCursor);
}
////////////////////////////////////////////////////////////
void WindowImplWin32::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY)
{
// Create the bitmap that will hold our color data
BITMAPV5HEADER bitmapHeader;
std::memset(&bitmapHeader, 0, sizeof(BITMAPV5HEADER));
bitmapHeader.bV5Size = sizeof(BITMAPV5HEADER);
bitmapHeader.bV5Width = width;
bitmapHeader.bV5Height = -height; // Negative indicates origin is in upper-left corner
bitmapHeader.bV5Planes = 1;
bitmapHeader.bV5BitCount = 32;
bitmapHeader.bV5Compression = BI_BITFIELDS;
bitmapHeader.bV5RedMask = 0x00ff0000;
bitmapHeader.bV5GreenMask = 0x0000ff00;
bitmapHeader.bV5BlueMask = 0x000000ff;
bitmapHeader.bV5AlphaMask = 0xff000000;
Uint8* bitmapData = NULL;
HDC screenDC = GetDC(NULL);
HBITMAP color = CreateDIBSection(
screenDC,
reinterpret_cast<const BITMAPINFO*>(&bitmapHeader),
DIB_RGB_COLORS,
reinterpret_cast<void**>(&bitmapData),
NULL,
0
);
ReleaseDC(NULL, screenDC);
if (!color)
{
err() << "Failed to create cursor color bitmap" << std::endl;
return;
}
// Fill our bitmap with the cursor color data
std::memcpy(bitmapData, pixels, width * height * 4);
// Create a dummy mask bitmap (it won't be used)
HBITMAP mask = CreateBitmap(width, height, 1, 1, NULL);
if (!mask)
{
DeleteObject(color);
err() << "Failed to create cursor mask bitmap" << std::endl;
return;
}
// Create the structure that describes our cursor
ICONINFO cursorInfo;
std::memset(&cursorInfo, 0, sizeof(ICONINFO));
cursorInfo.fIcon = FALSE; // This is a cursor and not an icon
cursorInfo.xHotspot = hotspotX;
cursorInfo.yHotspot = hotspotY;
cursorInfo.hbmColor = color;
cursorInfo.hbmMask = mask;
// Create the cursor
HCURSOR newCursor = reinterpret_cast<HCURSOR>(CreateIconIndirect(&cursorInfo));
// The data has been copied into the cursor, so get rid of these
DeleteObject(color);
DeleteObject(mask);
if (!newCursor)
{
err() << "Failed to create cursor from bitmaps" << std::endl;
return;
}
HCURSOR oldCursor = m_loadedCursor;
m_loadedCursor = newCursor;
if (m_cursor)
{
m_cursor = m_loadedCursor;
SetCursor(m_cursor);
}
if (oldCursor)
DestroyCursor(oldCursor);
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void WindowImplWin32::setKeyRepeatEnabled(bool enabled) void WindowImplWin32::setKeyRepeatEnabled(bool enabled)
{ {

View File

@ -153,6 +153,26 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void setMouseCursorGrabbed(bool grabbed); virtual void setMouseCursorGrabbed(bool grabbed);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to a native system cursor
///
/// \param cursor Native system cursor type to display
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(Window::Cursor cursor);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to the provided image
///
/// \param pixels Array of pixels of the image
/// \param width Width of the image
/// \param height Height of the image
/// \param hotspotX X location of the hotspot
/// \param hotspotY Y location of the hotspot
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat /// \brief Enable or disable automatic key-repeat
/// ///
@ -266,7 +286,8 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
HWND m_handle; ///< Win32 handle of the window HWND m_handle; ///< Win32 handle of the window
LONG_PTR m_callback; ///< Stores the original event callback function of the control LONG_PTR m_callback; ///< Stores the original event callback function of the control
HCURSOR m_cursor; ///< The system cursor to display into the window HCURSOR m_cursor; ///< The system cursor currently displayed into the window, NULL if hidden
HCURSOR m_loadedCursor; ///< The system cursor selected to be displayed into the window
HICON m_icon; ///< Custom icon assigned to the window HICON m_icon; ///< Custom icon assigned to the window
bool m_keyRepeatEnabled; ///< Automatic key-repeat state for keydown events bool m_keyRepeatEnabled; ///< Automatic key-repeat state for keydown events
Vector2u m_lastSize; ///< The last handled size of the window Vector2u m_lastSize; ///< The last handled size of the window

View File

@ -296,6 +296,22 @@ void Window::setMouseCursorGrabbed(bool grabbed)
} }
////////////////////////////////////////////////////////////
void Window::setMouseCursor(Cursor cursor)
{
if (m_impl)
m_impl->setMouseCursor(cursor);
}
////////////////////////////////////////////////////////////
void Window::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY)
{
if (m_impl && pixels && width && height)
m_impl->setMouseCursor(pixels, width, height, hotspotX, hotspotY);
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Window::setKeyRepeatEnabled(bool enabled) void Window::setKeyRepeatEnabled(bool enabled)
{ {

View File

@ -39,6 +39,7 @@
#include <SFML/Window/VideoMode.hpp> #include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/WindowHandle.hpp> #include <SFML/Window/WindowHandle.hpp>
#include <SFML/Window/ContextSettings.hpp> #include <SFML/Window/ContextSettings.hpp>
#include <SFML/Window/Window.hpp>
#include <queue> #include <queue>
#include <set> #include <set>
@ -194,6 +195,26 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void setMouseCursorGrabbed(bool grabbed) = 0; virtual void setMouseCursorGrabbed(bool grabbed) = 0;
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to a native system cursor
///
/// \param cursor Native system cursor type to display
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(Window::Cursor cursor) = 0;
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to the provided image
///
/// \param pixels Array of pixels of the image
/// \param width Width of the image
/// \param height Height of the image
/// \param hotspotX X location of the hotspot
/// \param hotspotY Y location of the hotspot
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY) = 0;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat /// \brief Enable or disable automatic key-repeat
/// ///

View File

@ -157,6 +157,26 @@ public:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void setMouseCursorGrabbed(bool grabbed); virtual void setMouseCursorGrabbed(bool grabbed);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to a native system cursor
///
/// \param cursor Native system cursor type to display
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(Window::Cursor cursor);
////////////////////////////////////////////////////////////
/// \brief Set the displayed cursor to the provided image
///
/// \param pixels Array of pixels of the image
/// \param width Width of the image
/// \param height Height of the image
/// \param hotspotX X location of the hotspot
/// \param hotspotY Y location of the hotspot
///
////////////////////////////////////////////////////////////
virtual void setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat /// \brief Enable or disable automatic key-repeat
/// ///

View File

@ -190,6 +190,20 @@ void WindowImplUIKit::setMouseCursorGrabbed(bool grabbed)
} }
////////////////////////////////////////////////////////////
void WindowImplUIKit::setMouseCursor(Window::Cursor cursor)
{
// Not applicable
}
////////////////////////////////////////////////////////////
void WindowImplUIKit::setMouseCursor(const Uint8* pixels, unsigned int width, unsigned int height, Uint16 hotspotX, Uint16 hotspotY)
{
// Not applicable
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void WindowImplUIKit::setKeyRepeatEnabled(bool enabled) void WindowImplUIKit::setKeyRepeatEnabled(bool enabled)
{ {