Rename all the LibGUI classes to GClassName.

This commit is contained in:
Andreas Kling 2019-01-20 04:49:48 +01:00
parent a026da47e7
commit b91479d9b9
Notes: sideshowbarker 2024-07-19 16:00:04 +09:00
33 changed files with 623 additions and 581 deletions

3
LibGUI/.gitignore vendored
View file

@ -1,3 +1,2 @@
*.o
*.swp
test
LibGUI.a

View file

@ -1,27 +0,0 @@
#pragma once
#include "Widget.h"
#include <AK/AKString.h>
#include <AK/Function.h>
class Button final : public Widget {
public:
explicit Button(Widget* parent);
virtual ~Button() override;
String caption() const { return m_caption; }
void setCaption(String&&);
Function<void(Button&)> onClick;
private:
virtual void paintEvent(PaintEvent&) override;
virtual void mouseDownEvent(MouseEvent&) override;
virtual void mouseUpEvent(MouseEvent&) override;
virtual const char* class_name() const override { return "Button"; }
String m_caption;
bool m_beingPressed { false };
};

View file

@ -1,26 +0,0 @@
#pragma once
#include "Widget.h"
#include <AK/AKString.h>
class CheckBox final : public Widget {
public:
explicit CheckBox(Widget* parent);
virtual ~CheckBox() override;
String caption() const { return m_caption; }
void setCaption(String&&);
bool isChecked() const { return m_isChecked; }
void setIsChecked(bool);
private:
virtual void paintEvent(PaintEvent&) override;
virtual void mouseDownEvent(MouseEvent&) override;
virtual const char* class_name() const override { return "CheckBox"; }
String m_caption;
bool m_isChecked { false };
};

View file

