Refactor SDL2 cursor manipulation

This commit is contained in:
Nikita Lisitsa 2022-04-06 17:52:32 +03:00
parent 5c401d6d50
commit bbeb05f34e
4 changed files with 38 additions and 19 deletions

View file

@ -5,4 +5,4 @@ file(GLOB_RECURSE PSEMEK_SDL2_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "so
psemek_add_library(psemek-sdl2 ${PSEMEK_SDL2_HEADERS} ${PSEMEK_SDL2_SOURCES})
target_include_directories(psemek-sdl2 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(psemek-sdl2 PUBLIC psemek-log SDL2)
target_link_libraries(psemek-sdl2 PUBLIC psemek-log psemek-util SDL2)

View file

@ -5,13 +5,18 @@
namespace psemek::sdl2
{
enum class cursor_type
{
arrow,
beam,
hand,
};
struct cursor;
struct cursor_provider
{
virtual cursor const & arrow() const = 0;
virtual cursor const & beam() const = 0;
virtual cursor const & hand() const = 0;
virtual cursor const & get(cursor_type type) const = 0;
virtual ~cursor_provider() {}
};
@ -21,6 +26,6 @@ namespace psemek::sdl2
std::unique_ptr<cursor_provider> set_cursor_provider(std::unique_ptr<cursor_provider> new_provider);
cursor_provider const * get_cursor_provider();
void set_cursor(cursor const & c);
void set_cursor(cursor_type type);
}

View file

@ -1,5 +1,6 @@
#include <psemek/sdl2/cursor.hpp>
#include <psemek/log/log.hpp>
#include <psemek/util/enum.hpp>
#include <SDL2/SDL_mouse.h>
@ -25,7 +26,7 @@ namespace psemek::sdl2
struct cursor
{
cursor_ptr cursor;
std::unique_ptr<SDL_Cursor, cursor_deleter> cursor;
};
namespace
@ -49,9 +50,17 @@ namespace psemek::sdl2
hand_.cursor.reset(create_system_cursor(SDL_SYSTEM_CURSOR_HAND));
}
cursor const & arrow() const override { return arrow_; }
cursor const & beam() const override { return beam_; }
cursor const & hand() const override { return hand_; }
cursor const & get(cursor_type type) const override
{
switch (type)
{
case cursor_type::arrow: return arrow_;
case cursor_type::beam: return beam_;
case cursor_type::hand: return hand_;
}
throw util::unknown_enum_value_exception<cursor_type>(type);
}
private:
cursor arrow_;
@ -76,15 +85,20 @@ namespace psemek::sdl2
cursor_provider const * get_cursor_provider()
{
static system_cursor_provider_impl const fallback;
if (!current_provider)
return &fallback;
return current_provider.get();
static std::unique_ptr<cursor_provider> fallback;
if (current_provider)
return current_provider.get();
if (!fallback)
fallback = system_cursor_provider();
return fallback.get();
}
void set_cursor(cursor const & c)
void set_cursor(cursor_type type)
{
SDL_SetCursor(c.cursor.get());
SDL_SetCursor(get_cursor_provider()->get(type).cursor.get());
}

View file

@ -98,21 +98,21 @@ namespace psemek::ui
if (mouseover)
{
state_ = state_t::mouseover;
sdl2::set_cursor(sdl2::get_cursor_provider()->beam());
sdl2::set_cursor(sdl2::cursor_type::beam);
}
break;
case state_t::mouseover:
if (!mouseover)
{
state_ = state_t::normal;
sdl2::set_cursor(sdl2::get_cursor_provider()->arrow());
sdl2::set_cursor(sdl2::cursor_type::arrow);
}
break;
case state_t::editing:
if (mouseover)
sdl2::set_cursor(sdl2::get_cursor_provider()->beam());
sdl2::set_cursor(sdl2::cursor_type::beam);
else
sdl2::set_cursor(sdl2::get_cursor_provider()->arrow());
sdl2::set_cursor(sdl2::cursor_type::arrow);
break;
}