Nice!
However, you should use another namespace than sf for StandardCursor. Just to differentiate what is from SFML and what comes from addons. Also there are a few indentation issues : mixing tabs and spaces is usually no good.
Now the interesting comment begins :
Apple's cursor API is quite a mess. I did success to make it work but there is one big constraint (I really don't like it) ! You have to wait some amount of time (100 ms should be enough) before setting the cursor in the application otherwise it won't work.
Here is a sample code :
#include <SFML/Graphics.hpp>
#include "ResourcePath.hpp"
#include "ChangeCursor.h"
int main (int argc, const char * argv[])
{
// Create the main window
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
// Load a sprite to display
sf::Texture texture;
if (!texture.loadFromFile(resourcePath() + "cute_image.jpg"))
return EXIT_FAILURE;
sf::Sprite sprite(texture);
// Create a graphical text to display
sf::Font font;
if (!font.loadFromFile(resourcePath() + "sansation.ttf"))
return EXIT_FAILURE;
sf::Text text("Hello SFML", font, 50);
text.setColor(sf::Color::Black);
sf::Clock cursorClock;
bool cursorSet = false;
// Start the game loop
while (window.isOpen())
{
if (!cursorSet and cursorClock.getElapsedTime() > sf::microseconds(100)) {
ChangeCursor(window);
cursorSet = true;
}
// Process events
sf::Event event;
while (window.pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
window.close();
// Escape pressed : exit
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
window.close();
}
// Clear screen
window.clear();
// Draw the sprite
window.draw(sprite);
// Draw the string
window.draw(text);
// Update the window
window.display();
}
return EXIT_SUCCESS;
}
Note that if you don't use the cursorClock then it won't work and if you remove also boolean cursorSet and call each time ChangeCursor the application will be less responsive when you switch from one application to another and come back.
Here is my implementation :
#import "ChangeCursor.h"
#import <SFML/Window.hpp>
#import <Cocoa/Cocoa.h>
void ChangeCursor(sf::Window& window)
{
id handle = (id)window.getSystemHandle();
// Get the content view of the handle
NSView* view = nil;
if ([handle isKindOfClass:[NSView class]]) {
view = handle;
} else {
NSWindow* nswindow = handle;
view = nswindow.contentView;
}
NSCursor* defaultCursor = [NSCursor currentCursor];
NSCursor* cursor = [NSCursor pointingHandCursor];
NSRect rect = view.frame;
[view addCursorRect:rect cursor:cursor];
[cursor setOnMouseEntered:YES];
[view addCursorRect:rect cursor:defaultCursor];
[defaultCursor setOnMouseExited:YES];
NSPoint mousePositionInWindow = [[view window] mouseLocationOutsideOfEventStream];
NSPoint mousePositionInView = [view convertPoint:mousePositionInWindow
fromView:nil]; // i.e. from the window.
if ([view mouse:mousePositionInView inRect:view.frame]) {
[cursor set];
}
}
It's Objective-C++ so it must be inside a .mm file.
There is one known bug : when switching back to your application the cursor is not set back unless you put the cursor outside the window; then if you put the mouse in the window the cursor will be set as expected.