Start adding a Window class.

This commit is contained in:
Andreas Kling 2018-10-12 01:03:22 +02:00
parent bd6172e3c7
commit 415c4b90c5
Notes: sideshowbarker 2024-07-19 18:50:36 +09:00
12 changed files with 159 additions and 55 deletions

View file

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

View file

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

View file

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

View file

@ -57,6 +57,13 @@ public:
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:
Point m_location;
int m_width { 0 };

View file

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

View file

@ -22,17 +22,6 @@ void Widget::setRect(const Rect& rect)
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)
{
switch (event.type()) {
@ -116,10 +105,3 @@ Widget::HitTestResult Widget::hitTest(int x, int 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 <AK/String.h>
class Window;
class Widget : public Object {
public:
explicit Widget(Widget* parent = nullptr);
@ -46,18 +48,29 @@ public:
void setBackgroundColor(Color color) { m_backgroundColor = color; }
void setForegroundColor(Color color) { m_foregroundColor = color; }
bool isWindow() const { return m_isWindow; }
void setIsWindow(bool);
Window* window()
{
if (auto* pw = parentWidget())
return pw->window();
return m_window;
}
void setWindowTitle(String&&);
String windowTitle() const { return m_windowTitle; }
const Window* window() const
{
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:
Window* m_window { nullptr };
Rect m_rect;
Color m_backgroundColor;
Color m_foregroundColor;
String m_windowTitle;
bool m_isWindow { 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 "Painter.h"
#include "Widget.h"
#include "Window.h"
#include "AbstractScreen.h"
WindowManager& WindowManager::the()
@ -19,44 +20,43 @@ WindowManager::~WindowManager()
void WindowManager::paintWindowFrames()
{
for (auto* widget : m_windows) {
paintWindowFrame(*widget);
}
for (auto* window : m_windows)
paintWindowFrame(*window);
}
void WindowManager::paintWindowFrame(Widget& widget)
void WindowManager::paintWindowFrame(Window& window)
{
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 windowTitleBarHeight = 16;
Rect topRect {
widget.x() - windowFrameWidth,
widget.y() - windowTitleBarHeight - windowFrameWidth,
widget.width() + windowFrameWidth * 2,
window.x() - windowFrameWidth,
window.y() - windowTitleBarHeight - windowFrameWidth,
window.width() + windowFrameWidth * 2,
windowTitleBarHeight + windowFrameWidth };
Rect bottomRect {
widget.x() - windowFrameWidth,
widget.y() + widget.height(),
widget.width() + windowFrameWidth * 2,
window.x() - windowFrameWidth,
window.y() + window.height(),
window.width() + windowFrameWidth * 2,
windowFrameWidth };
Rect leftRect {
widget.x() - windowFrameWidth,
widget.y(),
window.x() - windowFrameWidth,
window.y(),
windowFrameWidth,
widget.height()
window.height()
};
Rect rightRect {
widget.x() + widget.width(),
widget.y(),
window.x() + window.width(),
window.y(),
windowFrameWidth,
widget.height()
window.height()
};
static const Color windowBorderColor(0x00, 0x00, 0x80);
@ -66,7 +66,7 @@ void WindowManager::paintWindowFrame(Widget& widget)
topRect.x() - 1,
topRect.y() - 1,
topRect.width() + 2,
windowFrameWidth + windowTitleBarHeight + widget.height() + 4
windowFrameWidth + windowTitleBarHeight + window.rect().height() + 4
};
p.drawRect(borderRect, Color(255, 255, 255));
borderRect.inflate(2, 2);
@ -77,16 +77,29 @@ void WindowManager::paintWindowFrame(Widget& widget)
p.fillRect(leftRect, 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
class Widget;
class Window;
#include "Object.h"
#include "Rect.h"
#include <AK/HashTable.h>
class WindowManager : public Object {
public:
static WindowManager& the();
void addWindow(Widget&);
void addWindow(Window&);
void paintWindowFrames();
void notifyTitleChanged(Widget&);
void notifyTitleChanged(Window&);
void notifyRectChanged(Window&, const Rect& oldRect, const Rect& newRect);
private:
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 "TerminalWidget.h"
#include "WindowManager.h"
#include "Window.h"
#include <cstdio>
int main(int c, char** v)
@ -39,8 +40,12 @@ int main(int c, char** v)
b->setRect(Rect(10, 10, 100, 30));
b->setCaption("Button!");
auto* win = new Window;
win->setTitle("Console");
win->setRect({100, 300, 644, 254});
auto* t = new TerminalWidget(&w);
t->setWindowTitle("Console");
win->setMainWidget(t);
return loop.exec();
}