mirror of
https://github.com/SerenityOS/serenity
synced 2024-09-06 08:56:40 +00:00
Start adding a Window class.
This commit is contained in:
parent
bd6172e3c7
commit
415c4b90c5
|
@ -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)
|
||||||
|
|
|
@ -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&);
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
39
Widgets/Window.cpp
Normal 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
35
Widgets/Window.h
Normal 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 };
|
||||||
|
};
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue