Start adding a Window class.

This commit is contained in:
Andreas Kling 2018-10-12 01:03:22 +02:00
parent bd6172e3c7
commit 415c4b90c5
12 changed files with 159 additions and 55 deletions

View file

@ -21,6 +21,7 @@ VFS_OBJS = \
TerminalWidget.o \ TerminalWidget.o \
WindowManager.o \ WindowManager.o \
Font.o \ Font.o \
Window.o \
test.o test.o
OBJS = $(AK_OBJS) $(VFS_OBJS) OBJS = $(AK_OBJS) $(VFS_OBJS)

View file

@ -15,6 +15,9 @@ public:
Vector<Object*>& children() { return m_children; } Vector<Object*>& children() { return m_children; }
Object* parent() { return m_parent; }
const Object* parent() const { return m_parent; }
private: private:
void addChild(Object&); void addChild(Object&);
void removeChild(Object&); void removeChild(Object&);

View file

@ -17,6 +17,12 @@ public:
m_y += dy; m_y += dy;
} }
bool operator==(const Point& other) const
{
return m_x == other.m_x
&& m_y == other.m_y;
}
private: private:
int m_x { 0 }; int m_x { 0 };
int m_y { 0 }; int m_y { 0 };

View file

@ -57,6 +57,13 @@ public:
Point location() const { return m_location; } Point location() const { return m_location; }
bool operator==(const Rect& other) const
{
return m_location == other.m_location
&& m_width == other.m_width
&& m_height == other.m_height;
}
private: private:
Point m_location; Point m_location;
int m_width { 0 }; int m_width { 0 };

View file

