Get rid of the "root widget" concept in WindowManager.

Instead just create a GraphicsBitmap wrapper around the display framebuffer
and teach Painter how to draw directly into a GraphicsBitmap.
This commit is contained in:
Andreas Kling 2019-01-12 03:42:50 +01:00
parent 0e6c19ffa6
commit bb28c31531
10 changed files with 18 additions and 80 deletions

View file

@ -55,7 +55,6 @@ WIDGETS_OBJS = \
../Widgets/Color.o \
../Widgets/CharacterBitmap.o \
../Widgets/EventLoop.o \
../Widgets/RootWidget.o \
../Widgets/Label.o \
../Widgets/Button.o \
../Widgets/MsgBox.o \

View file

@ -3,7 +3,6 @@
#include <Widgets/Font.h>
#include <Widgets/FrameBuffer.h>
#include <Widgets/WindowManager.h>
#include <Widgets/RootWidget.h>
#include <Widgets/EventLoop.h>
#include <Widgets/MsgBox.h>
#include <Widgets/TextBox.h>
@ -26,11 +25,8 @@ void WindowComposer_main()
dbgprintf("Screen is %ux%ux%ubpp\n", info.width, info.height, info.bpp);
FrameBuffer framebuffer((dword*)info.framebuffer, info.width, info.height);
RootWidget rw;
EventLoop loop;
WindowManager::the().setRootWidget(&rw);
MsgBox(nullptr, "Serenity Operating System");
{

View file

@ -13,7 +13,6 @@ VFS_OBJS = \
Rect.o \
Object.o \
Widget.o \
RootWidget.o \
Color.o \
Painter.o \
Label.o \

View file

@ -6,9 +6,15 @@
#include <AK/Assertions.h>
#include <AK/StdLibExtras.h>
Painter::Painter(GraphicsBitmap& bitmap)
{
m_font = &Font::defaultFont();
m_target = &bitmap;
m_clipRect = { { 0, 0 }, bitmap.size() };
}
Painter::Painter(Widget& widget)
: m_widget(widget)
, m_font(&widget.font())
: m_font(&widget.font())
{
m_target = widget.backing();
ASSERT(m_target);
@ -102,7 +108,6 @@ void Painter::drawText(const Rect& rect, const String& text, TextAlignment align
if (alignment == TextAlignment::TopLeft) {
point = rect.location();
} else if (alignment == TextAlignment::CenterLeft) {
int textWidth = text.length() * font().glyphWidth();
point = { rect.x(), rect.center().y() - (font().glyphHeight() / 2) };
} else if (alignment == TextAlignment::Center) {
int textWidth = text.length() * font().glyphWidth();

View file

@ -16,6 +16,7 @@ class Painter {
public:
enum class TextAlignment { TopLeft, CenterLeft, Center };
explicit Painter(Widget&);
explicit Painter(GraphicsBitmap&);
~Painter();
void fillRect(const Rect&, Color);
void drawRect(const Rect&, Color);
@ -37,7 +38,6 @@ public:
private:
void set_pixel_with_draw_op(dword& pixel, const Color&);
Widget& m_widget;
const Font* m_font;
Point m_translation;
Rect m_clipRect;

View file

@ -1,29 +0,0 @@
#include "AbstractScreen.h"
#include "GraphicsBitmap.h"
#include "RootWidget.h"
#include "Painter.h"
#include "WindowManager.h"
#include "FrameBuffer.h"
RootWidget::RootWidget()
{
setWindowRelativeRect(FrameBuffer::the().rect());
m_backing = GraphicsBitmap::create_wrapper(size(), FrameBuffer::the().scanline(0));
}
RootWidget::~RootWidget()
{
}
void RootWidget::paintEvent(PaintEvent& event)
{
Painter painter(*this);
painter.fillRect(event.rect(), Color(0, 72, 96));
}
void RootWidget::mouseMoveEvent(MouseEvent& event)
{
//printf("RootWidget::mouseMoveEvent: x=%d, y=%d\n", event.x(), event.y());
Widget::mouseMoveEvent(event);
}

View file

@ -1,19 +0,0 @@
#pragma once
#include "Widget.h"
class GraphicsBitmap;
class RootWidget final : public Widget {
public:
RootWidget();
virtual ~RootWidget() override;
private:
virtual void paintEvent(PaintEvent&) override;
virtual void mouseMoveEvent(MouseEvent&) override;
virtual GraphicsBitmap* backing() override { return m_backing.ptr(); }
RetainPtr<GraphicsBitmap> m_backing;
};

View file

@ -63,6 +63,8 @@ void WindowManager::initialize()
WindowManager::WindowManager()
{
m_root_bitmap = GraphicsBitmap::create_wrapper(FrameBuffer::the().rect().size(), FrameBuffer::the().scanline(0));
m_activeWindowBorderColor = Color(0, 64, 192);
m_activeWindowTitleColor = Color::White;
@ -78,7 +80,7 @@ WindowManager::~WindowManager()
void WindowManager::paintWindowFrame(Window& window)
{
Painter p(*m_rootWidget);
Painter p(*m_root_bitmap);
//printf("[WM] paintWindowFrame {%p}, rect: %d,%d %dx%d\n", &window, window.rect().x(), window.rect().y(), window.rect().width(), window.rect().height());
@ -253,12 +255,12 @@ void WindowManager::compose()
return false;
};
{
Painter p(*m_root_bitmap);
for (auto& r : m_invalidated_rects) {
if (any_window_contains_rect(r))
continue;
dbgprintf("Repaint root %d,%d %dx%d\n", r.x(), r.y(), r.width(), r.height());
PaintEvent event(r);
m_rootWidget->paintEvent(event);
p.fillRect(r, Color(0, 72, 96));
}
}
auto& framebuffer = FrameBuffer::the();
@ -279,7 +281,7 @@ void WindowManager::compose()
void WindowManager::redraw_cursor()
{
auto cursor_location = AbstractScreen::the().cursor_location();
Painter painter(*m_rootWidget);
Painter painter(*m_root_bitmap);
painter.set_draw_op(Painter::DrawOp::Xor);
auto draw_cross = [&painter] (const Point& p) {
painter.drawLine({ p.x() - 10, p.y() }, { p.x() + 10, p.y() }, Color::Red);
@ -307,16 +309,6 @@ void WindowManager::event(Event& event)
return Object::event(event);
}
void WindowManager::setRootWidget(Widget* widget)
{
// FIXME: Should we support switching root widgets?
ASSERT(!m_rootWidget);
ASSERT(widget);
m_rootWidget = widget;
EventLoop::main().postEvent(m_rootWidget, make<ShowEvent>());
}
void WindowManager::setActiveWindow(Window* window)
{
if (window == m_activeWindow.ptr())

View file

@ -11,6 +11,7 @@ class MouseEvent;
class PaintEvent;
class Widget;
class Window;
class GraphicsBitmap;
class WindowManager : public Object {
public:
@ -21,9 +22,6 @@ public:
void notifyTitleChanged(Window&);
void notifyRectChanged(Window&, const Rect& oldRect, const Rect& newRect);
Widget* rootWidget() { return m_rootWidget; }
void setRootWidget(Widget*);
Window* activeWindow() { return m_activeWindow.ptr(); }
void setActiveWindow(Window*);
@ -60,7 +58,6 @@ private:
void paintWindowFrame(Window&);
HashTable<Window*> m_windows;
InlineLinkedList<Window> m_windows_in_order;
Widget* m_rootWidget { nullptr };
WeakPtr<Window> m_activeWindow;
@ -76,5 +73,7 @@ private:
unsigned m_recompose_count { 0 };
RetainPtr<GraphicsBitmap> m_root_bitmap;
Vector<Rect> m_invalidated_rects;
};

View file

@ -1,6 +1,5 @@
#include "FrameBuffer.h"
#include "EventLoop.h"
#include "RootWidget.h"
#include "Label.h"
#include "Button.h"
#include "WindowManager.h"
@ -19,9 +18,6 @@ int main(int argc, char** argv)
EventLoop loop;
RootWidget w;
WindowManager::the().setRootWidget(&w);
auto* fontTestWindow = new Window;
fontTestWindow->setTitle("Font test");
fontTestWindow->setRect({ 140, 100, 300, 80 });