Add more standard cursors
This adds standard cursors for diagonal resizing and operation-not-allowed.
This commit is contained in:
Родитель
396c05d2dd
Коммит
3d47dfb128
|
@ -118,6 +118,10 @@ information on what to include when reporting a bug.
|
|||
|
||||
## Changelog
|
||||
|
||||
- Added `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR`,
|
||||
`GLFW_RESIZE_ALL_CURSOR` and `GLFW_NOT_ALLOWED_CURSOR` standard cursors (#427)
|
||||
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
|
||||
- Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427)
|
||||
- Disabled tests and examples by default when built as a CMake subdirectory
|
||||
- Bugfix: The CMake config-file package used an absolute path and was not
|
||||
relocatable (#1470)
|
||||
|
|
|
@ -373,7 +373,7 @@ A cursor with a [standard shape](@ref shapes) from the current system cursor
|
|||
theme can be can be created with @ref glfwCreateStandardCursor.
|
||||
|
||||
@code
|
||||
GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
|
||||
GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_RESIZE_EW_CURSOR);
|
||||
@endcode
|
||||
|
||||
These cursor objects behave in the exact same way as those created with @ref
|
||||
|
|
|
@ -9,6 +9,18 @@
|
|||
|
||||
@subsection features_34 New features in version 3.4
|
||||
|
||||
@subsubsection standard_cursors_34 More standard cursors
|
||||
|
||||
GLFW now provides the standard cursors @ref GLFW_RESIZE_NWSE_CURSOR and @ref
|
||||
GLFW_RESIZE_NESW_CURSOR for diagonal resizing, @ref GLFW_RESIZE_ALL_CURSOR for
|
||||
omni-directional resizing and @ref GLFW_NOT_ALLOWED_CURSOR for showing an action
|
||||
is not allowed. The standard cursors for horizontal and vertical resizing are
|
||||
now referred to as @ref GLFW_RESIZE_EW_CURSOR and @ref GLFW_RESIZE_NS_CURSOR,
|
||||
but the older names are still available.
|
||||
|
||||
For more information see @ref cursor_standard.
|
||||
|
||||
|
||||
@subsection caveats_34 Caveats for version 3.4
|
||||
|
||||
@subsubsection standalone_34 Tests and examples are disabled when built as a sub-project
|
||||
|
@ -35,6 +47,13 @@ add_subdirectory(path/to/glfw)
|
|||
@subsubsection types_34 New types in version 3.4
|
||||
@subsubsection constants_34 New constants in version 3.4
|
||||
|
||||
- @ref GLFW_RESIZE_EW_CURSOR
|
||||
- @ref GLFW_RESIZE_NS_CURSOR
|
||||
- @ref GLFW_RESIZE_NWSE_CURSOR
|
||||
- @ref GLFW_RESIZE_NESW_CURSOR
|
||||
- @ref GLFW_RESIZE_ALL_CURSOR
|
||||
- @ref GLFW_NOT_ALLOWED_CURSOR
|
||||
|
||||
|
||||
@section news_33 Release notes for version 3.3
|
||||
|
||||
|
|
|
@ -1041,7 +1041,7 @@ extern "C" {
|
|||
|
||||
/*! @brief The regular arrow cursor shape.
|
||||
*
|
||||
* The regular arrow cursor.
|
||||
* The regular arrow cursor shape.
|
||||
*/
|
||||
#define GLFW_ARROW_CURSOR 0x00036001
|
||||
/*! @brief The text input I-beam cursor shape.
|
||||
|
@ -1049,26 +1049,48 @@ extern "C" {
|
|||
* The text input I-beam cursor shape.
|
||||
*/
|
||||
#define GLFW_IBEAM_CURSOR 0x00036002
|
||||
/*! @brief The crosshair shape.
|
||||
/*! @brief The crosshair cursor shape.
|
||||
*
|
||||
* The crosshair shape.
|
||||
* The crosshair cursor shape.
|
||||
*/
|
||||
#define GLFW_CROSSHAIR_CURSOR 0x00036003
|
||||
/*! @brief The hand shape.
|
||||
/*! @brief The pointing hand cursor shape.
|
||||
*
|
||||
* The hand shape.
|
||||
* The pointing hand cursor shape.
|
||||
*/
|
||||
#define GLFW_HAND_CURSOR 0x00036004
|
||||
/*! @brief The horizontal resize arrow shape.
|
||||
/*! @brief The horizontal resize/move arrow shape.
|
||||
*
|
||||
* The horizontal resize arrow shape.
|
||||
* The horizontal resize/move arrow shape.
|
||||
*/
|
||||
#define GLFW_HRESIZE_CURSOR 0x00036005
|
||||
/*! @brief The vertical resize arrow shape.
|
||||
#define GLFW_RESIZE_EW_CURSOR 0x00036005
|
||||
/*! @brief The vertical resize/move arrow shape.
|
||||
*
|
||||
* The vertical resize arrow shape.
|
||||
* The vertical resize arrow/move shape.
|
||||
*/
|
||||
#define GLFW_VRESIZE_CURSOR 0x00036006
|
||||
#define GLFW_RESIZE_NS_CURSOR 0x00036006
|
||||
/*! @brief The top-left to bottom-right diagonal resize/move arrow shape.
|
||||
*
|
||||
* The top-left to bottom-right diagonal resize/move arrow shape.
|
||||
*/
|
||||
#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
|
||||
/*! @brief The top-right to bottom-left diagonal resize/move arrow shape.
|
||||
*
|
||||
* The top-right to bottom-left diagonal resize arrow/move shape.
|
||||
*/
|
||||
#define GLFW_RESIZE_NESW_CURSOR 0x00036008
|
||||
/*! @brief The omni-directional resize/move cursor shape.
|
||||
*
|
||||
* The omni-directional resize cursor/move shape.
|
||||
*/
|
||||
#define GLFW_RESIZE_ALL_CURSOR 0x00036009
|
||||
/*! @brief The operation-not-allowed shape.
|
||||
*
|
||||
* The operation-not-allowed shape.
|
||||
*/
|
||||
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
|
||||
#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR
|
||||
#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR
|
||||
/*! @} */
|
||||
|
||||
#define GLFW_CONNECTED 0x00040001
|
||||
|
|
|
@ -1603,10 +1603,34 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|||
cursor->ns.object = [NSCursor crosshairCursor];
|
||||
else if (shape == GLFW_HAND_CURSOR)
|
||||
cursor->ns.object = [NSCursor pointingHandCursor];
|
||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
||||
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
cursor->ns.object = [NSCursor resizeLeftRightCursor];
|
||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
cursor->ns.object = [NSCursor resizeUpDownCursor];
|
||||
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||
{
|
||||
// HACK: Use a Cocoa-internal message
|
||||
if ([NSCursor respondsToSelector:@selector(_windowResizeNorthWestSouthEastCursor)])
|
||||
{
|
||||
id object = [NSCursor _windowResizeNorthWestSouthEastCursor];
|
||||
if ([object isKindOfClass:[NSCursor class]])
|
||||
cursor->ns.object = object;
|
||||
}
|
||||
}
|
||||
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||
{
|
||||
// HACK: Use a Cocoa-internal message
|
||||
if ([NSCursor respondsToSelector:@selector(_windowResizeNorthEastSouthWestCursor)])
|
||||
{
|
||||
id object = [NSCursor _windowResizeNorthEastSouthWestCursor];
|
||||
if ([object isKindOfClass:[NSCursor class]])
|
||||
cursor->ns.object = object;
|
||||
}
|
||||
}
|
||||
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||
cursor->ns.object = [NSCursor closedHandCursor];
|
||||
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||
cursor->ns.object = [NSCursor operationNotAllowedCursor];
|
||||
|
||||
if (!cursor->ns.object)
|
||||
{
|
||||
|
|
|
@ -758,8 +758,12 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
|
|||
shape != GLFW_IBEAM_CURSOR &&
|
||||
shape != GLFW_CROSSHAIR_CURSOR &&
|
||||
shape != GLFW_HAND_CURSOR &&
|
||||
shape != GLFW_HRESIZE_CURSOR &&
|
||||
shape != GLFW_VRESIZE_CURSOR)
|
||||
shape != GLFW_RESIZE_EW_CURSOR &&
|
||||
shape != GLFW_RESIZE_NS_CURSOR &&
|
||||
shape != GLFW_RESIZE_NWSE_CURSOR &&
|
||||
shape != GLFW_RESIZE_NESW_CURSOR &&
|
||||
shape != GLFW_RESIZE_ALL_CURSOR &&
|
||||
shape != GLFW_NOT_ALLOWED_CURSOR)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
|
||||
return NULL;
|
||||
|
|
|
@ -2057,12 +2057,23 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|||
id = OCR_CROSS;
|
||||
else if (shape == GLFW_HAND_CURSOR)
|
||||
id = OCR_HAND;
|
||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
||||
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
id = OCR_SIZEWE;
|
||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
id = OCR_SIZENS;
|
||||
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||
id = OCR_SIZENWSE;
|
||||
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||
id = OCR_SIZENESW;
|
||||
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||
id = OCR_SIZEALL;
|
||||
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||
id = OCR_NO;
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Unknown standard cursor");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
cursor->win32.handle = LoadImageW(NULL,
|
||||
MAKEINTRESOURCEW(id), IMAGE_CURSOR, 0, 0,
|
||||
|
|
|
@ -784,10 +784,18 @@ static char *translateCursorShape(int shape)
|
|||
return "crosshair";
|
||||
case GLFW_HAND_CURSOR:
|
||||
return "hand2";
|
||||
case GLFW_HRESIZE_CURSOR:
|
||||
case GLFW_RESIZE_EW_CURSOR:
|
||||
return "sb_h_double_arrow";
|
||||
case GLFW_VRESIZE_CURSOR:
|
||||
case GLFW_RESIZE_NS_CURSOR:
|
||||
return "sb_v_double_arrow";
|
||||
case GLFW_RESIZE_NWSE_CURSOR:
|
||||
return "nwse-resize";
|
||||
case GLFW_RESIZE_NESW_CURSOR:
|
||||
return "nesw-resize";
|
||||
case GLFW_RESIZE_ALL_CURSOR:
|
||||
return "all-scroll";
|
||||
case GLFW_NOT_ALLOWED_CURSOR:
|
||||
return "not-allowed";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -620,6 +620,12 @@ static GLFWbool initExtensions(void)
|
|||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
||||
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||
_glfw.x11.xcursor.GetTheme = (PFN_XcursorGetTheme)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetTheme");
|
||||
_glfw.x11.xcursor.GetDefaultSize = (PFN_XcursorGetDefaultSize)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetDefaultSize");
|
||||
_glfw.x11.xcursor.LibraryLoadImage = (PFN_XcursorLibraryLoadImage)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorLibraryLoadImage");
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
|
|
|
@ -85,9 +85,15 @@ typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
|
|||
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
|
||||
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
|
||||
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
|
||||
typedef char* (* PFN_XcursorGetTheme)(Display*);
|
||||
typedef int (* PFN_XcursorGetDefaultSize)(Display*);
|
||||
typedef XcursorImage* (* PFN_XcursorLibraryLoadImage)(const char*,const char*,int);
|
||||
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
|
||||
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
|
||||
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
|
||||
#define XcursorGetTheme _glfw.x11.xcursor.GetTheme
|
||||
#define XcursorGetDefaultSize _glfw.x11.xcursor.GetDefaultSize
|
||||
#define XcursorLibraryLoadImage _glfw.x11.xcursor.LibraryLoadImage
|
||||
|
||||
typedef Bool (* PFN_XineramaIsActive)(Display*);
|
||||
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
|
||||
|
@ -349,6 +355,9 @@ typedef struct _GLFWlibraryX11
|
|||
PFN_XcursorImageCreate ImageCreate;
|
||||
PFN_XcursorImageDestroy ImageDestroy;
|
||||
PFN_XcursorImageLoadCursor ImageLoadCursor;
|
||||
PFN_XcursorGetTheme GetTheme;
|
||||
PFN_XcursorGetDefaultSize GetDefaultSize;
|
||||
PFN_XcursorLibraryLoadImage LibraryLoadImage;
|
||||
} xcursor;
|
||||
|
||||
struct {
|
||||
|
|
|
@ -2833,29 +2833,74 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||
{
|
||||
int native = 0;
|
||||
if (_glfw.x11.xcursor.handle)
|
||||
{
|
||||
char* theme = XcursorGetTheme(_glfw.x11.display);
|
||||
if (theme)
|
||||
{
|
||||
const int size = XcursorGetDefaultSize(_glfw.x11.display);
|
||||
const char* name = NULL;
|
||||
|
||||
if (shape == GLFW_ARROW_CURSOR)
|
||||
native = XC_left_ptr;
|
||||
else if (shape == GLFW_IBEAM_CURSOR)
|
||||
native = XC_xterm;
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
native = XC_crosshair;
|
||||
else if (shape == GLFW_HAND_CURSOR)
|
||||
native = XC_hand2;
|
||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
||||
native = XC_sb_h_double_arrow;
|
||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
||||
native = XC_sb_v_double_arrow;
|
||||
else
|
||||
return GLFW_FALSE;
|
||||
if (shape == GLFW_ARROW_CURSOR)
|
||||
name = "default";
|
||||
else if (shape == GLFW_IBEAM_CURSOR)
|
||||
name = "text";
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
name = "crosshair";
|
||||
else if (shape == GLFW_HAND_CURSOR)
|
||||
name = "pointer";
|
||||
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
name = "ew-resize";
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
name = "ns-resize";
|
||||
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
|
||||
name = "nwse-resize";
|
||||
else if (shape == GLFW_RESIZE_NESW_CURSOR)
|
||||
name = "nesw-resize";
|
||||
else if (shape == GLFW_RESIZE_ALL_CURSOR)
|
||||
name = "all-scroll";
|
||||
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
|
||||
name = "not-allowed";
|
||||
|
||||
XcursorImage* image = XcursorLibraryLoadImage(name, theme, size);
|
||||
if (image)
|
||||
{
|
||||
cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, image);
|
||||
XcursorImageDestroy(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
|
||||
if (!cursor->x11.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to create standard cursor");
|
||||
return GLFW_FALSE;
|
||||
unsigned int native = 0;
|
||||
|
||||
if (shape == GLFW_ARROW_CURSOR)
|
||||
native = XC_left_ptr;
|
||||
else if (shape == GLFW_IBEAM_CURSOR)
|
||||
native = XC_xterm;
|
||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
||||
native = XC_crosshair;
|
||||
else if (shape == GLFW_HAND_CURSOR)
|
||||
native = XC_hand2;
|
||||
else if (shape == GLFW_RESIZE_EW_CURSOR)
|
||||
native = XC_sb_h_double_arrow;
|
||||
else if (shape == GLFW_RESIZE_NS_CURSOR)
|
||||
native = XC_sb_v_double_arrow;
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Standard cursor unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
|
||||
if (!cursor->x11.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to create standard cursor");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
|
|
|
@ -69,7 +69,7 @@ static int swap_interval = 1;
|
|||
static int wait_events = GLFW_TRUE;
|
||||
static int animate_cursor = GLFW_FALSE;
|
||||
static int track_cursor = GLFW_FALSE;
|
||||
static GLFWcursor* standard_cursors[6];
|
||||
static GLFWcursor* standard_cursors[9];
|
||||
static GLFWcursor* tracking_cursor = NULL;
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
|
@ -294,6 +294,18 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
|
|||
glfwSetCursor(window, standard_cursors[5]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_7:
|
||||
glfwSetCursor(window, standard_cursors[6]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_8:
|
||||
glfwSetCursor(window, standard_cursors[7]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_9:
|
||||
glfwSetCursor(window, standard_cursors[8]);
|
||||
break;
|
||||
|
||||
case GLFW_KEY_F11:
|
||||
case GLFW_KEY_ENTER:
|
||||
{
|
||||
|
@ -359,8 +371,11 @@ int main(void)
|
|||
GLFW_IBEAM_CURSOR,
|
||||
GLFW_CROSSHAIR_CURSOR,
|
||||
GLFW_HAND_CURSOR,
|
||||
GLFW_HRESIZE_CURSOR,
|
||||
GLFW_VRESIZE_CURSOR
|
||||
GLFW_RESIZE_EW_CURSOR,
|
||||
GLFW_RESIZE_NS_CURSOR,
|
||||
GLFW_RESIZE_NWSE_CURSOR,
|
||||
GLFW_RESIZE_NESW_CURSOR,
|
||||
GLFW_NOT_ALLOWED_CURSOR
|
||||
};
|
||||
|
||||
standard_cursors[i] = glfwCreateStandardCursor(shapes[i]);
|
||||
|
|
Загрузка…
Ссылка в новой задаче