@ -12,8 +12,6 @@ TerminalWidget* g_tw;
TerminalWidget::TerminalWidget(Widget* parent) TerminalWidget::TerminalWidget(Widget* parent)
: Widget(parent) : Widget(parent)
{ {
setIsWindow(true);
g_tw = this; g_tw = this;
auto& font = Font::defaultFont(); auto& font = Font::defaultFont();

View file

@ -22,17 +22,6 @@ void Widget::setRect(const Rect& rect)
update(); update();
} }
void Widget::setIsWindow(bool value)
{
if (m_isWindow == value)
return;
m_isWindow = value;
if (m_isWindow) {
WindowManager::the().addWindow(*this);
}
update();
}
void Widget::event(Event& event) void Widget::event(Event& event)
{ {
switch (event.type()) { switch (event.type()) {
@ -116,10 +105,3 @@ Widget::HitTestResult Widget::hitTest(int x, int y)
return { this, x, y }; return { this, x, y };
} }
void Widget::setWindowTitle(String&& title)
{
if (title == m_windowTitle)
return;
m_windowTitle = std::move(title);
WindowManager::the().notifyTitleChanged(*this);
}

View file

@ -6,6 +6,8 @@
#include "Color.h" #include "Color.h"
#include <AK/String.h> #include <AK/String.h>
class Window;
class Widget : public Object { class Widget : public Object {
public: public:
explicit Widget(Widget* parent = nullptr); explicit Widget(Widget* parent = nullptr);
@ -46,18 +48,29 @@ public:
void setBackgroundColor(Color color) { m_backgroundColor = color; } void setBackgroundColor(Color color) { m_backgroundColor = color; }
void setForegroundColor(Color color) { m_foregroundColor = color; } void setForegroundColor(Color color) { m_foregroundColor = color; }
bool isWindow() const { return m_isWindow; } Window* window()
void setIsWindow(bool); {
if (auto* pw = parentWidget())
return pw->window();
return m_window;
}
void setWindowTitle(String&&); const Window* window() const
String windowTitle() const { return m_windowTitle; } {
if (auto* pw = parentWidget())
return pw->window();
return m_window;
}
Widget* parentWidget() { return static_cast<Widget*>(parent()); }
const Widget* parentWidget() const { return static_cast<const Widget*>(parent()); }
private: private:
Window* m_window { nullptr };
Rect m_rect; Rect m_rect;
Color m_backgroundColor; Color m_backgroundColor;
Color m_foregroundColor; Color m_foregroundColor;
String m_windowTitle;
bool m_isWindow { false };
bool m_hasPendingPaintEvent { false }; bool m_hasPendingPaintEvent { false };
}; };

39
Widgets/Window.cpp Normal file
View file

@ -0,0 +1,39 @@
#include "Window.h"
#include "WindowManager.h"
Window::Window(Object* parent)
: Object(parent)
{
WindowManager::the().addWindow(*this);
}
Window::~Window()
{
}
void Window::setMainWidget(Widget* widget)
{
if (m_mainWidget == widget)
return;
m_mainWidget = widget;
}
void Window::setTitle(String&& title)
{
if (m_title == title)
return;
m_title = std::move(title);
WindowManager::the().notifyTitleChanged(*this);
}
void Window::setRect(const Rect& rect)
{
if (m_rect == rect)
return;
auto oldRect = m_rect;
m_rect = rect;
WindowManager::the().notifyRectChanged(*this, oldRect, m_rect);
}

35
Widgets/Window.h Normal file
View file

@ -0,0 +1,35 @@
#pragma once
#include <AK/String.h>
#include "Object.h"
#include "Rect.h"
class Widget;
class Window : public Object {
public:
explicit Window(Object* parent = nullptr);
virtual ~Window() override;
String title() const { return m_title; }
void setTitle(String&&);
int x() const { return m_rect.x(); }
int y() const { return m_rect.y(); }
int width() const { return m_rect.width(); }
int height() const { return m_rect.height(); }
const Rect& rect() const { return m_rect; }
void setRect(const Rect&);
Widget* mainWidget() { return m_mainWidget; }
const Widget* mainWidget() const { return m_mainWidget; }
void setMainWidget(Widget*);
private:
String m_title;
Rect m_rect;
Widget* m_mainWidget { nullptr };
};

View file

@ -1,6 +1,7 @@
#include "WindowManager.h" #include "WindowManager.h"
#include "Painter.h" #include "Painter.h"
#include "Widget.h" #include "Widget.h"
#include "Window.h"
#include "AbstractScreen.h" #include "AbstractScreen.h"
WindowManager& WindowManager::the() WindowManager& WindowManager::the()
@ -19,44 +20,43 @@ WindowManager::~WindowManager()
void WindowManager::paintWindowFrames() void WindowManager::paintWindowFrames()
{ {
for (auto* widget : m_windows) { for (auto* window : m_windows)
paintWindowFrame(*widget); paintWindowFrame(*window);
}
} }
void WindowManager::paintWindowFrame(Widget& widget) void WindowManager::paintWindowFrame(Window& window)
{ {
Painter p(*AbstractScreen::the().rootWidget()); Painter p(*AbstractScreen::the().rootWidget());
printf("WM: paintWindowFrame %s{%p}, rect: %d,%d %dx%d\n", widget.className(), &widget, widget.rect().x(), widget.rect().y(), widget.rect().width(), widget.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());
static const int windowFrameWidth = 2; static const int windowFrameWidth = 2;
static const int windowTitleBarHeight = 16; static const int windowTitleBarHeight = 16;
Rect topRect { Rect topRect {
widget.x() - windowFrameWidth, window.x() - windowFrameWidth,
widget.y() - windowTitleBarHeight - windowFrameWidth, window.y() - windowTitleBarHeight - windowFrameWidth,
widget.width() + windowFrameWidth * 2, window.width() + windowFrameWidth * 2,
windowTitleBarHeight + windowFrameWidth }; windowTitleBarHeight + windowFrameWidth };
Rect bottomRect { Rect bottomRect {
widget.x() - windowFrameWidth, window.x() - windowFrameWidth,
widget.y() + widget.height(), window.y() + window.height(),
widget.width() + windowFrameWidth * 2, window.width() + windowFrameWidth * 2,
windowFrameWidth }; windowFrameWidth };
Rect leftRect { Rect leftRect {
widget.x() - windowFrameWidth, window.x() - windowFrameWidth,
widget.y(), window.y(),
windowFrameWidth, windowFrameWidth,
widget.height() window.height()
}; };
Rect rightRect { Rect rightRect {
widget.x() + widget.width(), window.x() + window.width(),
widget.y(), window.y(),
windowFrameWidth, windowFrameWidth,
widget.height() window.height()
}; };
static const Color windowBorderColor(0x00, 0x00, 0x80); static const Color windowBorderColor(0x00, 0x00, 0x80);
@ -66,7 +66,7 @@ void WindowManager::paintWindowFrame(Widget& widget)
topRect.x() - 1, topRect.x() - 1,
topRect.y() - 1, topRect.y() - 1,
topRect.width() + 2, topRect.width() + 2,
windowFrameWidth + windowTitleBarHeight + widget.height() + 4 windowFrameWidth + windowTitleBarHeight + window.rect().height() + 4
}; };
p.drawRect(borderRect, Color(255, 255, 255)); p.drawRect(borderRect, Color(255, 255, 255));
borderRect.inflate(2, 2); borderRect.inflate(2, 2);
@ -77,16 +77,29 @@ void WindowManager::paintWindowFrame(Widget& widget)
p.fillRect(leftRect, windowBorderColor); p.fillRect(leftRect, windowBorderColor);
p.fillRect(rightRect, windowBorderColor); p.fillRect(rightRect, windowBorderColor);
p.drawText(topRect, widget.windowTitle(), Painter::TextAlignment::Center, windowTitleColor); p.drawText(topRect, window.title(), Painter::TextAlignment::Center, windowTitleColor);
} }
void WindowManager::addWindow(Widget& widget) void WindowManager::addWindow(Window& window)
{ {
m_windows.set(&widget); m_windows.set(&window);
} }
void WindowManager::notifyTitleChanged(Widget&) void WindowManager::notifyTitleChanged(Window& window)
{ {
AbstractScreen::the().rootWidget()->update(); printf("[WM] ]Window{%p} title set to '%s'\n", &window, window.title().characters());
} }
void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const Rect& newRect)
{
printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n",
&window,
oldRect.x(),
oldRect.y(),
oldRect.width(),
oldRect.height(),
newRect.x(),
newRect.y(),
newRect.width(),
newRect.height());
}

