Make a nice bitmap cursor.

It's rendered as two CharacterBitmaps right now because I don't have a good
primitive for this and I wanted it right away. I should add 2-color bitmaps..

Also make a neat little effect where the cursor becomes inverted on press.
This commit is contained in:
Andreas Kling 2019-01-13 07:17:12 +01:00
parent 1d914cbd84
commit 8e96cba7ef
Notes: sideshowbarker 2024-07-19 16:03:08 +09:00
3 changed files with 56 additions and 8 deletions

View file

@ -60,7 +60,7 @@ void AbstractScreen::on_receive_mouse_data(int dx, int dy, bool left_button, boo
auto event = make<MouseEvent>(right_button ? Event::MouseDown : Event::MouseUp, m_cursor_location.x(), m_cursor_location.y(), MouseButton::Right);
EventLoop::main().postEvent(&WindowManager::the(), move(event));
}
if (m_cursor_location != prev_location)
if (m_cursor_location != prev_location || prev_left_button != left_button)
WindowManager::the().redraw_cursor();
}

View file

@ -64,6 +64,46 @@ void WindowManager::initialize()
s_the_window_manager = nullptr;
}
static const char* cursor_bitmap_inner_ascii = {
" # "
" ## "
" ### "
" #### "
" ##### "
" ###### "
" ####### "
" ######## "
" ######### "
" ########## "
" ###### "
" ## ## "
" # ## "
" ## "
" ## "
" ## "
" "
};
static const char* cursor_bitmap_outer_ascii = {
"## "
"# # "
"# # "
"# # "
"# # "
"# # "
"# # "
"# # "
"# # "
"# # "
"# #### "
"# ## # "
"# # # # "
"## # # "
" # # "
" # # "
" ## "
};
WindowManager::WindowManager()
: m_framebuffer(FrameBuffer::the())
, m_screen_rect(m_framebuffer.rect())
@ -79,6 +119,9 @@ WindowManager::WindowManager()
m_inactiveWindowBorderColor = Color(64, 64, 64);
m_inactiveWindowTitleColor = Color::White;
m_cursor_bitmap_inner = CharacterBitmap::createFromASCII(cursor_bitmap_inner_ascii, 12, 17);
m_cursor_bitmap_outer = CharacterBitmap::createFromASCII(cursor_bitmap_outer_ascii, 12, 17);
invalidate();
compose();
}
@ -260,16 +303,17 @@ void WindowManager::compose()
void WindowManager::redraw_cursor()
{
auto cursor_location = AbstractScreen::the().cursor_location();
auto cursor_location = m_framebuffer.cursor_location();
Painter painter(*m_front_bitmap);
Rect cursor_rect { cursor_location.x() - 10, cursor_location.y() - 10, 21, 21 };
Rect cursor_rect { cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() };
flush(m_last_cursor_rect);
flush(cursor_rect);
auto draw_cross = [&painter] (const Point& p) {
painter.draw_line({ p.x() - 10, p.y() }, { p.x() + 10, p.y() }, Color::Red);
painter.draw_line({ p.x(), p.y() - 10 }, { p.x(), p.y() + 10 }, Color::Red);
};
draw_cross(cursor_location);
Color inner_color = Color::White;
Color outer_color = Color::Black;
if (m_framebuffer.left_mouse_button_pressed())
swap(inner_color, outer_color);
painter.draw_bitmap(cursor_location, *m_cursor_bitmap_inner, inner_color);
painter.draw_bitmap(cursor_location, *m_cursor_bitmap_outer, outer_color);
m_last_cursor_rect = cursor_rect;
}

View file

@ -12,6 +12,7 @@ class MouseEvent;
class PaintEvent;
class Widget;
class Window;
class CharacterBitmap;
class GraphicsBitmap;
class WindowManager : public Object {
@ -85,4 +86,7 @@ private:
Vector<Rect> m_invalidated_rects;
bool m_pending_compose_event { false };
RetainPtr<CharacterBitmap> m_cursor_bitmap_inner;
RetainPtr<CharacterBitmap> m_cursor_bitmap_outer;
};