Support image-based cursors
This commit is contained in:
parent
284df5d92c
commit
88e48f2454
3 changed files with 68 additions and 1 deletions
|
|
@ -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})
|
psemek_add_library(psemek-sdl2 ${PSEMEK_SDL2_HEADERS} ${PSEMEK_SDL2_SOURCES})
|
||||||
target_include_directories(psemek-sdl2 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
target_include_directories(psemek-sdl2 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
target_link_libraries(psemek-sdl2 PUBLIC psemek-log psemek-util SDL2)
|
target_link_libraries(psemek-sdl2 PUBLIC psemek-log psemek-util psemek-gfx SDL2)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/gfx/pixmap.hpp>
|
||||||
|
#include <psemek/geom/point.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace psemek::sdl2
|
namespace psemek::sdl2
|
||||||
{
|
{
|
||||||
|
|
@ -21,7 +25,14 @@ namespace psemek::sdl2
|
||||||
virtual ~cursor_provider() {}
|
virtual ~cursor_provider() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct image_cursor_description
|
||||||
|
{
|
||||||
|
gfx::pixmap_rgba image;
|
||||||
|
geom::point<int, 2> pivot;
|
||||||
|
};
|
||||||
|
|
||||||
std::unique_ptr<cursor_provider> system_cursor_provider();
|
std::unique_ptr<cursor_provider> system_cursor_provider();
|
||||||
|
std::unique_ptr<cursor_provider> image_cursor_provider(std::function<image_cursor_description(cursor_type)> image_provider);
|
||||||
|
|
||||||
std::unique_ptr<cursor_provider> set_cursor_provider(std::unique_ptr<cursor_provider> new_provider);
|
std::unique_ptr<cursor_provider> set_cursor_provider(std::unique_ptr<cursor_provider> new_provider);
|
||||||
cursor_provider const * get_cursor_provider();
|
cursor_provider const * get_cursor_provider();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <psemek/sdl2/cursor.hpp>
|
#include <psemek/sdl2/cursor.hpp>
|
||||||
|
#include <psemek/sdl2/init.hpp>
|
||||||
#include <psemek/log/log.hpp>
|
#include <psemek/log/log.hpp>
|
||||||
#include <psemek/util/enum.hpp>
|
#include <psemek/util/enum.hpp>
|
||||||
|
|
||||||
|
|
@ -12,6 +13,14 @@ namespace psemek::sdl2
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct surface_deleter
|
||||||
|
{
|
||||||
|
void operator() (SDL_Surface * s) const
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct cursor_deleter
|
struct cursor_deleter
|
||||||
{
|
{
|
||||||
void operator() (SDL_Cursor * c) const
|
void operator() (SDL_Cursor * c) const
|
||||||
|
|
@ -20,6 +29,7 @@ namespace psemek::sdl2
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using surface_ptr = std::unique_ptr<SDL_Surface, surface_deleter>;
|
||||||
using cursor_ptr = std::unique_ptr<SDL_Cursor, cursor_deleter>;
|
using cursor_ptr = std::unique_ptr<SDL_Cursor, cursor_deleter>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +78,47 @@ namespace psemek::sdl2
|
||||||
cursor hand_;
|
cursor hand_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cursor_ptr create_image_cursor(image_cursor_description desc)
|
||||||
|
{
|
||||||
|
surface_ptr surface{SDL_CreateRGBSurfaceFrom(desc.image.data(), desc.image.width(), desc.image.height(), 32, 4 * desc.image.width(), 0x000000ffu, 0x0000ff00u, 0x00ff0000u, 0xff000000u)};
|
||||||
|
if (!surface)
|
||||||
|
fail("failed to create cursor surface: ");
|
||||||
|
|
||||||
|
cursor_ptr cursor{SDL_CreateColorCursor(surface.get(), desc.pivot[0], desc.pivot[1])};
|
||||||
|
if (!cursor)
|
||||||
|
fail("failed to create cursor: ");
|
||||||
|
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct image_cursor_provider_impl
|
||||||
|
: cursor_provider
|
||||||
|
{
|
||||||
|
image_cursor_provider_impl(std::function<image_cursor_description(cursor_type)> image_provider)
|
||||||
|
{
|
||||||
|
arrow_.cursor = create_image_cursor(image_provider(cursor_type::arrow));
|
||||||
|
beam_.cursor = create_image_cursor(image_provider(cursor_type::beam));
|
||||||
|
hand_.cursor = create_image_cursor(image_provider(cursor_type::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_;
|
||||||
|
cursor beam_;
|
||||||
|
cursor hand_;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cursor_provider> system_cursor_provider()
|
std::unique_ptr<cursor_provider> system_cursor_provider()
|
||||||
|
|
@ -75,6 +126,11 @@ namespace psemek::sdl2
|
||||||
return std::make_unique<system_cursor_provider_impl>();
|
return std::make_unique<system_cursor_provider_impl>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<cursor_provider> image_cursor_provider(std::function<image_cursor_description(cursor_type)> image_provider)
|
||||||
|
{
|
||||||
|
return std::make_unique<image_cursor_provider_impl>(std::move(image_provider));
|
||||||
|
}
|
||||||
|
|
||||||
static std::unique_ptr<cursor_provider> current_provider;
|
static std::unique_ptr<cursor_provider> current_provider;
|
||||||
|
|
||||||
std::unique_ptr<cursor_provider> set_cursor_provider(std::unique_ptr<cursor_provider> new_provider)
|
std::unique_ptr<cursor_provider> set_cursor_provider(std::unique_ptr<cursor_provider> new_provider)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue