2.9.16
Coherent GT
A modern user interface library for games
Changing the mouse cursor

Since Coherent GT does not control the mouse cursor, it cannot change it. However, it can conveniently tell you when the cursor needs to be changed (i.e. the mouse is over a text box) and then it is up to your application to render the new cursor.

To do so, override Coherent::UIGT::ViewListener::OnCursorChanged in your ViewListener and inspect the value of the cursor argument. To see all possible values, see Coherent::UIGT::CursorType.

Your handler will be executed whenever the mouse enters an element whose cursor CSS property differs from the current one.

Image cursors

Coherent GT does not support setting the CSS cursor property to an URL. To show an image cursor, you need to use one of the predefined values and have your C++ code load an image instead. On Windows for example, you can load the cursor foo.cur using:

g_ActiveCursor = LoadCursorFromFile("foo.cur");

Example implementations

Modern operating systems have several cursors installed by default and the following code snippets show you how to use them in GT. Note that not every HTML5 cursor has a corresponding cursor in the OS by default.

Windows

On Windows cursor management is done via the pair of methods LoadCursor and SetCursor Although it might just work if you set the cursor at random time in your main loop, it is suggested that you do so when the message WM_SETCURSOR is handled. Here's the relevant code:

HCURSOR g_ActiveCursor = 0;
...
LRESULT PlatformWindow::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    ...
    case WM_SETCURSOR:
        SetCursor(g_ActiveCursor);
    break;
    }
}
...
class CustomViewListener : public Coherent::UIGT::ViewListener
{
    virtual void OnCursorChanged(Coherent::UIGT::CursorType cursor) override
    {
        using namespace Coherent::UIGT;
        LPCTSTR winCursor = IDC_ARROW;
        switch (cursor)
        {
        case CT_TypeIBeam:
            winCursor = IDC_IBEAM;
        break;
        case CT_TypeWait:
            winCursor = IDC_WAIT;
        break;
        case CT_TypeCross:
            winCursor = IDC_CROSS;
        break;
        case CT_TypeNorthResize:
            winCursor = IDC_UPARROW;
        break;
        case CT_TypeNorthSouthResize:
            winCursor = IDC_SIZENS;
        break;
        case CT_TypeNorthWestSouthEastResize:
            winCursor = IDC_SIZENWSE;
        break;
        case CT_TypeNorthEastSouthWestResize:
            winCursor = IDC_SIZENESW;
        break;
        case CT_TypeEastWestResize:
            winCursor = IDC_SIZEWE;
        break;
        case CT_TypeMove:
            winCursor = IDC_SIZEALL;
        break;
        case CT_TypeNotAllowed:
            winCursor = IDC_NO;
        break;
        case CT_TypeHand:
            winCursor = IDC_HAND;
        break;
        case CT_TypeProgress:
            winCursor = IDC_APPSTARTING;
        break;
        case CT_TypeHelp:
            winCursor = IDC_HELP;
        break;
        }
        g_ActiveCursor = LoadCursor(nullptr, winCursor);
    }
};

Mac

NSCursor* g_ActiveCursor = nullptr;
...
class CustomViewListener : public Coherent::UIGT::ViewListener
{
    virtual void OnCursorChanged(Coherent::UIGT::CursorType cursor) override
    {
        if (g_ActiveCursor)
        {
            [g_ActiveCursor release];
            g_ActiveCursor = nullptr;
        }
        switch (cursor)
        {
        case CT_TypeHand:
            g_ActiveCursor = [NSCursor pointingHandCursor];
        break;
        case CT_TypeMove:
            g_ActiveCursor = [NSCursor dragLinkCursor];
        break;
        case CT_TypeCopy:
            g_ActiveCursor = [NSCursor dragCopyCursor];
        break;
        case CT_TypeIBeam:
            g_ActiveCursor = [NSCursor IBeamCursor];
        break;
        case CT_TypeVerticalText:
            g_ActiveCursor = [NSCursor IBeamCursorForVerticalText];
        break;
        case CT_TypeEastResize:
            g_ActiveCursor = [NSCursor resizeRightCursor];
        break;
        case CT_TypeNorthResize:
            g_ActiveCursor = [NSCursor resizeUpCursor];
        break;
        case CT_TypeSouthResize:
            g_ActiveCursor = [NSCursor resizeDownCursor];
        break;
        case CT_TypeWestResize:
            g_ActiveCursor = [NSCursor resizeLeftCursor];
        break;
        case CT_TypeNorthSouthResize:
            g_ActiveCursor = [NSCursor resizeUpDownCursor];
        break;
        case CT_TypeEastWestResize:
            g_ActiveCursor = [NSCursor resizeLeftRightCursor];
        break;
        case CT_TypeCross:
            g_ActiveCursor = [NSCursor crosshairCursor];
        break;
        case CT_TypeNotAllowed:
            g_ActiveCursor = [NSCursor operationNotAllowedCursor];
        break;
        case CT_TypeGrab
            g_ActiveCursor = [NSCursor openHandCursor];
        break;
        case CT_TypeGrabbing:
            g_ActiveCursor = [NSCursor closedHandCursor];
        break;
        case CT_TypeContextMenu:
            g_ActiveCursor = [NSCursor contextualMenuCursor];
        break;
        default:
            g_ActiveCursor = [NSCursor arrowCursor];
        break;
        }
        [g_ActiveCursor set];
    }
}