mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-21 18:15:58 +00:00
Start working on a Widgets library.
This commit is contained in:
parent
a181a8f6e7
commit
8c84f9749e
35
Widgets/AbstractScreen.cpp
Normal file
35
Widgets/AbstractScreen.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include "AbstractScreen.h"
|
||||||
|
#include "EventLoop.h"
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Widget.h"
|
||||||
|
#include <AK/Assertions.h>
|
||||||
|
|
||||||
|
static AbstractScreen* s_the;
|
||||||
|
|
||||||
|
AbstractScreen& AbstractScreen::the()
|
||||||
|
{
|
||||||
|
ASSERT(s_the);
|
||||||
|
return *s_the;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractScreen::AbstractScreen(unsigned width, unsigned height)
|
||||||
|
: m_width(width)
|
||||||
|
, m_height(height)
|
||||||
|
{
|
||||||
|
ASSERT(!s_the);
|
||||||
|
s_the = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractScreen::~AbstractScreen()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractScreen::setRootWidget(Widget* widget)
|
||||||
|
{
|
||||||
|
// FIXME: Should we support switching root widgets?
|
||||||
|
ASSERT(!m_rootWidget);
|
||||||
|
ASSERT(widget);
|
||||||
|
|
||||||
|
m_rootWidget = widget;
|
||||||
|
EventLoop::main().postEvent(m_rootWidget, make<ShowEvent>());
|
||||||
|
}
|
25
Widgets/AbstractScreen.h
Normal file
25
Widgets/AbstractScreen.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Widget;
|
||||||
|
|
||||||
|
class AbstractScreen {
|
||||||
|
public:
|
||||||
|
virtual ~AbstractScreen();
|
||||||
|
|
||||||
|
unsigned width() const { return m_width; }
|
||||||
|
unsigned height() const { return m_height; }
|
||||||
|
|
||||||
|
void setRootWidget(Widget*);
|
||||||
|
|
||||||
|
static AbstractScreen& the();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AbstractScreen(unsigned width, unsigned height);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned m_width { 0 };
|
||||||
|
unsigned m_height { 0 };
|
||||||
|
|
||||||
|
Widget* m_rootWidget { nullptr };
|
||||||
|
};
|
||||||
|
|
118
Widgets/Event.h
Normal file
118
Widgets/Event.h
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Types.h>
|
||||||
|
|
||||||
|
static const char* eventNames[] = {
|
||||||
|
"Invalid",
|
||||||
|
"Quit",
|
||||||
|
"Show",
|
||||||
|
"Hide",
|
||||||
|
"Paint",
|
||||||
|
"MouseMove",
|
||||||
|
"MouseDown",
|
||||||
|
"MouseUp",
|
||||||
|
"KeyDown",
|
||||||
|
"KeyUp",
|
||||||
|
};
|
||||||
|
|
||||||
|
class Event {
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Invalid = 0,
|
||||||
|
Quit,
|
||||||
|
Show,
|
||||||
|
Hide,
|
||||||
|
Paint,
|
||||||
|
MouseMove,
|
||||||
|
MouseDown,
|
||||||
|
MouseUp,
|
||||||
|
KeyDown,
|
||||||
|
KeyUp,
|
||||||
|
};
|
||||||
|
|
||||||
|
Event() { }
|
||||||
|
~Event() { }
|
||||||
|
|
||||||
|
Type type() const { return m_type; }
|
||||||
|
|
||||||
|
const char* name() const { return eventNames[(unsigned)m_type]; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit Event(Type type) : m_type(type) { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type m_type { Invalid };
|
||||||
|
};
|
||||||
|
|
||||||
|
class QuitEvent final : public Event {
|
||||||
|
public:
|
||||||
|
QuitEvent()
|
||||||
|
: Event(Event::Quit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PaintEvent final : public Event {
|
||||||
|
public:
|
||||||
|
PaintEvent()
|
||||||
|
: Event(Event::Paint)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShowEvent final : public Event {
|
||||||
|
public:
|
||||||
|
ShowEvent()
|
||||||
|
: Event(Event::Show)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class HideEvent final : public Event {
|
||||||
|
public:
|
||||||
|
HideEvent()
|
||||||
|
: Event(Event::Hide)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MouseButton : byte {
|
||||||
|
None = 0,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
};
|
||||||
|
|
||||||
|
class KeyEvent : public Event {
|
||||||
|
public:
|
||||||
|
KeyEvent(Type type, int key)
|
||||||
|
: Event(type)
|
||||||
|
, m_key(key)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int key() const { return m_key; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_key { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
class MouseEvent : public Event {
|
||||||
|
public:
|
||||||
|
MouseEvent(Type type, int x, int y, MouseButton button = MouseButton::None)
|
||||||
|
: Event(type)
|
||||||
|
, m_x(x)
|
||||||
|
, m_y(y)
|
||||||
|
, m_button(button)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int x() const { return m_x; }
|
||||||
|
int y() const { return m_y; }
|
||||||
|
MouseButton button() const { return m_button; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_x { 0 };
|
||||||
|
int m_y { 0 };
|
||||||
|
MouseButton m_button { MouseButton::None };
|
||||||
|
};
|
||||||
|
|
52
Widgets/EventLoop.cpp
Normal file
52
Widgets/EventLoop.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#include "EventLoop.h"
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Object.h"
|
||||||
|
|
||||||
|
static EventLoop* s_mainEventLoop;
|
||||||
|
|
||||||
|
EventLoop::EventLoop()
|
||||||
|
{
|
||||||
|
if (!s_mainEventLoop)
|
||||||
|
s_mainEventLoop = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventLoop::~EventLoop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EventLoop& EventLoop::main()
|
||||||
|
{
|
||||||
|
ASSERT(s_mainEventLoop);
|
||||||
|
return *s_mainEventLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EventLoop::exec()
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
if (m_queuedEvents.isEmpty())
|
||||||
|
waitForEvent();
|
||||||
|
auto events = std::move(m_queuedEvents);
|
||||||
|
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());
|
||||||
|
if (!receiver) {
|
||||||
|
switch (event.type()) {
|
||||||
|
case Event::Quit:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
printf("event type %u with no receiver :(\n", event.type());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
receiver->event(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLoop::postEvent(Object* receiver, OwnPtr<Event>&& event)
|
||||||
|
{
|
||||||
|
m_queuedEvents.append({ receiver, std::move(event) });
|
||||||
|
}
|
||||||
|
|
30
Widgets/EventLoop.h
Normal file
30
Widgets/EventLoop.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/OwnPtr.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
|
class Event;
|
||||||
|
class Object;
|
||||||
|
|
||||||
|
class EventLoop {
|
||||||
|
public:
|
||||||
|
virtual ~EventLoop();
|
||||||
|
|
||||||
|
int exec();
|
||||||
|
|
||||||
|
virtual void waitForEvent() = 0;
|
||||||
|
|
||||||
|
void postEvent(Object* receiver, OwnPtr<Event>&&);
|
||||||
|
|
||||||
|
static EventLoop& main();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EventLoop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct QueuedEvent {
|
||||||
|
Object* receiver { nullptr };
|
||||||
|
OwnPtr<Event> event;
|
||||||
|
};
|
||||||
|
Vector<QueuedEvent> m_queuedEvents;
|
||||||
|
};
|
24
Widgets/EventLoopSDL.cpp
Normal file
24
Widgets/EventLoopSDL.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include "EventLoopSDL.h"
|
||||||
|
#include "Event.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
EventLoopSDL::EventLoopSDL()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EventLoopSDL::~EventLoopSDL()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLoopSDL::waitForEvent()
|
||||||
|
{
|
||||||
|
SDL_Event sdlEvent;
|
||||||
|
while (SDL_WaitEvent(&sdlEvent) != 0) {
|
||||||
|
switch (sdlEvent.type) {
|
||||||
|
case SDL_QUIT:
|
||||||
|
postEvent(nullptr, make<QuitEvent>());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
13
Widgets/EventLoopSDL.h
Normal file
13
Widgets/EventLoopSDL.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "EventLoop.h"
|
||||||
|
|
||||||
|
class EventLoopSDL final : public EventLoop {
|
||||||
|
public:
|
||||||
|
EventLoopSDL();
|
||||||
|
virtual ~EventLoopSDL() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void waitForEvent() override;
|
||||||
|
};
|
||||||
|
|
BIN
Widgets/FrameBuffer.o
Normal file
BIN
Widgets/FrameBuffer.o
Normal file
Binary file not shown.
49
Widgets/FrameBufferSDL.cpp
Normal file
49
Widgets/FrameBufferSDL.cpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include "FrameBufferSDL.h"
|
||||||
|
#include <AK/Assertions.h>
|
||||||
|
|
||||||
|
FrameBufferSDL::FrameBufferSDL(unsigned width, unsigned height)
|
||||||
|
: AbstractScreen(width, height)
|
||||||
|
{
|
||||||
|
initializeSDL();
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameBufferSDL::~FrameBufferSDL()
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(m_window);
|
||||||
|
m_surface = nullptr;
|
||||||
|
m_window = nullptr;
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameBufferSDL::show()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameBufferSDL::initializeSDL()
|
||||||
|
{
|
||||||
|
if (m_window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_window = SDL_CreateWindow(
|
||||||
|
"FrameBuffer",
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
|
width(),
|
||||||
|
height(),
|
||||||
|
SDL_WINDOW_SHOWN);
|
||||||
|
|
||||||
|
ASSERT(m_window);
|
||||||
|
|
||||||
|
m_surface = SDL_GetWindowSurface(m_window);
|
||||||
|
ASSERT(m_surface);
|
||||||
|
|
||||||
|
SDL_FillRect(m_surface, nullptr, SDL_MapRGB(m_surface->format, 0xff, 0xff, 0xff));
|
||||||
|
|
||||||
|
SDL_UpdateWindowSurface(m_window);
|
||||||
|
}
|
||||||
|
|
19
Widgets/FrameBufferSDL.h
Normal file
19
Widgets/FrameBufferSDL.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AbstractScreen.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
class FrameBufferSDL final : public AbstractScreen {
|
||||||
|
public:
|
||||||
|
FrameBufferSDL(unsigned width, unsigned height);
|
||||||
|
virtual ~FrameBufferSDL() override;
|
||||||
|
|
||||||
|
void show();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initializeSDL();
|
||||||
|
|
||||||
|
SDL_Window* m_window { nullptr };
|
||||||
|
SDL_Surface* m_surface { nullptr };
|
||||||
|
};
|
||||||
|
|
37
Widgets/Makefile
Normal file
37
Widgets/Makefile
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
PROGRAM = test
|
||||||
|
|
||||||
|
AK_OBJS = \
|
||||||
|
../AK/String.o \
|
||||||
|
../AK/StringImpl.o \
|
||||||
|
../AK/SimpleMalloc.o \
|
||||||
|
../AK/kmalloc.o
|
||||||
|
|
||||||
|
VFS_OBJS = \
|
||||||
|
AbstractScreen.o \
|
||||||
|
FrameBufferSDL.o \
|
||||||
|
EventLoop.o \
|
||||||
|
EventLoopSDL.o \
|
||||||
|
Object.o \
|
||||||
|
Widget.o \
|
||||||
|
RootWidget.o \
|
||||||
|
test.o
|
||||||
|
|
||||||
|
OBJS = $(AK_OBJS) $(VFS_OBJS)
|
||||||
|
|
||||||
|
CXXFLAGS = -std=c++17 -O0 -W -Wall -Wextra -Wconversion -I. -I.. -g `sdl2-config --cflags`
|
||||||
|
|
||||||
|
LDFLAGS = `sdl2-config --libs`
|
||||||
|
|
||||||
|
#test.o: BlockDevice.h FileBackedBlockDevice.h FileSystem.h Ext2FileSystem.h VirtualFileSystem.h FileHandle.h
|
||||||
|
|
||||||
|
all: $(PROGRAM)
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJS) $(PROGRAM)
|
||||||
|
|
||||||
|
$(PROGRAM): $(OBJS)
|
||||||
|
$(CXX) $(LDFLAGS) -o $@ $(OBJS)
|
||||||
|
|
23
Widgets/Object.cpp
Normal file
23
Widgets/Object.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "Object.h"
|
||||||
|
#include "Event.h"
|
||||||
|
#include <AK/Assertions.h>
|
||||||
|
|
||||||
|
Object::Object(Object* parent)
|
||||||
|
: m_parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Object::~Object()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::event(Event& event)
|
||||||
|
{
|
||||||
|
switch (event.type()) {
|
||||||
|
case Event::Invalid:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
14
Widgets/Object.h
Normal file
14
Widgets/Object.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Event;
|
||||||
|
|
||||||
|
class Object {
|
||||||
|
public:
|
||||||
|
Object(Object* parent = nullptr);
|
||||||
|
virtual ~Object();
|
||||||
|
|
||||||
|
virtual void event(Event&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Object* m_parent { nullptr };
|
||||||
|
};
|
23
Widgets/RootWidget.cpp
Normal file
23
Widgets/RootWidget.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "RootWidget.h"
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
RootWidget::RootWidget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RootWidget::~RootWidget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RootWidget::onPaint(PaintEvent& event)
|
||||||
|
{
|
||||||
|
printf("RootWidget::onPaint\n");
|
||||||
|
Widget::onPaint(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RootWidget::onMouseMove(MouseEvent& event)
|
||||||
|
{
|
||||||
|
printf("RootWidget::onMouseMove: x=%d, y=%d\n", event.x(), event.y());
|
||||||
|
Widget::onMouseMove(event);
|
||||||
|
}
|
||||||
|
|
13
Widgets/RootWidget.h
Normal file
13
Widgets/RootWidget.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
|
class RootWidget final : public Widget {
|
||||||
|
public:
|
||||||
|
RootWidget();
|
||||||
|
virtual ~RootWidget() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void onPaint(PaintEvent&) override;
|
||||||
|
virtual void onMouseMove(MouseEvent&) override;
|
||||||
|
};
|
76
Widgets/Widget.cpp
Normal file
76
Widgets/Widget.cpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#include "Widget.h"
|
||||||
|
#include "Event.h"
|
||||||
|
#include "EventLoop.h"
|
||||||
|
#include <AK/Assertions.h>
|
||||||
|
|
||||||
|
Widget::Widget(Widget* parent)
|
||||||
|
: Object(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget::~Widget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::event(Event& event)
|
||||||
|
{
|
||||||
|
switch (event.type()) {
|
||||||
|
case Event::Paint:
|
||||||
|
return onPaint(static_cast<PaintEvent&>(event));
|
||||||
|
case Event::Show:
|
||||||
|
return onShow(static_cast<ShowEvent&>(event));
|
||||||
|
case Event::Hide:
|
||||||
|
return onHide(static_cast<HideEvent&>(event));
|
||||||
|
case Event::KeyDown:
|
||||||
|
return onKeyDown(static_cast<KeyEvent&>(event));
|
||||||
|
case Event::KeyUp:
|
||||||
|
return onKeyUp(static_cast<KeyEvent&>(event));
|
||||||
|
case Event::MouseMove:
|
||||||
|
return onMouseMove(static_cast<MouseEvent&>(event));
|
||||||
|
case Event::MouseDown:
|
||||||
|
return onMouseDown(static_cast<MouseEvent&>(event));
|
||||||
|
case Event::MouseUp:
|
||||||
|
return onMouseUp(static_cast<MouseEvent&>(event));
|
||||||
|
default:
|
||||||
|
return Object::event(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onPaint(PaintEvent&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onShow(ShowEvent&)
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onHide(HideEvent&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onKeyDown(KeyEvent&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onKeyUp(KeyEvent&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onMouseDown(MouseEvent&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onMouseUp(MouseEvent&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::onMouseMove(MouseEvent&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::update()
|
||||||
|
{
|
||||||
|
EventLoop::main().postEvent(this, make<PaintEvent>());
|
||||||
|
}
|
||||||
|
|
26
Widgets/Widget.h
Normal file
26
Widgets/Widget.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Object.h"
|
||||||
|
|
||||||
|
class Widget : public Object {
|
||||||
|
public:
|
||||||
|
explicit Widget(Widget* parent = nullptr);
|
||||||
|
virtual ~Widget();
|
||||||
|
|
||||||
|
virtual void event(Event&);
|
||||||
|
virtual void onPaint(PaintEvent&);
|
||||||
|
virtual void onShow(ShowEvent&);
|
||||||
|
virtual void onHide(HideEvent&);
|
||||||
|
virtual void onKeyDown(KeyEvent&);
|
||||||
|
virtual void onKeyUp(KeyEvent&);
|
||||||
|
virtual void onMouseMove(MouseEvent&);
|
||||||
|
virtual void onMouseDown(MouseEvent&);
|
||||||
|
virtual void onMouseUp(MouseEvent&);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_x { 0 };
|
||||||
|
int m_y { 0 };
|
||||||
|
};
|
17
Widgets/test.cpp
Normal file
17
Widgets/test.cpp
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include "FrameBufferSDL.h"
|
||||||
|
#include "EventLoopSDL.h"
|
||||||
|
#include "RootWidget.h"
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
int main(int c, char** v)
|
||||||
|
{
|
||||||
|
FrameBufferSDL fb(800, 600);
|
||||||
|
fb.show();
|
||||||
|
|
||||||
|
EventLoopSDL loop;
|
||||||
|
|
||||||
|
RootWidget w;
|
||||||
|
fb.setRootWidget(&w);
|
||||||
|
|
||||||
|
return loop.exec();
|
||||||
|
}
|
Loading…
Reference in a new issue