Serenity Operating System
at master 66 lines 2.7 kB view raw
1/* 2 * Copyright (c) 2022, MacDue <macdue@dueutil.tech> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include "HighlightPreviewWidget.h" 8#include <AK/DeprecatedString.h> 9#include <LibCore/ConfigFile.h> 10#include <LibGUI/ConnectionToWindowServer.h> 11#include <LibGUI/Painter.h> 12#include <LibGfx/AntiAliasingPainter.h> 13 14namespace MouseSettings { 15 16HighlightPreviewWidget::HighlightPreviewWidget(Gfx::Palette const& palette) 17 : GUI::AbstractThemePreview(palette) 18{ 19 (void)reload_cursor(); 20} 21 22ErrorOr<void> HighlightPreviewWidget::reload_cursor() 23{ 24 auto cursor_theme = GUI::ConnectionToWindowServer::the().get_cursor_theme(); 25 auto theme_path = DeprecatedString::formatted("/res/cursor-themes/{}/{}", cursor_theme, "Config.ini"); 26 auto cursor_theme_config = TRY(Core::ConfigFile::open(theme_path)); 27 auto load_bitmap = [](StringView path, StringView default_path) { 28 auto maybe_bitmap = Gfx::Bitmap::load_from_file(path); 29 if (!maybe_bitmap.is_error()) 30 return maybe_bitmap; 31 return Gfx::Bitmap::load_from_file(default_path); 32 }; 33 constexpr auto default_cursor_path = "/res/cursor-themes/Default/arrow.x2y2.png"sv; 34 auto cursor_path = DeprecatedString::formatted("/res/cursor-themes/{}/{}", 35 cursor_theme, cursor_theme_config->read_entry("Cursor", "Arrow")); 36 m_cursor_bitmap = TRY(load_bitmap(cursor_path, default_cursor_path)); 37 m_cursor_params = Gfx::CursorParams::parse_from_filename(cursor_path, m_cursor_bitmap->rect().center()).constrained(*m_cursor_bitmap); 38 // Setup cursor animation: 39 if (m_cursor_params.frames() > 1 && m_cursor_params.frame_ms() > 0) { 40 m_frame_timer = TRY(Core::Timer::create_repeating(m_cursor_params.frame_ms(), [&] { 41 m_cursor_frame = (m_cursor_frame + 1) % m_cursor_params.frames(); 42 update(); 43 })); 44 m_frame_timer->start(); 45 } else { 46 m_frame_timer = nullptr; 47 } 48 return {}; 49} 50 51void HighlightPreviewWidget::paint_preview(GUI::PaintEvent&) 52{ 53 GUI::Painter painter(*this); 54 Gfx::AntiAliasingPainter aa_painter { painter }; 55 Gfx::IntRect highlight_rect { 0, 0, m_radius * 2, m_radius * 2 }; 56 highlight_rect.center_within(frame_inner_rect()); 57 aa_painter.fill_ellipse(highlight_rect, m_color); 58 if (m_cursor_bitmap) { 59 auto cursor_rect = m_cursor_bitmap->rect(); 60 if (m_cursor_params.frames() > 1) 61 cursor_rect.set_width(cursor_rect.width() / m_cursor_params.frames()); 62 painter.blit(cursor_rect.centered_within(frame_inner_rect()).location(), *m_cursor_bitmap, cursor_rect.translated(m_cursor_frame * cursor_rect.width(), 0)); 63 } 64} 65 66}