diff --git a/Userland/Applications/DisplaySettings/MonitorWidget.cpp b/Userland/Applications/DisplaySettings/MonitorWidget.cpp index a916cb5f66..4a7676c932 100644 --- a/Userland/Applications/DisplaySettings/MonitorWidget.cpp +++ b/Userland/Applications/DisplaySettings/MonitorWidget.cpp @@ -19,17 +19,21 @@ MonitorWidget::MonitorWidget() { m_desktop_resolution = GUI::Desktop::the().rect().size(); m_monitor_bitmap = Gfx::Bitmap::load_from_file("/res/graphics/monitor.png"); - m_monitor_rect = { 12, 13, 280, 158 }; + m_desktop_bitmap = Gfx::Bitmap::create(m_monitor_bitmap->format(), { 280, 158 }); + m_monitor_rect = { { 12, 13 }, m_desktop_bitmap->size() }; set_fixed_size(304, 201); } bool MonitorWidget::set_wallpaper(String path) { - auto bitmap_ptr = Gfx::Bitmap::load_from_file(path); - if (!bitmap_ptr && !path.is_empty()) + if (path.is_empty()) + return false; + auto bitmap = Gfx::Bitmap::load_from_file(path); + if (!bitmap) return false; m_desktop_wallpaper_path = move(path); - m_desktop_wallpaper_bitmap = bitmap_ptr; + m_wallpaper_bitmap = move(bitmap); + m_desktop_dirty = true; update(); return true; } @@ -44,6 +48,7 @@ void MonitorWidget::set_wallpaper_mode(String mode) if (m_desktop_wallpaper_mode == mode) return; m_desktop_wallpaper_mode = move(mode); + m_desktop_dirty = true; update(); } @@ -54,7 +59,11 @@ String MonitorWidget::wallpaper_mode() void MonitorWidget::set_desktop_resolution(Gfx::IntSize resolution) { + if (m_desktop_resolution == resolution) + return; m_desktop_resolution = resolution; + m_desktop_dirty = true; + update(); } Gfx::IntSize MonitorWidget::desktop_resolution() @@ -67,6 +76,7 @@ void MonitorWidget::set_background_color(Gfx::Color color) if (m_desktop_color == color) return; m_desktop_color = color; + m_desktop_dirty = true; update(); } @@ -75,33 +85,49 @@ Gfx::Color MonitorWidget::background_color() return m_desktop_color; } +void MonitorWidget::redraw_desktop_if_needed() +{ + if (!m_desktop_dirty) + return; + + m_desktop_dirty = false; + + GUI::Painter painter(*m_desktop_bitmap); + painter.fill_rect(m_desktop_bitmap->rect(), m_desktop_color); + + if (!m_wallpaper_bitmap) + return; + + float sw = (float)m_desktop_bitmap->width() / (float)m_desktop_resolution.width(); + float sh = (float)m_desktop_bitmap->height() / (float)m_desktop_resolution.height(); + + auto scaled_size = m_wallpaper_bitmap->size().to_type().scaled_by(sw, sh).to_type(); + auto scaled_bitmap = m_wallpaper_bitmap->scaled(sw, sh); + + if (m_desktop_wallpaper_mode == "simple") { + painter.blit({}, *scaled_bitmap, scaled_bitmap->rect()); + } else if (m_desktop_wallpaper_mode == "center") { + Gfx::IntRect centered_rect { {}, scaled_size }; + centered_rect.center_within(m_desktop_bitmap->rect()); + painter.blit(centered_rect.location(), *scaled_bitmap, scaled_bitmap->rect()); + } else if (m_desktop_wallpaper_mode == "tile") { + painter.draw_tiled_bitmap(m_desktop_bitmap->rect(), *scaled_bitmap); + } else if (m_desktop_wallpaper_mode == "stretch") { + painter.draw_scaled_bitmap(m_desktop_bitmap->rect(), *m_wallpaper_bitmap, m_wallpaper_bitmap->rect()); + } else { + VERIFY_NOT_REACHED(); + } +} + void MonitorWidget::paint_event(GUI::PaintEvent& event) { - Gfx::IntRect screen_rect = { { 0, 0 }, m_desktop_resolution }; - auto screen_bitmap = Gfx::Bitmap::create(m_monitor_bitmap->format(), m_desktop_resolution); - GUI::Painter screen_painter(*screen_bitmap); - screen_painter.fill_rect(screen_rect, m_desktop_color); - - if (!m_desktop_wallpaper_bitmap.is_null()) { - if (m_desktop_wallpaper_mode == "simple") { - screen_painter.blit({ 0, 0 }, *m_desktop_wallpaper_bitmap, m_desktop_wallpaper_bitmap->rect()); - } else if (m_desktop_wallpaper_mode == "center") { - Gfx::IntPoint offset { (screen_rect.width() - m_desktop_wallpaper_bitmap->width()) / 2, (screen_rect.height() - m_desktop_wallpaper_bitmap->height()) / 2 }; - screen_painter.blit_offset(screen_rect.location(), *m_desktop_wallpaper_bitmap, screen_rect, offset); - } else if (m_desktop_wallpaper_mode == "tile") { - screen_painter.draw_tiled_bitmap(screen_bitmap->rect(), *m_desktop_wallpaper_bitmap); - } else if (m_desktop_wallpaper_mode == "stretch") { - screen_painter.draw_scaled_bitmap(screen_bitmap->rect(), *m_desktop_wallpaper_bitmap, m_desktop_wallpaper_bitmap->rect()); - } else { - VERIFY_NOT_REACHED(); - } - } + redraw_desktop_if_needed(); GUI::Painter painter(*this); painter.add_clip_rect(event.rect()); painter.blit({ 0, 0 }, *m_monitor_bitmap, m_monitor_bitmap->rect()); - painter.draw_scaled_bitmap(m_monitor_rect, *screen_bitmap, screen_bitmap->rect()); + painter.blit(m_monitor_rect.location(), *m_desktop_bitmap, m_desktop_bitmap->rect()); #if 0 if (!m_desktop_resolution.is_null()) { diff --git a/Userland/Applications/DisplaySettings/MonitorWidget.h b/Userland/Applications/DisplaySettings/MonitorWidget.h index 1e9bbb7a8d..272eaa5156 100644 --- a/Userland/Applications/DisplaySettings/MonitorWidget.h +++ b/Userland/Applications/DisplaySettings/MonitorWidget.h @@ -32,13 +32,17 @@ public: private: MonitorWidget(); + void redraw_desktop_if_needed(); + virtual void paint_event(GUI::PaintEvent& event) override; Gfx::IntRect m_monitor_rect; RefPtr m_monitor_bitmap; + RefPtr m_desktop_bitmap; + bool m_desktop_dirty { true }; String m_desktop_wallpaper_path; - RefPtr m_desktop_wallpaper_bitmap; + RefPtr m_wallpaper_bitmap; String m_desktop_wallpaper_mode; Gfx::IntSize m_desktop_resolution; int m_desktop_scale_factor { 1 };