Преглед изворни кода

LibHTML: Introduce the HtmlView widget

This is a GWidget that can display contents of an HTML document.
It replaces the Frame class.
Sergey Bugaev пре 5 година
родитељ
комит
b9493ba783

+ 0 - 41
Libraries/LibHTML/Frame.cpp

@@ -1,41 +0,0 @@
-#include <AK/Function.h>
-#include <LibHTML/CSS/StyleResolver.h>
-#include <LibHTML/DOM/Element.h>
-#include <LibHTML/Dump.h>
-#include <LibHTML/Frame.h>
-#include <LibHTML/Layout/LayoutBlock.h>
-#include <LibHTML/Layout/LayoutDocument.h>
-#include <LibHTML/Layout/LayoutInline.h>
-#include <stdio.h>
-
-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);
-}

+ 0 - 23
Libraries/LibHTML/Frame.h

@@ -1,23 +0,0 @@
-#pragma once
-
-#include <LibDraw/Size.h>
-#include <LibHTML/DOM/Document.h>
-
-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<LayoutNode> generate_layout_tree();
-
-    RefPtr<Document> m_document;
-    Size m_size;
-};

+ 80 - 0
Libraries/LibHTML/HtmlView.cpp

@@ -0,0 +1,80 @@
+#include <LibGUI/GPainter.h>
+#include <LibGUI/GScrollBar.h>
+#include <LibHTML/Dump.h>
+#include <LibHTML/HtmlView.h>
+#include <LibHTML/Layout/LayoutNode.h>
+#include <LibHTML/RenderingContext.h>
+#include <stdio.h>
+
+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);
+}

+ 26 - 0
Libraries/LibHTML/HtmlView.h

@@ -0,0 +1,26 @@
+#pragma once
+
+#include <LibGUI/GScrollableWidget.h>
+#include <LibHTML/DOM/Document.h>
+
+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<Document> m_document;
+    RefPtr<LayoutNode> m_layout_root;
+};

+ 1 - 1
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 = \

+ 12 - 5
Libraries/LibHTML/test.cpp

@@ -1,8 +1,10 @@
 #include <LibCore/CFile.h>
+#include <LibGUI/GApplication.h>
+#include <LibGUI/GWindow.h>
 #include <LibHTML/CSS/StyleResolver.h>
 #include <LibHTML/DOM/Element.h>
 #include <LibHTML/Dump.h>
-#include <LibHTML/Frame.h>
+#include <LibHTML/HtmlView.h>
 #include <LibHTML/Layout/LayoutBlock.h>
 #include <LibHTML/Layout/LayoutInline.h>
 #include <LibHTML/Parser/CSSParser.h>
@@ -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>();
-    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();
 }