View file

@ -1,24 +1,26 @@
#pragma once #pragma once
class Widget; class Window;
#include "Object.h" #include "Object.h"
#include "Rect.h"
#include <AK/HashTable.h> #include <AK/HashTable.h>
class WindowManager : public Object { class WindowManager : public Object {
public: public:
static WindowManager& the(); static WindowManager& the();
void addWindow(Widget&); void addWindow(Window&);
void paintWindowFrames(); void paintWindowFrames();
void notifyTitleChanged(Widget&); void notifyTitleChanged(Window&);
void notifyRectChanged(Window&, const Rect& oldRect, const Rect& newRect);
private: private:
WindowManager(); WindowManager();
~WindowManager(); ~WindowManager();
void paintWindowFrame(Widget&); void paintWindowFrame(Window&);
HashTable<Widget*> m_windows; HashTable<Window*> m_windows;
}; };

View file

@ -5,6 +5,7 @@
#include "Button.h" #include "Button.h"
#include "TerminalWidget.h" #include "TerminalWidget.h"
#include "WindowManager.h" #include "WindowManager.h"
#include "Window.h"
#include <cstdio> #include <cstdio>
int main(int c, char** v) int main(int c, char** v)
@ -39,8 +40,12 @@ int main(int c, char** v)
b->setRect(Rect(10, 10, 100, 30)); b->setRect(Rect(10, 10, 100, 30));
b->setCaption("Button!"); b->setCaption("Button!");
auto* win = new Window;
win->setTitle("Console");
win->setRect({100, 300, 644, 254});
auto* t = new TerminalWidget(&w); auto* t = new TerminalWidget(&w);
t->setWindowTitle("Console"); win->setMainWidget(t);
return loop.exec(); return loop.exec();
} }