diff options
Diffstat (limited to 'Userland/Applications/Presenter/PresenterWidget.cpp')
-rw-r--r-- | Userland/Applications/Presenter/PresenterWidget.cpp | 79 |
1 files changed, 52 insertions, 27 deletions
diff --git a/Userland/Applications/Presenter/PresenterWidget.cpp b/Userland/Applications/Presenter/PresenterWidget.cpp index 652bdaacd4..66a6a5539b 100644 --- a/Userland/Applications/Presenter/PresenterWidget.cpp +++ b/Userland/Applications/Presenter/PresenterWidget.cpp @@ -1,12 +1,12 @@ /* * Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org> + * Copyright (c) 2023, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #include "PresenterWidget.h" #include "Presentation.h" -#include <AK/Format.h> #include <LibCore/MimeData.h> #include <LibFileSystemAccessClient/Client.h> #include <LibGUI/Action.h> @@ -15,13 +15,39 @@ #include <LibGUI/Menu.h> #include <LibGUI/MessageBox.h> #include <LibGUI/Painter.h> -#include <LibGUI/Window.h> -#include <LibGfx/Forward.h> -#include <LibGfx/Orientation.h> PresenterWidget::PresenterWidget() { set_min_size(100, 100); + set_fill_with_background_color(true); + m_web_view = add<WebView::OutOfProcessWebView>(); + m_web_view->set_frame_thickness(0); + m_web_view->set_scrollbars_enabled(false); + m_web_view->set_focus_policy(GUI::FocusPolicy::NoFocus); + m_web_view->set_content_scales_to_viewport(true); +} + +void PresenterWidget::resize_event(GUI::ResizeEvent& event) +{ + Widget::resize_event(event); + + if (!m_current_presentation) + return; + + auto normative_size = m_current_presentation->normative_size().to_type<float>(); + float widget_ratio = static_cast<float>(event.size().width()) / static_cast<float>(event.size().height()); + float wh_ratio = normative_size.width() / normative_size.height(); + + Gfx::IntRect rect; + if (widget_ratio >= wh_ratio) { + rect.set_width(static_cast<int>(ceilf(static_cast<float>(event.size().height()) * wh_ratio))); + rect.set_height(event.size().height()); + } else { + float hw_ratio = normative_size.height() / normative_size.width(); + rect.set_width(event.size().width()); + rect.set_height(static_cast<int>(ceilf(static_cast<float>(event.size().width()) * hw_ratio))); + } + m_web_view->set_relative_rect(rect.centered_within(this->rect())); } ErrorOr<void> PresenterWidget::initialize_menubar() @@ -44,15 +70,13 @@ ErrorOr<void> PresenterWidget::initialize_menubar() auto next_slide_action = GUI::Action::create("&Next", { KeyCode::Key_Right }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-forward.png"sv)), [this](auto&) { if (m_current_presentation) { m_current_presentation->next_frame(); - outln("Switched forward to slide {} frame {}", m_current_presentation->current_slide_number(), m_current_presentation->current_frame_in_slide_number()); - update(); + update_web_view(); } }); auto previous_slide_action = GUI::Action::create("&Previous", { KeyCode::Key_Left }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-back.png"sv)), [this](auto&) { if (m_current_presentation) { m_current_presentation->previous_frame(); - outln("Switched backward to slide {} frame {}", m_current_presentation->current_slide_number(), m_current_presentation->current_frame_in_slide_number()); - update(); + update_web_view(); } }); TRY(presentation_menu.try_add_action(next_slide_action)); @@ -64,25 +88,31 @@ ErrorOr<void> PresenterWidget::initialize_menubar() this->window()->set_fullscreen(true); }))); TRY(presentation_menu.try_add_action(GUI::Action::create("Present From First &Slide", { KeyCode::Key_F5 }, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/play.png"sv)), [this](auto&) { - if (m_current_presentation) + if (m_current_presentation) { m_current_presentation->go_to_first_slide(); + update_web_view(); + } this->window()->set_fullscreen(true); }))); return {}; } +void PresenterWidget::update_web_view() +{ + m_web_view->run_javascript(DeprecatedString::formatted("goto({}, {})", m_current_presentation->current_slide_number(), m_current_presentation->current_frame_in_slide_number())); +} + void PresenterWidget::set_file(StringView file_name) { - auto presentation = Presentation::load_from_file(file_name, *window()); + auto presentation = Presentation::load_from_file(file_name); if (presentation.is_error()) { GUI::MessageBox::show_error(window(), DeprecatedString::formatted("The presentation \"{}\" could not be loaded.\n{}", file_name, presentation.error())); } else { m_current_presentation = presentation.release_value(); window()->set_title(DeprecatedString::formatted(title_template, m_current_presentation->title(), m_current_presentation->author())); set_min_size(m_current_presentation->normative_size()); - // This will apply the new minimum size. - update(); + m_web_view->load_html(MUST(m_current_presentation->render()), "presenter://slide.html"sv); } } @@ -114,24 +144,19 @@ void PresenterWidget::keydown_event(GUI::KeyEvent& event) } } -void PresenterWidget::paint_event([[maybe_unused]] GUI::PaintEvent& event) +void PresenterWidget::paint_event(GUI::PaintEvent& event) +{ + GUI::Painter painter(*this); + painter.clear_rect(event.rect(), Gfx::Color::Black); +} + +void PresenterWidget::second_paint_event(GUI::PaintEvent& event) { if (!m_current_presentation) return; - auto normative_size = m_current_presentation->normative_size(); - // Choose an aspect-correct size which doesn't exceed actual widget dimensions. - auto width_corresponding_to_height = height() * normative_size.aspect_ratio(); - auto dimension_to_preserve = (width_corresponding_to_height > width()) ? Orientation::Horizontal : Orientation::Vertical; - auto display_size = size().match_aspect_ratio(normative_size.aspect_ratio(), dimension_to_preserve); - - GUI::Painter painter { *this }; - auto clip_rect = Gfx::IntRect::centered_at({ width() / 2, height() / 2 }, display_size); - painter.clear_clip_rect(); - // FIXME: This currently leaves a black border when the window aspect ratio doesn't match. - // Figure out a way to apply the background color here as well. - painter.add_clip_rect(clip_rect); - - m_current_presentation->paint(painter); + GUI::Painter painter(*this); + painter.add_clip_rect(event.rect()); + painter.draw_text(m_web_view->relative_rect(), m_current_presentation->current_slide().title(), Gfx::TextAlignment::BottomCenter); } void PresenterWidget::drag_enter_event(GUI::DragEvent& event) |