mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:47:45 +00:00
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:
parent
0e6c19ffa6
commit
bb28c31531
10 changed files with 18 additions and 80 deletions
|
@ -55,7 +55,6 @@ WIDGETS_OBJS = \
|
||||||
../Widgets/Color.o \
|
../Widgets/Color.o \
|
||||||
../Widgets/CharacterBitmap.o \
|
../Widgets/CharacterBitmap.o \
|
||||||
../Widgets/EventLoop.o \
|
../Widgets/EventLoop.o \
|
||||||
../Widgets/RootWidget.o \
|
|
||||||
../Widgets/Label.o \
|
../Widgets/Label.o \
|
||||||
../Widgets/Button.o \
|
../Widgets/Button.o \
|
||||||
../Widgets/MsgBox.o \
|
../Widgets/MsgBox.o \
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <Widgets/Font.h>
|
#include <Widgets/Font.h>
|
||||||
#include <Widgets/FrameBuffer.h>
|
#include <Widgets/FrameBuffer.h>
|
||||||
#include <Widgets/WindowManager.h>
|
#include <Widgets/WindowManager.h>
|
||||||
#include <Widgets/RootWidget.h>
|
|
||||||
#include <Widgets/EventLoop.h>
|
#include <Widgets/EventLoop.h>
|
||||||
#include <Widgets/MsgBox.h>
|
#include <Widgets/MsgBox.h>
|
||||||
#include <Widgets/TextBox.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);
|
dbgprintf("Screen is %ux%ux%ubpp\n", info.width, info.height, info.bpp);
|
||||||
|
|
||||||
FrameBuffer framebuffer((dword*)info.framebuffer, info.width, info.height);
|
FrameBuffer framebuffer((dword*)info.framebuffer, info.width, info.height);
|
||||||
RootWidget rw;
|
|
||||||
EventLoop loop;
|
EventLoop loop;
|
||||||
|
|
||||||
WindowManager::the().setRootWidget(&rw);
|
|
||||||
|
|
||||||
MsgBox(nullptr, "Serenity Operating System");
|
MsgBox(nullptr, "Serenity Operating System");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,6 @@ VFS_OBJS = \
|
||||||
Rect.o \
|
Rect.o \
|
||||||
Object.o \
|
Object.o \
|
||||||
Widget.o \
|
Widget.o \
|
||||||
RootWidget.o \
|
|
||||||
Color.o \
|
Color.o \
|
||||||
Painter.o \
|
Painter.o \
|
||||||
Label.o \
|
Label.o \
|
||||||
|
|
|
@ -6,9 +6,15 @@
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
#include <AK/StdLibExtras.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)
|
Painter::Painter(Widget& widget)
|
||||||
: m_widget(widget)
|
: m_font(&widget.font())
|
||||||
, m_font(&widget.font())
|
|
||||||
{
|
{
|
||||||
m_target = widget.backing();
|
m_target = widget.backing();
|
||||||
ASSERT(m_target);
|
ASSERT(m_target);
|
||||||
|
@ -102,7 +108,6 @@ void Painter::drawText(const Rect& rect, const String& text, TextAlignment align
|
||||||
if (alignment == TextAlignment::TopLeft) {
|
if (alignment == TextAlignment::TopLeft) {
|
||||||
point = rect.location();
|
point = rect.location();
|
||||||
} else if (alignment == TextAlignment::CenterLeft) {
|
} else if (alignment == TextAlignment::CenterLeft) {
|
||||||
int textWidth = text.length() * font().glyphWidth();
|
|
||||||
point = { rect.x(), rect.center().y() - (font().glyphHeight() / 2) };
|
point = { rect.x(), rect.center().y() - (font().glyphHeight() / 2) };
|
||||||
} else if (alignment == TextAlignment::Center) {
|
} else if (alignment == TextAlignment::Center) {
|
||||||
int textWidth = text.length() * font().glyphWidth();
|
int textWidth = text.length() * font().glyphWidth();
|
||||||
|
|
|
@ -16,6 +16,7 @@ class Painter {
|
||||||
public:
|
public:
|
||||||
enum class TextAlignment { TopLeft, CenterLeft, Center };
|
enum class TextAlignment { TopLeft, CenterLeft, Center };
|
||||||
explicit Painter(Widget&);
|
explicit Painter(Widget&);
|
||||||
|
explicit Painter(GraphicsBitmap&);
|
||||||
~Painter();
|
~Painter();
|
||||||
void fillRect(const Rect&, Color);
|
void fillRect(const Rect&, Color);
|
||||||
void drawRect(const Rect&, Color);
|
void drawRect(const Rect&, Color);
|
||||||
|
@ -37,7 +38,6 @@ public:
|
||||||
private:
|
private:
|
||||||
void set_pixel_with_draw_op(dword& pixel, const Color&);
|
void set_pixel_with_draw_op(dword& pixel, const Color&);
|
||||||
|
|
||||||
Widget& m_widget;
|
|
||||||
const Font* m_font;
|
const Font* m_font;
|
||||||
Point m_translation;
|
Point m_translation;
|
||||||
Rect m_clipRect;
|
Rect m_clipRect;
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
|
|
@ -63,6 +63,8 @@ void WindowManager::initialize()
|
||||||
|
|
||||||
WindowManager::WindowManager()
|
WindowManager::WindowManager()
|
||||||
{
|
{
|
||||||
|
m_root_bitmap = GraphicsBitmap::create_wrapper(FrameBuffer::the().rect().size(), FrameBuffer::the().scanline(0));
|
||||||
|
|
||||||
m_activeWindowBorderColor = Color(0, 64, 192);
|
m_activeWindowBorderColor = Color(0, 64, 192);
|
||||||
m_activeWindowTitleColor = Color::White;
|
m_activeWindowTitleColor = Color::White;
|
||||||
|
|
||||||
|
@ -78,7 +80,7 @@ WindowManager::~WindowManager()
|
||||||
|
|
||||||
void WindowManager::paintWindowFrame(Window& window)
|
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());
|
//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;
|
return false;
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
|
Painter p(*m_root_bitmap);
|
||||||
for (auto& r : m_invalidated_rects) {
|
for (auto& r : m_invalidated_rects) {
|
||||||
if (any_window_contains_rect(r))
|
if (any_window_contains_rect(r))
|
||||||
continue;
|
continue;
|
||||||
dbgprintf("Repaint root %d,%d %dx%d\n", r.x(), r.y(), r.width(), r.height());
|
dbgprintf("Repaint root %d,%d %dx%d\n", r.x(), r.y(), r.width(), r.height());
|
||||||
PaintEvent event(r);
|
p.fillRect(r, Color(0, 72, 96));
|
||||||
m_rootWidget->paintEvent(event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto& framebuffer = FrameBuffer::the();
|
auto& framebuffer = FrameBuffer::the();
|
||||||
|
@ -279,7 +281,7 @@ void WindowManager::compose()
|
||||||
void WindowManager::redraw_cursor()
|
void WindowManager::redraw_cursor()
|
||||||
{
|
{
|
||||||
auto cursor_location = AbstractScreen::the().cursor_location();
|
auto cursor_location = AbstractScreen::the().cursor_location();
|
||||||
Painter painter(*m_rootWidget);
|
Painter painter(*m_root_bitmap);
|
||||||
painter.set_draw_op(Painter::DrawOp::Xor);
|
painter.set_draw_op(Painter::DrawOp::Xor);
|
||||||
auto draw_cross = [&painter] (const Point& p) {
|
auto draw_cross = [&painter] (const Point& p) {
|
||||||
painter.drawLine({ p.x() - 10, p.y() }, { p.x() + 10, p.y() }, Color::Red);
|
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);
|
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)
|
void WindowManager::setActiveWindow(Window* window)
|
||||||
{
|
{
|
||||||
if (window == m_activeWindow.ptr())
|
if (window == m_activeWindow.ptr())
|
||||||
|
|
|
@ -11,6 +11,7 @@ class MouseEvent;
|
||||||
class PaintEvent;
|
class PaintEvent;
|
||||||
class Widget;
|
class Widget;
|
||||||
class Window;
|
class Window;
|
||||||
|
class GraphicsBitmap;
|
||||||
|
|
||||||
class WindowManager : public Object {
|
class WindowManager : public Object {
|
||||||
public:
|
public:
|
||||||
|
@ -21,9 +22,6 @@ public:
|
||||||
void notifyTitleChanged(Window&);
|
void notifyTitleChanged(Window&);
|
||||||
void notifyRectChanged(Window&, const Rect& oldRect, const Rect& newRect);
|
void notifyRectChanged(Window&, const Rect& oldRect, const Rect& newRect);
|
||||||
|
|
||||||
Widget* rootWidget() { return m_rootWidget; }
|
|
||||||
void setRootWidget(Widget*);
|
|
||||||
|
|
||||||
Window* activeWindow() { return m_activeWindow.ptr(); }
|
Window* activeWindow() { return m_activeWindow.ptr(); }
|
||||||
void setActiveWindow(Window*);
|
void setActiveWindow(Window*);
|
||||||
|
|
||||||
|
@ -60,7 +58,6 @@ private:
|
||||||
void paintWindowFrame(Window&);
|
void paintWindowFrame(Window&);
|
||||||
HashTable<Window*> m_windows;
|
HashTable<Window*> m_windows;
|
||||||
InlineLinkedList<Window> m_windows_in_order;
|
InlineLinkedList<Window> m_windows_in_order;
|
||||||
Widget* m_rootWidget { nullptr };
|
|
||||||
|
|
||||||
WeakPtr<Window> m_activeWindow;
|
WeakPtr<Window> m_activeWindow;
|
||||||
|
|
||||||
|
@ -76,5 +73,7 @@ private:
|
||||||
|
|
||||||
unsigned m_recompose_count { 0 };
|
unsigned m_recompose_count { 0 };
|
||||||
|
|
||||||
|
RetainPtr<GraphicsBitmap> m_root_bitmap;
|
||||||
|
|
||||||
Vector<Rect> m_invalidated_rects;
|
Vector<Rect> m_invalidated_rects;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "FrameBuffer.h"
|
#include "FrameBuffer.h"
|
||||||
#include "EventLoop.h"
|
#include "EventLoop.h"
|
||||||
#include "RootWidget.h"
|
|
||||||
#include "Label.h"
|
#include "Label.h"
|
||||||
#include "Button.h"
|
#include "Button.h"
|
||||||
#include "WindowManager.h"
|
#include "WindowManager.h"
|
||||||
|
@ -19,9 +18,6 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
EventLoop loop;
|
EventLoop loop;
|
||||||
|
|
||||||
RootWidget w;
|
|
||||||
WindowManager::the().setRootWidget(&w);
|
|
||||||
|
|
||||||
auto* fontTestWindow = new Window;
|
auto* fontTestWindow = new Window;
|
||||||
fontTestWindow->setTitle("Font test");
|
fontTestWindow->setTitle("Font test");
|
||||||
fontTestWindow->setRect({ 140, 100, 300, 80 });
|
fontTestWindow->setRect({ 140, 100, 300, 80 });
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue