27 #include <boost/logic/tribool.hpp>
29 #include <SDL2/SDL_events.h>
30 #include <SDL2/SDL_mouse.h>
49 using cursor_ptr = std::unique_ptr<SDL_Cursor, void(*)(SDL_Cursor*)>;
50 cursor_ptr
cursor{
nullptr, SDL_FreeCursor};
57 auto available_cursors = std::array
60 cursor_data{
"normal.png",
"normal.png", 0, 0 },
61 cursor_data{
"wait-alt.png",
"wait.png", 0, 0 },
62 cursor_data{
"ibeam.png",
"ibeam.png", 14, 14 },
63 cursor_data{
"move.png",
"move.png", 0, 0 },
64 cursor_data{
"attack.png",
"attack.png", 0, 0 },
65 cursor_data{
"select.png",
"select.png", 0, 0 },
66 cursor_data{
"move_drag_alt.png",
"move_drag.png", 2, 20 },
67 cursor_data{
"attack_drag_alt.png",
"attack_drag.png", 3, 22 },
68 cursor_data{
"no_cursor.png",
"", 0, 0 }
70 cursor_data{
"normal.png",
"normal.png", 0, 0 },
71 cursor_data{
"wait.png",
"wait.png", 0, 0 },
72 cursor_data{
"ibeam.png",
"ibeam.png", 14, 14 },
73 cursor_data{
"move.png",
"move.png", 0, 0 },
74 cursor_data{
"attack.png",
"attack.png", 0, 0 },
75 cursor_data{
"select.png",
"select.png", 0, 0 },
76 cursor_data{
"move_drag.png",
"move_drag.png", 2, 20 },
77 cursor_data{
"attack_drag.png",
"attack_drag.png", 3, 22 },
78 cursor_data{
"no_cursor.png",
"", 0, 0 }
85 bool have_focus =
true;
87 bool use_color_cursors()
101 std::size_t cursor_width = 16;
103 std::size_t cursor_width =
surf->w;
104 if((cursor_width % 8) != 0) {
105 cursor_width += 8 - (cursor_width % 8);
109 std::vector<uint8_t>
data((cursor_width *
surf->h) / 8, 0);
110 std::vector<uint8_t> mask(
data.size(), 0);
117 for(
int y = 0; y !=
surf->h; ++y) {
118 for(
int x = 0; x !=
surf->w; ++x) {
119 if(
static_cast<std::size_t
>(x) < cursor_width) {
121 SDL_GetRGBA(pixels[y *
surf->w + x],
surf->format, &r, &
g, &
b, &a);
123 const std::size_t
index = y * cursor_width + x;
124 const std::size_t shift = 7 - (
index % 8);
126 const uint8_t trans = (a < 128 ? 0 : 1) << shift;
127 const uint8_t black = (trans == 0 || (r +
g +
b) / 3 > 128 ? 0 : 1) << shift;
130 mask[
index / 8] |= trans;
135 return SDL_CreateCursor(&
data[0], &mask[0], cursor_width,
surf->h, 0, 0);
140 const bool use_color = use_color_cursors();
141 cursor_data&
data = available_cursors[
type];
143 if(
data.cursor ==
nullptr || boost::indeterminate(
data.is_color) ||
data.is_color != use_color) {
144 static const std::string color_prefix =
"cursors/";
145 static const std::string bw_prefix =
"cursors-bw/";
152 data.cursor.reset(create_cursor(
surf));
155 data.is_color = use_color;
158 return data.cursor.get();
176 current_cursor =
type;
183 SDL_SetCursor(get_cursor(current_cursor));
188 switch(current_cursor) {
208 return current_cursor;
221 : old_(current_cursor)
Helper class for pinning SDL surfaces into memory.
void set_dragging(bool drag)
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
void set_focus(bool focus)
surface get_surface(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image surface suitable for software manipulation.
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.