More hacking on Widgets.

This commit is contained in:
Andreas Kling 2018-10-11 16:52:40 +02:00
parent c37ded0ae4
commit a4491e9630
9 changed files with 150 additions and 2 deletions

View file

@ -19,6 +19,7 @@ VFS_OBJS = \
Label.o \
Button.o \
TerminalWidget.o \
WindowManager.o \
test.o
OBJS = $(AK_OBJS) $(VFS_OBJS)

View file

@ -22,6 +22,14 @@ public:
return { x() + width() / 2, y() + height() / 2 };
}
void inflate(int w, int h)
{
setX(x() - w / 2);
setWidth(width() + w);
setY(y() - h / 2);
setHeight(height() + h);
}
bool contains(int x, int y) const
{
return x >= m_location.x() && x <= right() && y >= m_location.y() && y <= bottom();

View file

@ -1,5 +1,6 @@
#include "RootWidget.h"
#include "Painter.h"
#include "WindowManager.h"
#include <cstdio>
RootWidget::RootWidget()
@ -12,15 +13,16 @@ RootWidget::~RootWidget()
void RootWidget::onPaint(PaintEvent& event)
{
printf("RootWidget::onPaint\n");
//printf("RootWidget::onPaint\n");
Painter painter(*this);
painter.fillRect(Rect(0, 0, 800, 600), Color(0x40, 0x40, 0x40));
WindowManager::the().paintWindowFrames();
Widget::onPaint(event);
}
void RootWidget::onMouseMove(MouseEvent& event)
{
printf("RootWidget::onMouseMove: x=%d, y=%d\n", event.x(), event.y());
//printf("RootWidget::onMouseMove: x=%d, y=%d\n", event.x(), event.y());
Widget::onMouseMove(event);
}

View file

@ -11,6 +11,8 @@ TerminalWidget* g_tw;
TerminalWidget::TerminalWidget(Widget* parent)
: Widget(parent)
{
setIsWindow(true);
g_tw = this;
setRect({ 100, 300, columns() * 8, rows() * 10 });

View file

@ -1,6 +1,7 @@
#include "Widget.h"
#include "Event.h"
#include "EventLoop.h"
#include "WindowManager.h"
#include <AK/Assertions.h>
Widget::Widget(Widget* parent)
@ -21,6 +22,17 @@ 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()) {
@ -104,3 +116,10 @@ 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

@ -4,6 +4,7 @@
#include "Object.h"
#include "Rect.h"
#include "Color.h"
#include <AK/String.h>
class Widget : public Object {
public:
@ -45,10 +46,18 @@ public:
void setBackgroundColor(Color color) { m_backgroundColor = color; }
void setForegroundColor(Color color) { m_foregroundColor = color; }
bool isWindow() const { return m_isWindow; }
void setIsWindow(bool);
void setWindowTitle(String&&);
String windowTitle() const { return m_windowTitle; }
private:
Rect m_rect;
Color m_backgroundColor;
Color m_foregroundColor;
String m_windowTitle;
bool m_isWindow { false };
bool m_hasPendingPaintEvent { false };
};

79
Widgets/WindowManager.cpp Normal file
View file

@ -0,0 +1,79 @@
#include "WindowManager.h"
#include "Painter.h"
#include "Widget.h"
#include "AbstractScreen.h"
WindowManager& WindowManager::the()
{
static WindowManager* s_the = new WindowManager;
return *s_the;
}
WindowManager::WindowManager()
{
}
WindowManager::~WindowManager()
{
}
void WindowManager::paintWindowFrames()
{
for (auto* widget : m_windows) {
paintWindowFrame(*widget);
}
}
void WindowManager::paintWindowFrame(Widget& widget)
{
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());
static const int windowFrameWidth = 2;
static const int windowTitleBarHeight = 14;
Rect topRect {
widget.x() - windowFrameWidth,
widget.y() - windowTitleBarHeight - windowFrameWidth,
widget.width() + windowFrameWidth * 2,
windowTitleBarHeight + windowFrameWidth };
Rect bottomRect {
widget.x() - windowFrameWidth,
widget.y() + widget.height(),
widget.width() + windowFrameWidth * 2,
windowFrameWidth };
Rect leftRect {
widget.x() - windowFrameWidth,
widget.y(),
windowFrameWidth,
widget.height()
};
Rect rightRect {
widget.x() + widget.width(),
widget.y(),
windowFrameWidth,
widget.height()
};
p.fillRect(topRect, Color(0x40, 0x40, 0xc0));
p.fillRect(bottomRect, Color(0x40, 0x40, 0xc0));
p.fillRect(leftRect, Color(0x40, 0x40, 0xc0));
p.fillRect(rightRect, Color(0x40, 0x40, 0xc0));
p.drawText(topRect, widget.windowTitle(), Painter::TextAlignment::Center, Color(255, 255, 255));
}
void WindowManager::addWindow(Widget& widget)
{
m_windows.set(&widget);
}
void WindowManager::notifyTitleChanged(Widget&)
{
AbstractScreen::the().rootWidget()->update();
}

24
Widgets/WindowManager.h Normal file
View file

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

View file

@ -4,6 +4,7 @@
#include "Label.h"
#include "Button.h"
#include "TerminalWidget.h"
#include "WindowManager.h"
#include <cstdio>
int main(int c, char** v)
@ -16,6 +17,8 @@ int main(int c, char** v)
RootWidget w;
fb.setRootWidget(&w);
WindowManager::the();
auto* l1 = new Label(&w);
l1->setRect(Rect(100, 100, 300, 20));
l1->setText("0123456789");
@ -37,6 +40,7 @@ int main(int c, char** v)
b->setCaption("Button!");
auto* t = new TerminalWidget(&w);
t->setWindowTitle("Console");
return loop.exec();
}