From b9493ba783e833769e04b8276a42be8c18c98339 Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Wed, 25 Sep 2019 12:44:22 +0300 Subject: [PATCH] LibHTML: Introduce the HtmlView widget This is a GWidget that can display contents of an HTML document. It replaces the Frame class. --- Libraries/LibHTML/Frame.cpp | 41 ---------------- Libraries/LibHTML/Frame.h | 23 --------- Libraries/LibHTML/HtmlView.cpp | 80 +++++++++++++++++++++++++++++++ Libraries/LibHTML/HtmlView.h | 26 ++++++++++ Libraries/LibHTML/Makefile.shared | 2 +- Libraries/LibHTML/test.cpp | 17 +++++-- 6 files changed, 119 insertions(+), 70 deletions(-) delete mode 100644 Libraries/LibHTML/Frame.cpp delete mode 100644 Libraries/LibHTML/Frame.h create mode 100644 Libraries/LibHTML/HtmlView.cpp create mode 100644 Libraries/LibHTML/HtmlView.h diff --git a/Libraries/LibHTML/Frame.cpp b/Libraries/LibHTML/Frame.cpp deleted file mode 100644 index 7681fa3df17..00000000000 --- a/Libraries/LibHTML/Frame.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Frame::Frame() - : m_size(800, 600) -{ -} - -Frame::~Frame() -{ -} - -void Frame::set_document(Document* document) -{ - m_document = document; -} - -void Frame::layout() -{ - if (!m_document) - return; - - auto layout_root = m_document->create_layout_tree(m_document->style_resolver(), nullptr); - - layout_root->style().size().set_width(m_size.width()); - - printf("\033[33;1mLayout tree before layout:\033[0m\n"); - dump_tree(*layout_root); - - layout_root->layout(); - - printf("\033[33;1mLayout tree after layout:\033[0m\n"); - dump_tree(*layout_root); -} diff --git a/Libraries/LibHTML/Frame.h b/Libraries/LibHTML/Frame.h deleted file mode 100644 index 31b1bb6c9dd..00000000000 --- a/Libraries/LibHTML/Frame.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -class Frame { -public: - Frame(); - ~Frame(); - - Document* document() { return m_document.ptr(); } - const Document* document() const { return m_document.ptr(); } - - void set_document(Document*); - - void layout(); - -private: - RefPtr generate_layout_tree(); - - RefPtr m_document; - Size m_size; -}; diff --git a/Libraries/LibHTML/HtmlView.cpp b/Libraries/LibHTML/HtmlView.cpp new file mode 100644 index 00000000000..99bf2928076 --- /dev/null +++ b/Libraries/LibHTML/HtmlView.cpp @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include +#include + +HtmlView::HtmlView(GWidget* parent) + : GScrollableWidget(parent) +{ + set_frame_shape(FrameShape::Container); + set_frame_shadow(FrameShadow::Sunken); + set_frame_thickness(2); + set_should_hide_unnecessary_scrollbars(true); + set_background_color(Color::White); +} + +void HtmlView::set_document(Document* document) +{ + if (document == m_document) + return; + m_document = document; + + if (document == nullptr) + m_layout_root = nullptr; + else + m_layout_root = document->create_layout_tree(document->style_resolver(), nullptr); + +#ifdef HTML_DEBUG + if (document != nullptr) { + printf("\033[33;1mLayout tree before layout:\033[0m\n"); + ::dump_tree(*m_layout_root); + } +#endif + + layout_and_sync_size(); + update(); +} + +void HtmlView::layout_and_sync_size() +{ + if (!m_layout_root) + return; + + m_layout_root->style().size().set_width(available_size().width()); + m_layout_root->layout(); + set_content_size(m_layout_root->rect().size()); + +#ifdef HTML_DEBUG + printf("\033[33;1mLayout tree after layout:\033[0m\n"); + ::dump_tree(*m_layout_root); +#endif +} + +void HtmlView::resize_event(GResizeEvent& event) +{ + GScrollableWidget::resize_event(event); + layout_and_sync_size(); +} + +void HtmlView::paint_event(GPaintEvent& event) +{ + GFrame::paint_event(event); + + GPainter painter(*this); + painter.add_clip_rect(widget_inner_rect()); + painter.add_clip_rect(event.rect()); + + painter.fill_rect(event.rect(), background_color()); + + painter.translate(frame_thickness(), frame_thickness()); + painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value()); + + if (!m_layout_root) + return; + + RenderingContext context { painter }; + m_layout_root->render(context); +} diff --git a/Libraries/LibHTML/HtmlView.h b/Libraries/LibHTML/HtmlView.h new file mode 100644 index 00000000000..8d04f738fe1 --- /dev/null +++ b/Libraries/LibHTML/HtmlView.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +class HtmlView : public GScrollableWidget { + C_OBJECT(HtmlView) +public: + virtual ~HtmlView() override {} + + Document* document() { return m_document; } + const Document* document() const { return m_document; } + void set_document(Document*); + +protected: + HtmlView(GWidget* parent = nullptr); + + virtual void resize_event(GResizeEvent&) override; + virtual void paint_event(GPaintEvent&) override; + +private: + void layout_and_sync_size(); + + RefPtr m_document; + RefPtr m_layout_root; +}; diff --git a/Libraries/LibHTML/Makefile.shared b/Libraries/LibHTML/Makefile.shared index 00c045ef3e5..f55764de553 100644 --- a/Libraries/LibHTML/Makefile.shared +++ b/Libraries/LibHTML/Makefile.shared @@ -20,7 +20,7 @@ LIBHTML_OBJS = \ Layout/LayoutInline.o \ Layout/LayoutDocument.o \ Layout/ComputedStyle.o \ - Frame.o \ + HtmlView.o \ Dump.o GENERATED_SOURCES = \ diff --git a/Libraries/LibHTML/test.cpp b/Libraries/LibHTML/test.cpp index 6e47918e912..22f3e3791f4 100644 --- a/Libraries/LibHTML/test.cpp +++ b/Libraries/LibHTML/test.cpp @@ -1,8 +1,10 @@ #include +#include +#include #include #include #include -#include +#include #include #include #include @@ -11,6 +13,8 @@ int main(int argc, char** argv) { + GApplication app(argc, argv); + auto f = CFile::construct(argc == 1 ? "/home/anon/small.html" : argv[1]); if (!f->open(CIODevice::ReadOnly)) { fprintf(stderr, "Error: %s\n", f->error_string()); @@ -28,8 +32,11 @@ int main(int argc, char** argv) dump_tree(document); document->add_sheet(*sheet); - auto frame = make(); - frame->set_document(document); - frame->layout(); - return 0; + auto window = GWindow::construct(); + auto widget = HtmlView::construct(); + widget->set_document(document); + window->set_main_widget(widget); + window->show(); + + return app.exec(); }