@ -1,9 +1,9 @@
#include "ClockWidget.h"
#include "Painter.h"
#include <SharedGraphics/Painter.h>
#include <time.h>
ClockWidget::ClockWidget(Widget* parent)
: Widget(parent)
ClockWidget::ClockWidget(GWidget* parent)
: GWidget(parent)
{
setWindowRelativeRect({ 0, 0, 100, 40 });
startTimer(250);

View file

@ -1,37 +0,0 @@
#pragma once
#include "Event.h"
#include <AK/OwnPtr.h>
#include <AK/Vector.h>
class Object;
class Process;
class EventLoop {
public:
EventLoop();
~EventLoop();
int exec();
void postEvent(Object* receiver, OwnPtr<Event>&&);
static EventLoop& main();
static void initialize();
bool running() const { return m_running; }
Process& server_process() { return *m_server_process; }
private:
void waitForEvent();
struct QueuedEvent {
Object* receiver { nullptr };
OwnPtr<Event> event;
};
Vector<QueuedEvent> m_queuedEvents;
Process* m_server_process { nullptr };
bool m_running { false };
};

View file

@ -1,17 +1,17 @@
#include "Button.h"
#include "GButton.h"
#include <SharedGraphics/Painter.h>
Button::Button(Widget* parent)
: Widget(parent)
GButton::GButton(GWidget* parent)
: GWidget(parent)
{
setFillWithBackgroundColor(false);
}
Button::~Button()
GButton::~GButton()
{
}
void Button::setCaption(String&& caption)
void GButton::setCaption(String&& caption)
{
if (caption == m_caption)
return;
@ -19,7 +19,7 @@ void Button::setCaption(String&& caption)
update();
}
void Button::paintEvent(PaintEvent&)
void GButton::paintEvent(GPaintEvent&)
{
Color buttonColor = Color::LightGray;
Color highlightColor = Color::White;
@ -64,24 +64,24 @@ void Button::paintEvent(PaintEvent&)
}
}
void Button::mouseDownEvent(MouseEvent& event)
void GButton::mouseDownEvent(GMouseEvent& event)
{
dbgprintf("Button::mouseDownEvent: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
m_beingPressed = true;
update();
Widget::mouseDownEvent(event);
GWidget::mouseDownEvent(event);
}
void Button::mouseUpEvent(MouseEvent& event)
void GButton::mouseUpEvent(GMouseEvent& event)
{
dbgprintf("Button::mouseUpEvent: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
m_beingPressed = false;
update();
Widget::mouseUpEvent(event);
GWidget::mouseUpEvent(event);
if (onClick)
onClick(*this);

27
LibGUI/GButton.h Normal file
View file

@ -0,0 +1,27 @@
#pragma once
#include "GWidget.h"
#include <AK/AKString.h>
#include <AK/Function.h>
class GButton final : public GWidget {
public:
explicit GButton(GWidget* parent);
virtual ~GButton() override;
String caption() const { return m_caption; }
void setCaption(String&&);
Function<void(GButton&)> onClick;
private:
virtual void paintEvent(GPaintEvent&) override;
virtual void mouseDownEvent(GMouseEvent&) override;
virtual void mouseUpEvent(GMouseEvent&) override;
virtual const char* class_name() const override { return "Button"; }
String m_caption;
bool m_beingPressed { false };
};

View file

@ -1,17 +1,17 @@
#include "CheckBox.h"
#include "GCheckBox.h"
#include <SharedGraphics/Painter.h>
#include <SharedGraphics/CharacterBitmap.h>
CheckBox::CheckBox(Widget* parent)
: Widget(parent)
GCheckBox::GCheckBox(GWidget* parent)
: GWidget(parent)
{
}
CheckBox::~CheckBox()
GCheckBox::~GCheckBox()
{
}
void CheckBox::setCaption(String&& caption)
void GCheckBox::setCaption(String&& caption)
{
if (caption == m_caption)
return;
@ -19,7 +19,7 @@ void CheckBox::setCaption(String&& caption)
update();
}
void CheckBox::setIsChecked(bool b)
void GCheckBox::setIsChecked(bool b)
{
if (m_isChecked == b)
return;
@ -72,7 +72,7 @@ static const char* checkedBitmap = {
"###########"
};
void CheckBox::paintEvent(PaintEvent&)
void GCheckBox::paintEvent(GPaintEvent&)
{
Painter painter(*this);
auto bitmap = CharacterBitmap::create_from_ascii(isChecked() ? checkedBitmap : uncheckedBitmap, 11, 11);
@ -93,9 +93,9 @@ void CheckBox::paintEvent(PaintEvent&)
}
}
void CheckBox::mouseDownEvent(MouseEvent& event)
void GCheckBox::mouseDownEvent(GMouseEvent& event)
{
dbgprintf("CheckBox::mouseDownEvent: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
dbgprintf("GCheckBox::mouseDownEvent: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
setIsChecked(!isChecked());
}

26
LibGUI/GCheckBox.h Normal file
View file

@ -0,0 +1,26 @@
#pragma once
#include "GWidget.h"
#include <AK/AKString.h>
class GCheckBox final : public GWidget {
public:
explicit GCheckBox(GWidget* parent);
virtual ~GCheckBox() override;
String caption() const { return m_caption; }
void setCaption(String&&);
bool isChecked() const { return m_isChecked; }
void setIsChecked(bool);
private:
virtual void paintEvent(GPaintEvent&) override;
virtual void mouseDownEvent(GMouseEvent&) override;
virtual const char* class_name() const override { return "GCheckBox"; }
String m_caption;
bool m_isChecked { false };
};

View file

@ -20,7 +20,7 @@ static const char* eventNames[] = {
"DeferredDestroy",
};
class Event {
class GEvent {
public:
enum Type {
Invalid = 0,
@ -37,12 +37,11 @@ public:
DeferredDestroy,
WindowBecameInactive,
WindowBecameActive,
WM_Compose,
};
Event() { }
explicit Event(Type type) : m_type(type) { }
virtual ~Event() { }
GEvent() { }
explicit GEvent(Type type) : m_type(type) { }
virtual ~GEvent() { }
Type type() const { return m_type; }
@ -56,60 +55,51 @@ private:
Type m_type { Invalid };
};
class DeferredDestroyEvent final : public Event {
public:
DeferredDestroyEvent()
: Event(Event::DeferredDestroy)
{
}
};
class QuitEvent final : public Event {
class QuitEvent final : public GEvent {
public:
QuitEvent()
: Event(Event::Quit)
: GEvent(GEvent::Quit)
{
}
};
class PaintEvent final : public Event {
class GPaintEvent final : public GEvent {
public:
explicit PaintEvent(const Rect& rect = Rect())
: Event(Event::Paint)
explicit GPaintEvent(const Rect& rect = Rect())
: GEvent(GEvent::Paint)
, m_rect(rect)
{
}
const Rect& rect() const { return m_rect; }
private:
friend class WindowManager;
Rect m_rect;
};
class ShowEvent final : public Event {
class GShowEvent final : public GEvent {
public:
ShowEvent()
: Event(Event::Show)
GShowEvent()
: GEvent(GEvent::Show)
{
}
};
class HideEvent final : public Event {
class GHideEvent final : public GEvent {
public:
HideEvent()
: Event(Event::Hide)
GHideEvent()
: GEvent(GEvent::Hide)
{
}
};
enum class MouseButton : byte {
enum class GMouseButton : byte {
None = 0,
Left,
Middle,
Right,
};
enum KeyboardKey {
enum GKeyboardKey {
Invalid,
LeftArrow,
RightArrow,
@ -119,10 +109,10 @@ enum KeyboardKey {
Return,
};
class KeyEvent final : public Event {
class GKeyEvent final : public GEvent {
public:
KeyEvent(Type type, int key)
: Event(type)
GKeyEvent(Type type, int key)
: GEvent(type)
, m_key(key)
{
}
@ -134,8 +124,7 @@ public:
String text() const { return m_text; }
private:
friend class EventLoop;
friend class AbstractScreen;
friend class GEventLoop;
int m_key { 0 };
bool m_ctrl { false };
bool m_alt { false };
@ -143,10 +132,10 @@ private:
String m_text;
};
class MouseEvent final : public Event {
class GMouseEvent final : public GEvent {
public:
MouseEvent(Type type, int x, int y, MouseButton button = MouseButton::None)
: Event(type)
GMouseEvent(Type type, int x, int y, GMouseButton button = GMouseButton::None)
: GEvent(type)
, m_position(x, y)
, m_button(button)
{
@ -155,16 +144,16 @@ public:
Point position() const { return m_position; }
int x() const { return m_position.x(); }
int y() const { return m_position.y(); }
MouseButton button() const { return m_button; }
GMouseButton button() const { return m_button; }
private:
Point m_position;
MouseButton m_button { MouseButton::None };
GMouseButton m_button { GMouseButton::None };
};
class TimerEvent final : public Event {
class GTimerEvent final : public GEvent {
public:
TimerEvent() : Event(Event::Timer) { }
~TimerEvent() { }
GTimerEvent() : GEvent(GEvent::Timer) { }
~GTimerEvent() { }
};

View file

@ -1,31 +1,31 @@
#include "EventLoop.h"
#include "Event.h"
#include "Object.h"
#include "GEventLoop.h"
#include "GEvent.h"
#include "GObject.h"
static EventLoop* s_mainEventLoop;
static GEventLoop* s_mainGEventLoop;
void EventLoop::initialize()
void GEventLoop::initialize()
{
s_mainEventLoop = nullptr;
s_mainGEventLoop = nullptr;
}
EventLoop::EventLoop()
GEventLoop::GEventLoop()
{
if (!s_mainEventLoop)
s_mainEventLoop = this;
if (!s_mainGEventLoop)
s_mainGEventLoop = this;
}
EventLoop::~EventLoop()
GEventLoop::~GEventLoop()
{
}
EventLoop& EventLoop::main()
GEventLoop& GEventLoop::main()
{
ASSERT(s_mainEventLoop);
return *s_mainEventLoop;
ASSERT(s_mainGEventLoop);
return *s_mainGEventLoop;
}
int EventLoop::exec()
int GEventLoop::exec()
{
m_running = true;
for (;;) {
@ -38,10 +38,10 @@ int EventLoop::exec()
for (auto& queuedEvent : events) {
auto* receiver = queuedEvent.receiver;
auto& event = *queuedEvent.event;
//printf("EventLoop: Object{%p} event %u (%s)\n", receiver, (unsigned)event.type(), event.name());
//printf("GEventLoop: GObject{%p} event %u (%s)\n", receiver, (unsigned)event.type(), event.name());
if (!receiver) {
switch (event.type()) {
case Event::Quit:
case GEvent::Quit:
ASSERT_NOT_REACHED();
return 0;
default:
@ -56,12 +56,12 @@ int EventLoop::exec()
}
}
void EventLoop::postEvent(Object* receiver, OwnPtr<Event>&& event)
void GEventLoop::postEvent(GObject* receiver, OwnPtr<GEvent>&& event)
{
//printf("EventLoop::postEvent: {%u} << receiver=%p, event=%p\n", m_queuedEvents.size(), receiver, event.ptr());
//printf("GEventLoop::postGEvent: {%u} << receiver=%p, event=%p\n", m_queuedEvents.size(), receiver, event.ptr());
m_queuedEvents.append({ receiver, move(event) });
}
void EventLoop::waitForEvent()
void GEventLoop::waitForEvent()
{
}

34
LibGUI/GEventLoop.h Normal file
View file

@ -0,0 +1,34 @@
#pragma once
#include "GEvent.h"
#include <AK/OwnPtr.h>
#include <AK/Vector.h>
class GObject;
class GEventLoop {
public:
GEventLoop();
~GEventLoop();
int exec();
void postEvent(GObject* receiver, OwnPtr<GEvent>&&);
static GEventLoop& main();
static void initialize();
bool running() const { return m_running; }
private:
void waitForEvent();
struct QueuedEvent {
GObject* receiver { nullptr };
OwnPtr<GEvent> event;
};
Vector<QueuedEvent> m_queuedEvents;
bool m_running { false };
};

View file

@ -1,16 +1,16 @@
#include "Label.h"
#include "GLabel.h"
#include <SharedGraphics/Painter.h>
Label::Label(Widget* parent)
: Widget(parent)
GLabel::GLabel(GWidget* parent)
: GWidget(parent)
{
}
Label::~Label()
GLabel::~GLabel()
{
}
void Label::setText(String&& text)
void GLabel::setText(String&& text)
{
if (text == m_text)
return;
@ -18,7 +18,7 @@ void Label::setText(String&& text)
update();
}
void Label::paintEvent(PaintEvent&)
void GLabel::paintEvent(GPaintEvent&)
{
Painter painter(*this);
if (fillWithBackgroundColor())
@ -27,9 +27,9 @@ void Label::paintEvent(PaintEvent&)
painter.draw_text({ 4, 4, width(), height() }, text(), Painter::TextAlignment::TopLeft, foregroundColor());
}
void Label::mouseMoveEvent(MouseEvent& event)
void GLabel::mouseMoveEvent(GMouseEvent& event)
{
dbgprintf("Label::mouseMoveEvent: x=%d, y=%d\n", event.x(), event.y());
Widget::mouseMoveEvent(event);
dbgprintf("GLabel::mouseMoveEvent: x=%d, y=%d\n", event.x(), event.y());
GWidget::mouseMoveEvent(event);
}

22
LibGUI/GLabel.h Normal file
View file

@ -0,0 +1,22 @@
#pragma once
#include "GWidget.h"
#include <AK/AKString.h>
class GLabel final : public GWidget {
public:
explicit GLabel(GWidget* parent);
virtual ~GLabel() override;
String text() const { return m_text; }
void setText(String&&);
private:
virtual void paintEvent(GPaintEvent&) override;
virtual void mouseMoveEvent(GMouseEvent&) override;
virtual const char* class_name() const override { return "GLabel"; }
String m_text;
};

View file

@ -1,24 +1,23 @@
#include "ListBox.h"
#include "Window.h"
#include "GListBox.h"
#include <SharedGraphics/Font.h>
#include <SharedGraphics/Painter.h>
ListBox::ListBox(Widget* parent)
: Widget(parent)
GListBox::GListBox(GWidget* parent)
: GWidget(parent)
{
}
ListBox::~ListBox()
GListBox::~GListBox()
{
}
Rect ListBox::item_rect(int index) const
Rect GListBox::item_rect(int index) const
{
int item_height = font().glyph_height() + 2;
return Rect { 2, 2 + (index * item_height), width() - 4, item_height };
}
void ListBox::paintEvent(PaintEvent&)
void GListBox::paintEvent(GPaintEvent&)
{
Painter painter(*this);
@ -45,21 +44,21 @@ void ListBox::paintEvent(PaintEvent&)
}
}
void ListBox::mouseDownEvent(MouseEvent& event)
void GListBox::mouseDownEvent(GMouseEvent& event)
{
dbgprintf("ListBox::mouseDownEvent %d,%d\n", event.x(), event.y());
dbgprintf("GListBox::mouseDownEvent %d,%d\n", event.x(), event.y());
for (int i = m_scrollOffset; i < static_cast<int>(m_items.size()); ++i) {
auto itemRect = item_rect(i);
if (itemRect.contains(event.position())) {
m_selectedIndex = i;
dbgprintf("ListBox: selected item %u (\"%s\")\n", i, m_items[i].characters());
dbgprintf("GListBox: selected item %u (\"%s\")\n", i, m_items[i].characters());
update();
return;
}
}
}
void ListBox::addItem(String&& item)
void GListBox::addItem(String&& item)
{
m_items.append(move(item));
if (m_selectedIndex == -1)

25
LibGUI/GListBox.h Normal file
View file

@ -0,0 +1,25 @@
#pragma once
#include "GWidget.h"
class GListBox final : public GWidget {
public:
explicit GListBox(GWidget* parent);
virtual ~GListBox() override;
void addItem(String&&);
int selectedIndex() const { return m_selectedIndex; }
private:
virtual void paintEvent(GPaintEvent&) override;
virtual void mouseDownEvent(GMouseEvent&) override;
virtual const char* class_name() const override { return "GListBox"; }
Rect item_rect(int index) const;
int m_scrollOffset { 0 };
int m_selectedIndex { -1 };
Vector<String> m_items;
};

View file

@ -1,16 +1,16 @@
#include "Object.h"
#include "Event.h"
#include "EventLoop.h"
#include "GObject.h"
#include "GEvent.h"
#include "GEventLoop.h"
#include <AK/Assertions.h>
Object::Object(Object* parent)
GObject::GObject(GObject* parent)
: m_parent(parent)
{
if (m_parent)
m_parent->addChild(*this);
}
Object::~Object()
GObject::~GObject()
{
if (m_parent)
m_parent->removeChild(*this);
@ -19,15 +19,15 @@ Object::~Object()
delete child;
}
void Object::event(Event& event)
void GObject::event(GEvent& event)
{
switch (event.type()) {
case Event::Timer:
return timerEvent(static_cast<TimerEvent&>(event));
case Event::DeferredDestroy:
case GEvent::Timer:
return timerEvent(static_cast<GTimerEvent&>(event));
case GEvent::DeferredDestroy:
delete this;
break;
case Event::Invalid:
case GEvent::Invalid:
ASSERT_NOT_REACHED();
break;
default:
@ -35,12 +35,12 @@ void Object::event(Event& event)
}
}
void Object::addChild(Object& object)
void GObject::addChild(GObject& object)
{
m_children.append(&object);
}
void Object::removeChild(Object& object)
void GObject::removeChild(GObject& object)
{
for (unsigned i = 0; i < m_children.size(); ++i) {
if (m_children[i] == &object) {
@ -50,27 +50,27 @@ void Object::removeChild(Object& object)
}
}
void Object::timerEvent(TimerEvent&)
void GObject::timerEvent(GTimerEvent&)
{
}
void Object::startTimer(int ms)
void GObject::startTimer(int ms)
{
if (m_timerID) {
dbgprintf("Object{%p} already has a timer!\n", this);
dbgprintf("GObject{%p} already has a timer!\n", this);
ASSERT_NOT_REACHED();
}
}
void Object::stopTimer()
void GObject::stopTimer()
{
if (!m_timerID)
return;
m_timerID = 0;
}
void Object::deleteLater()
void GObject::deleteLater()
{
EventLoop::main().postEvent(this, make<DeferredDestroyEvent>());
GEventLoop::main().postEvent(this, make<GEvent>(GEvent::DeferredDestroy));
}

40
LibGUI/GObject.h Normal file
View file

@ -0,0 +1,40 @@
#pragma once
#include <AK/Vector.h>
#include <AK/Weakable.h>
class GEvent;
class GTimerEvent;
class GObject : public Weakable<GObject> {
public:
GObject(GObject* parent = nullptr);
virtual ~GObject();
virtual const char* class_name() const { return "GObject"; }
virtual void event(GEvent&);
Vector<GObject*>& children() { return m_children; }
GObject* parent() { return m_parent; }
const GObject* parent() const { return m_parent; }
void startTimer(int ms);
void stopTimer();
bool hasTimer() const { return m_timerID; }
void addChild(GObject&);
void removeChild(GObject&);
void deleteLater();
private:
virtual void timerEvent(GTimerEvent&);
GObject* m_parent { nullptr };
int m_timerID { 0 };
Vector<GObject*> m_children;
};

View file

@ -1,27 +1,27 @@
#include "TextBox.h"
#include "GTextBox.h"
#include <AK/StdLibExtras.h>
#include <SharedGraphics/CharacterBitmap.h>
#include <SharedGraphics/Font.h>
#include <SharedGraphics/Painter.h>
TextBox::TextBox(Widget* parent)
: Widget(parent)
GTextBox::GTextBox(GWidget* parent)
: GWidget(parent)
{
startTimer(500);
}
TextBox::~TextBox()
GTextBox::~GTextBox()
{
}
void TextBox::setText(String&& text)
void GTextBox::setText(String&& text)
{
m_text = move(text);
m_cursorPosition = m_text.length();
update();
}
void TextBox::paintEvent(PaintEvent&)
void GTextBox::paintEvent(GPaintEvent&)
{
Painter painter(*this);
@ -48,7 +48,7 @@ void TextBox::paintEvent(PaintEvent&)
int x = innerRect.x() + (i * font().glyph_width());
auto* bitmap = font().glyph_bitmap(ch);
if (!bitmap) {
dbgprintf("TextBox: glyph missing: %02x\n", ch);
dbgprintf("GTextBox: glyph missing: %02x\n", ch);
ASSERT_NOT_REACHED();
}
painter.draw_bitmap({x, y}, *bitmap, Color::Black);
@ -61,11 +61,11 @@ void TextBox::paintEvent(PaintEvent&)
}
}
void TextBox::mouseDownEvent(MouseEvent&)
void GTextBox::mouseDownEvent(GMouseEvent&)
{
}
void TextBox::handleBackspace()
void GTextBox::handleBackspace()
{
if (m_cursorPosition == 0)
return;
@ -88,24 +88,24 @@ void TextBox::handleBackspace()
update();
}
void TextBox::keyDownEvent(KeyEvent& event)
void GTextBox::keyDownEvent(GKeyEvent& event)
{
switch (event.key()) {
case KeyboardKey::LeftArrow:
case GKeyboardKey::LeftArrow:
if (m_cursorPosition)
--m_cursorPosition;
m_cursorBlinkState = true;
update();
return;
case KeyboardKey::RightArrow:
case GKeyboardKey::RightArrow:
if (m_cursorPosition < m_text.length())
++m_cursorPosition;
m_cursorBlinkState = true;
update();
return;
case KeyboardKey::Backspace:
case GKeyboardKey::Backspace:
return handleBackspace();
case KeyboardKey::Return:
case GKeyboardKey::Return:
if (onReturnPressed)
onReturnPressed(*this);
return;
@ -128,7 +128,7 @@ void TextBox::keyDownEvent(KeyEvent& event)
}
}
void TextBox::timerEvent(TimerEvent&)
void GTextBox::timerEvent(GTimerEvent&)
{
// FIXME: Disable the timer when not focused.
if (!isFocused())

29
LibGUI/GTextBox.h Normal file
View file

@ -0,0 +1,29 @@
#pragma once
#include "GWidget.h"
#include <AK/Function.h>
class GTextBox final : public GWidget {
public:
explicit GTextBox(GWidget* parent);
virtual ~GTextBox() override;
String text() const { return m_text; }
void setText(String&&);
Function<void(GTextBox&)> onReturnPressed;
private:
virtual const char* class_name() const override { return "GTextBox"; }
virtual void paintEvent(GPaintEvent&) override;
virtual void mouseDownEvent(GMouseEvent&) override;
virtual void keyDownEvent(GKeyEvent&) override;
virtual void timerEvent(GTimerEvent&) override;
void handleBackspace();
String m_text;
unsigned m_cursorPosition { 0 };
bool m_cursorBlinkState { false };
};

163
LibGUI/GWidget.cpp Normal file
View file

@ -0,0 +1,163 @@
#include "GWidget.h"
#include "GEvent.h"
#include "GEventLoop.h"
#include "GWindow.h"
#include <AK/Assertions.h>
#include <SharedGraphics/GraphicsBitmap.h>
#include <SharedGraphics/Painter.h>
GWidget::GWidget(GWidget* parent)
: GObject(parent)
{
setFont(nullptr);
m_backgroundColor = Color::White;
m_foregroundColor = Color::Black;
}
GWidget::~GWidget()
{
}
void GWidget::setWindowRelativeRect(const Rect& rect, bool should_update)
{
// FIXME: Make some kind of event loop driven ResizeEvent?
m_relativeRect = rect;
if (should_update)
update();
}
void GWidget::repaint(const Rect& rect)
{
// FIXME: Implement.
}
void GWidget::event(GEvent& event)
{
switch (event.type()) {
case GEvent::Paint:
m_hasPendingPaintEvent = false;
if (auto* win = window()) {
if (win->is_being_dragged())
return;
if (!win->is_visible())
return;
}
return paintEvent(static_cast<GPaintEvent&>(event));
case GEvent::Show:
return showEvent(static_cast<GShowEvent&>(event));
case GEvent::Hide:
return hideEvent(static_cast<GHideEvent&>(event));
case GEvent::KeyDown:
return keyDownEvent(static_cast<GKeyEvent&>(event));
case GEvent::KeyUp:
return keyUpEvent(static_cast<GKeyEvent&>(event));
case GEvent::MouseMove:
return mouseMoveEvent(static_cast<GMouseEvent&>(event));
case GEvent::MouseDown:
// FIXME: Focus self if needed.
return mouseDownEvent(static_cast<GMouseEvent&>(event));
case GEvent::MouseUp:
return mouseUpEvent(static_cast<GMouseEvent&>(event));
default:
return GObject::event(event);
}
}
void GWidget::paintEvent(GPaintEvent& event)
{
//printf("GWidget::paintEvent :)\n");
if (fillWithBackgroundColor()) {
Painter painter(*this);
painter.fill_rect(rect(), backgroundColor());
}
for (auto* ch : children()) {
auto* child = (GWidget*)ch;
child->event(event);
}
}
void GWidget::showEvent(GShowEvent&)
{
}
void GWidget::hideEvent(GHideEvent&)
{
}
void GWidget::keyDownEvent(GKeyEvent&)
{
}
void GWidget::keyUpEvent(GKeyEvent&)
{
}
void GWidget::mouseDownEvent(GMouseEvent&)
{
}
void GWidget::mouseUpEvent(GMouseEvent&)
{
}
void GWidget::mouseMoveEvent(GMouseEvent&)
{
}
void GWidget::update()
{
auto* w = window();
if (!w)
return;
if (m_hasPendingPaintEvent)
return;
m_hasPendingPaintEvent = true;
GEventLoop::main().postEvent(w, make<GPaintEvent>(relativeRect()));
}
GWidget::HitTestResult GWidget::hitTest(int x, int y)
{
// FIXME: Care about z-order.
for (auto* ch : children()) {
auto* child = (GWidget*)ch;
if (child->relativeRect().contains(x, y)) {
return child->hitTest(x - child->relativeRect().x(), y - child->relativeRect().y());
}
}
return { this, x, y };
}
void GWidget::setWindow(GWindow* window)
{
if (m_window == window)
return;
m_window = window;
}
bool GWidget::isFocused() const
{
// FIXME: Implement.
return false;
}
void GWidget::setFocus(bool focus)
{
if (focus == isFocused())
return;
// FIXME: Implement.
}
void GWidget::setFont(RetainPtr<Font>&& font)
{
if (!font)
m_font = Font::default_font();
else
m_font = move(font);
}
GraphicsBitmap* GWidget::backing()
{
if (auto* w = window())
return w->backing();
return nullptr;
}

View file

@ -1,29 +1,29 @@
#pragma once
#include "Event.h"
#include "Object.h"
#include "GEvent.h"
#include "GObject.h"
#include <SharedGraphics/Rect.h>
#include <SharedGraphics/Color.h>
#include <SharedGraphics/Font.h>
#include <AK/AKString.h>
class GraphicsBitmap;
class Window;
class GWindow;
class Widget : public Object {
class GWidget : public GObject {
public:
explicit Widget(Widget* parent = nullptr);
virtual ~Widget();
explicit GWidget(GWidget* parent = nullptr);
virtual ~GWidget();
virtual void event(Event&) override;
virtual void paintEvent(PaintEvent&);
virtual void showEvent(ShowEvent&);
virtual void hideEvent(HideEvent&);
virtual void keyDownEvent(KeyEvent&);
virtual void keyUpEvent(KeyEvent&);
virtual void mouseMoveEvent(MouseEvent&);
virtual void mouseDownEvent(MouseEvent&);
virtual void mouseUpEvent(MouseEvent&);
virtual void event(GEvent&) override;
virtual void paintEvent(GPaintEvent&);
virtual void showEvent(GShowEvent&);
virtual void hideEvent(GHideEvent&);
virtual void keyDownEvent(GKeyEvent&);
virtual void keyUpEvent(GKeyEvent&);
virtual void mouseMoveEvent(GMouseEvent&);
virtual void mouseDownEvent(GMouseEvent&);
virtual void mouseUpEvent(GMouseEvent&);
Rect relativeRect() const { return m_relativeRect; }
Point relativePosition() const { return m_relativeRect.location(); }
@ -43,13 +43,13 @@ public:
void setFocus(bool);
struct HitTestResult {
Widget* widget { nullptr };
GWidget* widget { nullptr };
int localX { 0 };
int localY { 0 };
};
HitTestResult hitTest(int x, int y);
virtual const char* class_name() const override { return "Widget"; }
virtual const char* class_name() const override { return "GWidget"; }
void setWindowRelativeRect(const Rect&, bool should_update = true);
@ -59,24 +59,24 @@ public:
void setBackgroundColor(Color color) { m_backgroundColor = color; }
void setForegroundColor(Color color) { m_foregroundColor = color; }
Window* window()
GWindow* window()
{
if (auto* pw = parentWidget())
return pw->window();
return m_window;
}
const Window* window() const
const GWindow* window() const
{
if (auto* pw = parentWidget())
return pw->window();
return m_window;
}
void setWindow(Window*);
void setWindow(GWindow*);
Widget* parentWidget() { return static_cast<Widget*>(parent()); }
const Widget* parentWidget() const { return static_cast<const Widget*>(parent()); }
GWidget* parentWidget() { return static_cast<GWidget*>(parent()); }
const GWidget* parentWidget() const { return static_cast<const GWidget*>(parent()); }
void setFillWithBackgroundColor(bool b) { m_fillWithBackgroundColor = b; }
bool fillWithBackgroundColor() const { return m_fillWithBackgroundColor; }
@ -87,7 +87,7 @@ public:
virtual GraphicsBitmap* backing();
private:
Window* m_window { nullptr };
GWindow* m_window { nullptr };
Rect m_relativeRect;
Color m_backgroundColor { 0xffffff };

42
LibGUI/GWindow.cpp Normal file
View file

@ -0,0 +1,42 @@
#include "GWindow.h"
#include "GEvent.h"
#include "GEventLoop.h"
#include <SharedGraphics/GraphicsBitmap.h>
GWindow::GWindow(int window_id)
: m_window_id(window_id)
{
}
GWindow::~GWindow()
{
}
void GWindow::set_title(String&& title)
{
if (m_title == title)
return;
m_title = move(title);
}
void GWindow::set_rect(const Rect& rect)
{
if (m_rect == rect)
return;
m_rect = rect;
dbgprintf("GWindow::setRect %d,%d %dx%d\n", m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height());
}
void GWindow::event(GEvent& event)
{
}
bool GWindow::is_visible() const
{
return false;
}
void GWindow::close()
{
}

View file

@ -1,14 +1,14 @@
#pragma once
#include "Object.h"
#include "GObject.h"
#include <SharedGraphics/Rect.h>
#include <SharedGraphics/GraphicsBitmap.h>
#include <AK/AKString.h>
class Window final : public Object {
class GWindow final : public GObject {
public:
explicit Window(int window_id);
virtual ~Window() override;
explicit GWindow(int window_id);
virtual ~GWindow() override;
int window_id() const { return m_window_id; }
@ -27,7 +27,7 @@ public:
Point position() const { return m_rect.location(); }
void set_position_without_repaint(const Point& position) { set_rect_without_repaint({ position.x(), position.y(), width(), height() }); }
virtual void event(Event&) override;
virtual void event(GEvent&) override;
bool is_being_dragged() const { return m_is_being_dragged; }
void set_is_being_dragged(bool b) { m_is_being_dragged = b; }

View file

@ -1,22 +0,0 @@
#pragma once
#include "Widget.h"
#include <AK/AKString.h>
class Label final : public Widget {
public:
explicit Label(Widget* parent);
virtual ~Label() override;
String text() const { return m_text; }
void setText(String&&);
private:
virtual void paintEvent(PaintEvent&) override;
virtual void mouseMoveEvent(MouseEvent&) override;
virtual const char* class_name() const override { return "Label"; }
String m_text;
};

View file

@ -1,25 +0,0 @@
#pragma once
#include "Widget.h"
class ListBox final : public Widget {
public:
explicit ListBox(Widget* parent);
virtual ~ListBox() override;
void addItem(String&&);
int selectedIndex() const { return m_selectedIndex; }
private:
virtual void paintEvent(PaintEvent&) override;
virtual void mouseDownEvent(MouseEvent&) override;
virtual const char* class_name() const override { return "ListBox"; }
Rect item_rect(int index) const;
int m_scrollOffset { 0 };
int m_selectedIndex { -1 };
Vector<String> m_items;
};

51
LibGUI/Makefile Normal file
View file

@ -0,0 +1,51 @@
SHAREDGRAPHICS_OBJS = \
../SharedGraphics/Painter.o \
../SharedGraphics/Font.o \
../SharedGraphics/Rect.o \
../SharedGraphics/GraphicsBitmap.o \
../SharedGraphics/CharacterBitmap.o \
../SharedGraphics/Color.o
LIBGUI_OBJS = \
GButton.o \
GCheckBox.o \
GEventLoop.o \
GLabel.o \
GListBox.o \
GObject.o \
GTextBox.o \
GWidget.o \
GWindow.o
OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)
LIBS = ../LibC/LibC.a
LIBRARY = LibGUI.a
ARCH_FLAGS =
STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib -nostdinc
LIBC_FLAGS = -ffreestanding -fno-stack-protector -fno-ident
WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings
FLAVOR_FLAGS = -fomit-frame-pointer -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -fmerge-all-constants -fno-unroll-loops -fno-pie -fno-pic
OPTIMIZATION_FLAGS = -Oz -fno-asynchronous-unwind-tables
INCLUDE_FLAGS = -I../LibC -I.. -I.
DEFINES = -DSERENITY -DUSERLAND -DSANITIZE_PTRS -DLIBGUI
CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(LIBC_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES)
CXX = clang
LD = ld
AR = ar
LDFLAGS = -T linker.ld --strip-debug -melf_i386 --gc-sections --build-id=none -z norelro -z now
all: $(LIBRARY)
$(LIBRARY): $(OBJS)
@echo "LIB $@"; $(AR) rcs $@ $(OBJS) $(LIBS)
.cpp.o:
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
clean:
@echo "CLEAN"; rm -f $(LIBRARY) $(OBJS)

View file

@ -1,40 +0,0 @@
#pragma once
#include <AK/Vector.h>
#include <AK/Weakable.h>
class Event;
class TimerEvent;
class Object : public Weakable<Object> {
public:
Object(Object* parent = nullptr);
virtual ~Object();
virtual const char* class_name() const { return "Object"; }
virtual void event(Event&);
Vector<Object*>& children() { return m_children; }
Object* parent() { return m_parent; }
const Object* parent() const { return m_parent; }
void startTimer(int ms);
void stopTimer();
bool hasTimer() const { return m_timerID; }
void addChild(Object&);
void removeChild(Object&);
void deleteLater();
private:
virtual void timerEvent(TimerEvent&);
Object* m_parent { nullptr };
int m_timerID { 0 };
Vector<Object*> m_children;
};

View file

@ -1,29 +0,0 @@
#pragma once
#include "Widget.h"
#include <AK/Function.h>
class TextBox final : public Widget {
public:
explicit TextBox(Widget* parent = nullptr);
virtual ~TextBox() override;
String text() const { return m_text; }
void setText(String&&);
Function<void(TextBox&)> onReturnPressed;
private:
virtual const char* class_name() const override { return "TextBox"; }
virtual void paintEvent(PaintEvent&) override;
virtual void mouseDownEvent(MouseEvent&) override;
virtual void keyDownEvent(KeyEvent&) override;
virtual void timerEvent(TimerEvent&) override;
void handleBackspace();
String m_text;
unsigned m_cursorPosition { 0 };
bool m_cursorBlinkState { false };
};

View file

@ -1,163 +0,0 @@
#include "Widget.h"
#include "Event.h"
#include "EventLoop.h"
#include "Window.h"
#include <AK/Assertions.h>
#include <SharedGraphics/GraphicsBitmap.h>
#include <SharedGraphics/Painter.h>
Widget::Widget(Widget* parent)
: Object(parent)
{
setFont(nullptr);
m_backgroundColor = Color::White;
m_foregroundColor = Color::Black;
}
Widget::~Widget()
{
}
void Widget::setWindowRelativeRect(const Rect& rect, bool should_update)
{
// FIXME: Make some kind of event loop driven ResizeEvent?
m_relativeRect = rect;
if (should_update)
update();
}
void Widget::repaint(const Rect& rect)
{
// FIXME: Implement.
}
void Widget::event(Event& event)
{
switch (event.type()) {
case Event::Paint:
m_hasPendingPaintEvent = false;
if (auto* win = window()) {
if (win->is_being_dragged())
return;
if (!win->is_visible())
return;
}
return paintEvent(static_cast<PaintEvent&>(event));
case Event::Show:
return showEvent(static_cast<ShowEvent&>(event));
case Event::Hide:
return hideEvent(static_cast<HideEvent&>(event));
case Event::KeyDown:
return keyDownEvent(static_cast<KeyEvent&>(event));
case Event::KeyUp:
return keyUpEvent(static_cast<KeyEvent&>(event));
case Event::MouseMove:
return mouseMoveEvent(static_cast<MouseEvent&>(event));
case Event::MouseDown:
// FIXME: Focus self if needed.
return mouseDownEvent(static_cast<MouseEvent&>(event));
case Event::MouseUp:
return mouseUpEvent(static_cast<MouseEvent&>(event));
default:
return Object::event(event);
}
}
void Widget::paintEvent(PaintEvent& event)
{
//printf("Widget::paintEvent :)\n");
if (fillWithBackgroundColor()) {
Painter painter(*this);
painter.fill_rect(rect(), backgroundColor());
}
for (auto* ch : children()) {
auto* child = (Widget*)ch;
child->event(event);
}
}
void Widget::showEvent(ShowEvent&)
{
}
void Widget::hideEvent(HideEvent&)
{
}
void Widget::keyDownEvent(KeyEvent&)
{
}
void Widget::keyUpEvent(KeyEvent&)
{
}
void Widget::mouseDownEvent(MouseEvent&)
{
}
void Widget::mouseUpEvent(MouseEvent&)
{
}
void Widget::mouseMoveEvent(MouseEvent&)
{
}
void Widget::update()
{
auto* w = window();
if (!w)
return;
if (m_hasPendingPaintEvent)
return;
m_hasPendingPaintEvent = true;
EventLoop::main().postEvent(w, make<PaintEvent>(relativeRect()));
}
Widget::HitTestResult Widget::hitTest(int x, int y)
{
// FIXME: Care about z-order.
for (auto* ch : children()) {
auto* child = (Widget*)ch;
if (child->relativeRect().contains(x, y)) {
return child->hitTest(x - child->relativeRect().x(), y - child->relativeRect().y());
}
}
return { this, x, y };
}
void Widget::setWindow(Window* window)
{
if (m_window == window)
return;
m_window = window;
}
bool Widget::isFocused() const
{
// FIXME: Implement.
return false;
}
void Widget::setFocus(bool focus)
{
if (focus == isFocused())
return;
// FIXME: Implement.
}
void Widget::setFont(RetainPtr<Font>&& font)
{
if (!font)
m_font = Font::default_font();
else
m_font = move(font);
}
GraphicsBitmap* Widget::backing()
{
if (auto* w = window())
return w->backing();
return nullptr;
}

View file

@ -1,42 +0,0 @@
#include "Window.h"
#include "Event.h"
#include "EventLoop.h"
#include <SharedGraphics/GraphicsBitmap.h>
Window::Window(int window_id)
: m_window_id(window_id)
{
}
Window::~Window()
{
}
void Window::set_title(String&& title)
{
if (m_title == title)
return;
m_title = move(title);
}
void Window::set_rect(const Rect& rect)
{
if (m_rect == rect)
return;
m_rect = rect;
dbgprintf("Window::setRect %d,%d %dx%d\n", m_rect.x(), m_rect.y(), m_rect.width(), m_rect.height());
}
void Window::event(Event& event)
{
}
bool Window::is_visible() const
{
return false;
}
void Window::close()
{
}

View file

@ -5,7 +5,7 @@
#include <AK/StdLibExtras.h>
#ifdef LIBGUI
#include <LibGUI/Widget.h>
#include <LibGUI/GWidget.h>
#endif
#define DEBUG_WIDGET_UNDERDRAW
@ -18,7 +18,7 @@ Painter::Painter(GraphicsBitmap& bitmap)
}
#ifdef LIBGUI
Painter::Painter(Widget& widget)
Painter::Painter(GWidget& widget)
: m_font(&widget.font())
{
m_target = widget.backing();

View file

@ -9,12 +9,17 @@
class CharacterBitmap;
class GraphicsBitmap;
class Font;
class Widget;
class Window;
#ifdef LIBGUI
class GWidget;
class GWindow;
#endif
class Painter {
public:
explicit Painter(Widget&);
#ifdef LIBGUI
explicit Painter(GWidget&);
#endif
explicit Painter(GraphicsBitmap&);
~Painter();
void fill_rect(const Rect&, Color);
@ -42,6 +47,8 @@ private:
Point m_translation;
Rect m_clip_rect;
RetainPtr<GraphicsBitmap> m_target;
Window* m_window { nullptr };
#ifdef LIBGUI
GWindow* m_window { nullptr };
#endif
DrawOp m_draw_op { DrawOp::Copy };
};