GithubHelp home page GithubHelp logo

sfml.mouseeventlistener's Introduction

SFML.MouseEventListener

Make SFML 3 shapes listen mouse event when cursor is in their boundary.

A working example

[Sample: ManyConvexes]

Screen.Recording.2023-02-07.at.5.22.13.PM.mov

How to add this library to my project?

This library is based on CMake. You can use FetchContent CMake script to add the library.

include(FetchContent)
FetchContent_Declare(SFML_MouseEventListener
        GIT_REPOSITORY https://github.com/stripe2933/SFML.MouseEventListener.git)
FetchContent_MakeAvailable(SFML_MouseEventListener)

target_link_libraries(${PROJECT_NAME} PUBLIC SFML_MouseEventListener)

Because the library has direct dependency from SFML, SFML would be automatically included to your project via find_package(SFML). You can set SFML_DIR CMake variable manually if the CMake system cannot find SFML.

How should I use it?

It supports sf::CircleShape, sf::RectangleShape, sf::ConvexShape and any custom combined boundary consists of circle, rectangle and convex polygon. For example, if you want to print message when clikcing sf::CircleShape,

  1. Make sf::CircleShape object.
sf::CircleShape circle { 24.f }; // Make a circle with radius=24.

// You can apply any affine transformation to the object.
circle.setPosition({ 200.f, 100.f });
circle.setScale({ 1.2f, 2.0f });
  1. Create MouseEventSystem which accepts mouse event from window and execute registered MouseEventListener.
// MouseEventSystem accept integer-vector(sf::Vector2f) from sf::Event.
// Since your object is not only positioned by float-vector, but also may inside your own created sf::View,
// the accepted int vector and real position of object may different.
// Therefore, You should register MouseEventSystem with coordination converter, which converts mouse position
// to actual object-coordinate position.
MouseEventSystem system { [&](sf::Vector2i position) { return window.mapPixelToCoords(position); } };

// Now you can register listener from target object. Create an ObjectBoundary with factory method `createBoundaryFrom`,
// and unique_ptr of MouseEventListener.
// The constructor of MouseEventListener has optional argument, z_index, which indicates the hit-test priority (higher 
// z-index means the object is in front of other objects), sets by 0. You can manually set it as what you want.
auto listener = std::make_unique<MouseEventListener>(circle, ObjectBoundary::createBoundaryFrom(circle));

// And register callback for sf::MouseButtonPressed. It will be executed when press mouse button.
listener->on_mouse_button_pressed = [&](auto &sender, const auto &event){
    // sender: MouseEventListener whose callback is executed.
    // event: sf::Event::MouseButtonEvent, which has button and cursor position.
    
    std::cout << "Mouse pressed on " << static_cast<void*>(&sender) << " at (" << event.x << ", " << event.y << ")\n";
};
    
// Register listener to system.
system.addListener(std::move(listener));
  1. Make MouseEventSystem listens sf::Event polled by window. Since only callback for mouse pressing is registered, it is only necessary for listen sf::Event::MouseButtonPressed event.
for (sf::Event event { }; window.pollEvent(event);) {
    switch (event.type) {
        case sf::Event::Closed:
            window.close();
            break;

        case sf::Event::MouseButtonPressed:
            system.executeMouseEvent<sf::Event::MouseButtonPressed>(event.mouseButton);
            break;
        
        // and any other event...
    }
}
  1. Now draw your objects and test if they print messages when clicking them. If you want to render objects by its z-index (so higher z-indexed object is in front of other), you can iterate system's listeners and render them. Listeners are always sorted with ascending z-index.
for (auto &listener : system.getListeners()){
    window.draw(*dynamic_cast<const sf::Drawable*>(&listener->target));
}

You can find more sample from ManyConvexes (make objects pannable using MouseEventListener) and Shapes (create an ObjectBoundary by combining multiple ObjectBoundarys to make non-regular shaped target be able to listen.)

sfml.mouseeventlistener's People

Contributors

stripe2933 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.