Implemented methods to set the displayed cursor to a system cursor type or custom bitmap image.
This commit is contained in:
parent
bd479c4454
commit
6f5a7d1b1b
@ -56,6 +56,29 @@ class Event;
|
||||
////////////////////////////////////////////////////////////
|
||||
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:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -361,6 +384,43 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -154,6 +154,26 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
|
@ -321,6 +321,26 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -25,8 +25,8 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// 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/WindowImplX11.hpp>
|
||||
#include <SFML/Window/Unix/Display.hpp>
|
||||
#include <SFML/System/Mutex.hpp>
|
||||
#include <SFML/System/Lock.hpp>
|
||||
|
@ -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)
|
||||
{
|
||||
@ -1306,9 +1550,6 @@ void WindowImplX11::initialize()
|
||||
// Raise the window and grab input focus
|
||||
grabFocus();
|
||||
|
||||
// Create the hidden cursor
|
||||
createHiddenCursor();
|
||||
|
||||
// Flush the commands queue
|
||||
XFlush(m_display);
|
||||
|
||||
|
@ -154,6 +154,26 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
@ -233,12 +253,6 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
void initialize();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a transparent mouse cursor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void createHiddenCursor();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Cleanup graphical resources attached to the window
|
||||
///
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <SFML/System/Err.hpp>
|
||||
#include <SFML/System/Utf.hpp>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
// MinGW lacks the definition of some Win32 constants
|
||||
#ifndef XBUTTON1
|
||||
@ -132,6 +133,7 @@ WindowImplWin32::WindowImplWin32(WindowHandle handle) :
|
||||
m_handle (handle),
|
||||
m_callback (0),
|
||||
m_cursor (NULL),
|
||||
m_loadedCursor (NULL),
|
||||
m_icon (NULL),
|
||||
m_keyRepeatEnabled(true),
|
||||
m_lastSize (0, 0),
|
||||
@ -164,6 +166,7 @@ WindowImplWin32::WindowImplWin32(VideoMode mode, const String& title, Uint32 sty
|
||||
m_handle (NULL),
|
||||
m_callback (0),
|
||||
m_cursor (NULL),
|
||||
m_loadedCursor (NULL),
|
||||
m_icon (NULL),
|
||||
m_keyRepeatEnabled(true),
|
||||
m_lastSize (mode.width, mode.height),
|
||||
@ -238,6 +241,10 @@ m_cursorGrabbed (m_fullscreen)
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplWin32::~WindowImplWin32()
|
||||
{
|
||||
// Destroy the cursor
|
||||
if (m_loadedCursor)
|
||||
DestroyCursor(m_loadedCursor);
|
||||
|
||||
// Destroy the custom icon, if any
|
||||
if (m_icon)
|
||||
DestroyIcon(m_icon);
|
||||
@ -389,8 +396,12 @@ void WindowImplWin32::setVisible(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)
|
||||
m_cursor = LoadCursorW(NULL, IDC_ARROW);
|
||||
m_cursor = m_loadedCursor;
|
||||
else
|
||||
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)
|
||||
{
|
||||
|
@ -153,6 +153,26 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
@ -266,7 +286,8 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
HWND m_handle; ///< Win32 handle of the window
|
||||
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
|
||||
bool m_keyRepeatEnabled; ///< Automatic key-repeat state for keydown events
|
||||
Vector2u m_lastSize; ///< The last handled size of the window
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <SFML/Window/VideoMode.hpp>
|
||||
#include <SFML/Window/WindowHandle.hpp>
|
||||
#include <SFML/Window/ContextSettings.hpp>
|
||||
#include <SFML/Window/Window.hpp>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
@ -194,6 +195,26 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
|
@ -157,6 +157,26 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user