Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Wiki] How to change your cursor  (Read 26284 times)

0 Members and 1 Guest are viewing this topic.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
[Wiki] How to change your cursor
« on: June 21, 2012, 04:54:03 pm »
I've added the 'How to change your cursor' tutorial to the GitHub wiki.

@Laurent: Can you change the title? I don't understand how to do it. My first '# Title' doesn't show up. :-\

It's partially based on the old tutorial (probably wirtten by TechRogue). But since the Windows code wasn't working for 64bit platform, I had to make small changes. Additionally I've restructered the class a bit.
I've also expanded the tutorial with the explenation on how to use only SFML functions to get your own cursor.
And finally I've added a demonstration that shows how both technique can be used.

Now the OS specific cursor change has been tested on Windows 7 64bit but at the moment I can't test it for the Linux enviroment. Could someone else try it and if it's not working try to find a workaround?

For the Mac platform I've no idea how to change things. Has anyone some experience in that section and maybe able to add it to the wiki? :)

I hope it will help some of you and feel free to correct my text/code.

Note: It's only for SFML 2!
« Last Edit: October 18, 2012, 03:39:35 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [Wiki] How to change your cursor
« Reply #1 on: June 21, 2012, 05:59:56 pm »
Quote
@Laurent: Can you change the title? I don't understand how to do it. My first '# Title' doesn't show up.
It looks like a bug. It works for other pages.
Laurent Gomila - SFML developer

Zinlibs

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Re: [Wiki] How to change your cursor
« Reply #2 on: June 21, 2012, 10:36:39 pm »
Thanks for the tuto, very helpful !
Zoost & Zoom libraries : An easy way to create and handle geometric objets, animate and use them for better graphics !

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: [Wiki] How to change your cursor
« Reply #3 on: June 22, 2012, 12:33:27 am »
It looks like a bug. It works for other pages.
An bug in GitHub! :o ;D

Thanks for the tuto, very helpful !
You're very welcome. ;)

Also check out my just published tutorial about how to use sf::View. I'll also publish it later in the wiki. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: [Wiki] How to change your cursor
« Reply #4 on: June 22, 2012, 11:26:39 am »
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.
SFML / OS X developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: [Wiki] How to change your cursor
« Reply #5 on: June 23, 2012, 01:40:18 am »
However, you should use another namespace than sf for StandardCursor. Just to differentiate what is from SFML and what comes from addons.
Yes I fully agree, but that's the code from the old tutorial. Maybe I'll change it. ;)

Also there are a few indentation issues : mixing tabs and spaces is usually no good.
Woops my bad. In the beginning had some problems with GitHub's formating system...

What's better tabs or spaces?

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.

Hmmm yeah that's not really nice, but then again you get sometimes some strange flickering with the mouse cursor on Windows.
Do you want to add it to the wiki or shall I do it?

Thanks alot! :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: [Wiki] How to change your cursor
« Reply #6 on: June 23, 2012, 07:47:14 am »
Spaces are better since they are always the same for everybody. (Depending on the environment tabs can be equivalent to 2/4/8/... spaces.)

I can finish the implementation later - exams first. So maybe around the 10th of July.
SFML / OS X developer

capz

  • Newbie
  • *
  • Posts: 29
    • View Profile
Re: [Wiki] How to change your cursor
« Reply #7 on: June 23, 2012, 02:49:13 pm »
Spaces are better since they are always the same for everybody. (Depending on the environment tabs can be equivalent to 2/4/8/... spaces.)
I beg to differ. At least with tabs, you can set the indentation width to your own liking, regardless of what other developers used. With spaces, you're forcing people that browse your code to use your specific indentation preference.

I prefer 4 spaces, i know people who prefer 8. should i be forced to have 4 and 8 mixed in my code because it contains some of their work? or have to convert / re-indent?  ???

Also, from reading over the obj-c code, all you're doing is changing the cursor to another system cursor, right? Is it even possible to change it to a user-supplied sprite? Just curious

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: [Wiki] How to change your cursor
« Reply #8 on: June 23, 2012, 02:57:11 pm »
I beg to differ. At least with tabs, you can set the indentation width to your own liking, regardless of what other developers used. With spaces, you're forcing people that browse your code to use your specific indentation preference.
I prefer 4 spaces, i know people who prefer 8. should i be forced to have 4 and 8 mixed in my code because it contains some of their work? or have to convert / re-indent?  ???
I guess it's not that hard to replace 4 spaces with a tab or 8 if needed, the other way around wouldn't be that hard either. The four space wide indention is afaik the most common one and will also be handled by best by the browser, thus I won't change it.

Also, from reading over the obj-c code, all you're doing is changing the cursor to another system cursor, right? Is it even possible to change it to a user-supplied sprite? Just curious
Have you even looked at the tutorial and not just the code posted here?

Hiura's obj-c code was only an addition to the tutorial for OS specific change of the standard cursor. If you want a non standard cursor, you'll either have to write your own OS specific code or use the hide-cursor-darw-sprite method explained in the tutorial...
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: [Wiki] How to change your cursor
« Reply #9 on: June 23, 2012, 03:04:09 pm »
Is it even possible to change it to a user-supplied sprite? Just curious

Yes, that's what I intend to do in the implementation later next month.



Quote
I beg to differ. At least with tabs, you can set the indentation width to your own liking, regardless of what other developers used. With spaces, you're forcing people that browse your code to use your specific indentation preference.

In a perfect world I would totally agree with you.

BUT : if you write something on two lines and need some specific alignment then you can't use tabs. It just won't work nicely if someone has tab=8spaces if you have tab=4spaces.

    NSPoint mousePositionInView = [view convertPoint:mousePositionInWindow
                                            fromView:nil]; // i.e. from the window.
 
SFML / OS X developer

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: [Wiki] How to change your cursor
« Reply #10 on: July 09, 2012, 04:53:31 pm »
Ok, here is the implementation : https://gist.github.com/3076898

What I did was :
  • use .mm implementation file in order to let the compile know that the code is written in Objective-C++; I can't do the same as you did for Linux and Windows (i.e. use one file for both and play with macro directives).
  • In the header I changed some #if defined to make it work on Mac OS X and the previously supported OSes.
  • In order to use TYPE as a field of the class I switched private & public in class declaration.
  • I substituted sf with sfp in order to make it clear that this code is an add-on and not part of SFML itself (you can of couse change sfp with whatever you want).

I let you update the wiki page.

I also have two suggestion for you :

First, instead of a class why not using a simple free function ? e.g. void sfp::ChangeCursor(Type type, sf::Window const& window) You could use a singleton object for implementation like this :
namespace /* anonymous */
{
    struct {
        #ifdef SFML_SYSTEM_WINDOWS
        // blabla
        :
        :
    } impl;
}
 

Secondly, you should probably add some license to your source file like we do with SFML.
SFML / OS X developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: [Wiki] How to change your cursor
« Reply #11 on: July 10, 2012, 12:03:35 am »
Great work! Will have a closer look later on and probably change a few things from the wiki to better integrate it. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
Re: [Wiki] How to change your cursor
« Reply #12 on: July 16, 2012, 12:33:43 am »
Wow nice tutorial. I really think the effort to make it is worth it :)

You deserve a cookie. here.