LibGUI/WindowServer: Allow custom cursor origin
This commit is contained in:
parent
4801fd3e67
commit
7a66eb44d4
|
|
@ -201,11 +201,13 @@ namespace LibGUI
|
||||||
set_attributes(attributes);
|
set_attributes(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::set_cursor(uint32_t width, uint32_t height, BAN::Span<uint32_t> pixels)
|
void Window::set_cursor(uint32_t width, uint32_t height, BAN::Span<const uint32_t> pixels, int32_t origin_x, int32_t origin_y)
|
||||||
{
|
{
|
||||||
WindowPacket::WindowSetCursor packet;
|
WindowPacket::WindowSetCursor packet;
|
||||||
packet.width = width;
|
packet.width = width;
|
||||||
packet.height = height;
|
packet.height = height;
|
||||||
|
packet.origin_x = origin_x;
|
||||||
|
packet.origin_y = origin_y;
|
||||||
MUST(packet.pixels.resize(pixels.size()));
|
MUST(packet.pixels.resize(pixels.size()));
|
||||||
for (size_t i = 0; i < packet.pixels.size(); i++)
|
for (size_t i = 0; i < packet.pixels.size(); i++)
|
||||||
packet.pixels[i] = pixels[i];
|
packet.pixels[i] = pixels[i];
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#define FOR_EACH_4(macro, type, name, ...) macro(type, name) FOR_EACH_2(macro, __VA_ARGS__)
|
#define FOR_EACH_4(macro, type, name, ...) macro(type, name) FOR_EACH_2(macro, __VA_ARGS__)
|
||||||
#define FOR_EACH_6(macro, type, name, ...) macro(type, name) FOR_EACH_4(macro, __VA_ARGS__)
|
#define FOR_EACH_6(macro, type, name, ...) macro(type, name) FOR_EACH_4(macro, __VA_ARGS__)
|
||||||
#define FOR_EACH_8(macro, type, name, ...) macro(type, name) FOR_EACH_6(macro, __VA_ARGS__)
|
#define FOR_EACH_8(macro, type, name, ...) macro(type, name) FOR_EACH_6(macro, __VA_ARGS__)
|
||||||
|
#define FOR_EACH_10(macro, type, name, ...) macro(type, name) FOR_EACH_8(macro, __VA_ARGS__)
|
||||||
|
|
||||||
#define CONCATENATE_2(arg1, arg2) arg1 ## arg2
|
#define CONCATENATE_2(arg1, arg2) arg1 ## arg2
|
||||||
#define CONCATENATE_1(arg1, arg2) CONCATENATE_2(arg1, arg2)
|
#define CONCATENATE_1(arg1, arg2) CONCATENATE_2(arg1, arg2)
|
||||||
|
|
@ -22,8 +23,8 @@
|
||||||
|
|
||||||
#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__ __VA_OPT__(,) FOR_EACH_RSEQ_N())
|
#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__ __VA_OPT__(,) FOR_EACH_RSEQ_N())
|
||||||
#define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__)
|
#define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__)
|
||||||
#define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
|
#define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
|
||||||
#define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
|
#define FOR_EACH_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||||
|
|
||||||
#define FOR_EACH_(N, what, ...) CONCATENATE(FOR_EACH_, N)(what __VA_OPT__(,) __VA_ARGS__)
|
#define FOR_EACH_(N, what, ...) CONCATENATE(FOR_EACH_, N)(what __VA_OPT__(,) __VA_ARGS__)
|
||||||
#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what __VA_OPT__(,) __VA_ARGS__)
|
#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what __VA_OPT__(,) __VA_ARGS__)
|
||||||
|
|
@ -303,6 +304,8 @@ namespace LibGUI
|
||||||
WindowSetCursor,
|
WindowSetCursor,
|
||||||
uint32_t, width,
|
uint32_t, width,
|
||||||
uint32_t, height,
|
uint32_t, height,
|
||||||
|
int32_t, origin_x,
|
||||||
|
int32_t, origin_y,
|
||||||
BAN::Vector<uint32_t>, pixels
|
BAN::Vector<uint32_t>, pixels
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ namespace LibGUI
|
||||||
void set_position(int32_t x, int32_t y);
|
void set_position(int32_t x, int32_t y);
|
||||||
|
|
||||||
void set_cursor_visible(bool visible);
|
void set_cursor_visible(bool visible);
|
||||||
void set_cursor(uint32_t width, uint32_t height, BAN::Span<uint32_t> pixels);
|
void set_cursor(uint32_t width, uint32_t height, BAN::Span<const uint32_t> pixels, int32_t origin_x = 0, int32_t origin_y = 0);
|
||||||
|
|
||||||
Attributes get_attributes() const { return m_attributes; }
|
Attributes get_attributes() const { return m_attributes; }
|
||||||
void set_attributes(Attributes attributes);
|
void set_attributes(Attributes attributes);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ public:
|
||||||
{
|
{
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
|
int32_t origin_x;
|
||||||
|
int32_t origin_y;
|
||||||
BAN::Vector<uint32_t> pixels;
|
BAN::Vector<uint32_t> pixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -387,6 +387,8 @@ void WindowServer::on_window_set_cursor(int fd, const LibGUI::WindowPacket::Wind
|
||||||
Window::Cursor cursor;
|
Window::Cursor cursor;
|
||||||
cursor.width = packet.width;
|
cursor.width = packet.width;
|
||||||
cursor.height = packet.height;
|
cursor.height = packet.height;
|
||||||
|
cursor.origin_x = packet.origin_x;
|
||||||
|
cursor.origin_y = packet.origin_y;
|
||||||
if (auto ret = cursor.pixels.resize(packet.pixels.size()); ret.is_error())
|
if (auto ret = cursor.pixels.resize(packet.pixels.size()); ret.is_error())
|
||||||
{
|
{
|
||||||
dwarnln("failed to set cursor: {}", ret.error());
|
dwarnln("failed to set cursor: {}", ret.error());
|
||||||
|
|
@ -1179,12 +1181,15 @@ void WindowServer::invalidate_impl(Rectangle area)
|
||||||
{
|
{
|
||||||
if (const auto overlap = cursor_area().get_overlap(area); overlap.has_value())
|
if (const auto overlap = cursor_area().get_overlap(area); overlap.has_value())
|
||||||
{
|
{
|
||||||
|
const int32_t origin_x = window_cursor ? window_cursor->origin_x : 0;
|
||||||
|
const int32_t origin_y = window_cursor ? window_cursor->origin_y : 0;
|
||||||
|
|
||||||
for (int32_t y_off = 0; y_off < overlap->height; y_off++)
|
for (int32_t y_off = 0; y_off < overlap->height; y_off++)
|
||||||
{
|
{
|
||||||
for (int32_t x_off = 0; x_off < overlap->width; x_off++)
|
for (int32_t x_off = 0; x_off < overlap->width; x_off++)
|
||||||
{
|
{
|
||||||
const int32_t rel_x = overlap->x - m_cursor.x + x_off;
|
const int32_t rel_x = overlap->x - m_cursor.x + x_off + origin_x;
|
||||||
const int32_t rel_y = overlap->y - m_cursor.y + y_off;
|
const int32_t rel_y = overlap->y - m_cursor.y + y_off + origin_y;
|
||||||
const auto pixel = get_cursor_pixel(rel_x, rel_y);
|
const auto pixel = get_cursor_pixel(rel_x, rel_y);
|
||||||
if (pixel.has_value())
|
if (pixel.has_value())
|
||||||
m_framebuffer.pixels[(overlap->y + y_off) * m_framebuffer.width + (overlap->x + x_off)] = pixel.value();
|
m_framebuffer.pixels[(overlap->y + y_off) * m_framebuffer.width + (overlap->x + x_off)] = pixel.value();
|
||||||
|
|
@ -1248,6 +1253,9 @@ Rectangle WindowServer::cursor_area() const
|
||||||
int32_t width = s_default_cursor_width;
|
int32_t width = s_default_cursor_width;
|
||||||
int32_t height = s_default_cursor_height;
|
int32_t height = s_default_cursor_height;
|
||||||
|
|
||||||
|
int32_t origin_x = 0;
|
||||||
|
int32_t origin_y = 0;
|
||||||
|
|
||||||
if (auto window = find_hovered_window())
|
if (auto window = find_hovered_window())
|
||||||
{
|
{
|
||||||
if (!window->get_attributes().cursor_visible)
|
if (!window->get_attributes().cursor_visible)
|
||||||
|
|
@ -1256,10 +1264,12 @@ Rectangle WindowServer::cursor_area() const
|
||||||
{
|
{
|
||||||
width = window->cursor().width;
|
width = window->cursor().width;
|
||||||
height = window->cursor().height;
|
height = window->cursor().height;
|
||||||
|
origin_x = window->cursor().origin_x;
|
||||||
|
origin_y = window->cursor().origin_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { m_cursor.x, m_cursor.y, width, height };
|
return { m_cursor.x - origin_x, m_cursor.y - origin_y, width, height };
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle WindowServer::resize_area(Position cursor) const
|
Rectangle WindowServer::resize_area(Position cursor) const
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue