This adds standard cursors for diagonal resizing and
operation-not-allowed.
This commit is contained in:
Camilla Löwy 2019-05-07 20:40:37 +02:00
Родитель 396c05d2dd
Коммит 3d47dfb128
12 изменённых файлов: 209 добавлений и 42 удалений

Просмотреть файл

@ -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]);