summaryrefslogtreecommitdiff
path: root/Widgets
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-10-12 12:18:59 +0200
committerAndreas Kling <awesomekling@gmail.com>2018-10-12 12:18:59 +0200
commit73895ce043fcd4eeb6f84645dc1b46ca58788e62 (patch)
tree5d4e8d2a409a0e3c19b00d18359a6103445a8a6d /Widgets
parent6637dec958b91168cc94e4b97744e24cebdb1257 (diff)
downloadserenity-73895ce043fcd4eeb6f84645dc1b46ca58788e62.zip
Add a clock widget.
Diffstat (limited to 'Widgets')
-rw-r--r--Widgets/ClockWidget.cpp37
-rw-r--r--Widgets/ClockWidget.h16
-rw-r--r--Widgets/Event.h12
-rw-r--r--Widgets/Makefile3
-rw-r--r--Widgets/Object.cpp39
-rw-r--r--Widgets/Object.h9
-rw-r--r--Widgets/Painter.cpp1
-rw-r--r--Widgets/Widget.cpp5
-rw-r--r--Widgets/Window.cpp8
-rw-r--r--Widgets/Window.h4
-rw-r--r--Widgets/WindowManager.cpp2
-rw-r--r--Widgets/test.cpp22
12 files changed, 143 insertions, 15 deletions
diff --git a/Widgets/ClockWidget.cpp b/Widgets/ClockWidget.cpp
new file mode 100644
index 0000000000..a4778e2ca2
--- /dev/null
+++ b/Widgets/ClockWidget.cpp
@@ -0,0 +1,37 @@
+#include "ClockWidget.h"
+#include "Painter.h"
+#include <time.h>
+
+ClockWidget::ClockWidget(Widget* parent)
+ : Widget(parent)
+{
+ setRect({ 0, 0, 100, 40 });
+ startTimer(250);
+}
+
+ClockWidget::~ClockWidget()
+{
+}
+
+void ClockWidget::onPaint(PaintEvent&)
+{
+ auto now = time(nullptr);
+ auto& tm = *localtime(&now);
+
+ char timeBuf[128];
+ sprintf(timeBuf, "%02u:%02u:%02u ", tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ Painter painter(*this);
+ painter.fillRect(rect(), Color(127, 127, 127));
+ painter.drawText(rect(), timeBuf, Painter::TextAlignment::Center, Color(0,0,0));
+}
+
+void ClockWidget::onTimer(TimerEvent&)
+{
+ auto now = time(nullptr);
+ if (now == m_lastSeenTimestamp)
+ return;
+ m_lastSeenTimestamp = now;
+ update();
+}
+
diff --git a/Widgets/ClockWidget.h b/Widgets/ClockWidget.h
new file mode 100644
index 0000000000..3ddf269030
--- /dev/null
+++ b/Widgets/ClockWidget.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "Widget.h"
+
+class ClockWidget final : public Widget {
+public:
+ explicit ClockWidget(Widget* parent = nullptr);
+ virtual ~ClockWidget() override;
+
+private:
+ virtual void onPaint(PaintEvent&) override;
+ virtual void onTimer(TimerEvent&) override;
+
+ dword m_lastSeenTimestamp { 0 };
+};
+
diff --git a/Widgets/Event.h b/Widgets/Event.h
index 9dcde5827e..6de27b79e0 100644
--- a/Widgets/Event.h
+++ b/Widgets/Event.h
@@ -14,6 +14,7 @@ static const char* eventNames[] = {
"MouseUp",
"KeyDown",
"KeyUp",
+ "Timer",
};
class Event {
@@ -29,6 +30,7 @@ public:
MouseUp,
KeyDown,
KeyUp,
+ Timer,
};
Event() { }
@@ -88,7 +90,7 @@ enum class MouseButton : byte {
Right,
};
-class KeyEvent : public Event {
+class KeyEvent final : public Event {
public:
KeyEvent(Type type, int key)
: Event(type)
@@ -102,7 +104,7 @@ private:
int m_key { 0 };
};
-class MouseEvent : public Event {
+class MouseEvent final : public Event {
public:
MouseEvent(Type type, int x, int y, MouseButton button = MouseButton::None)
: Event(type)
@@ -121,3 +123,9 @@ private:
MouseButton m_button { MouseButton::None };
};
+class TimerEvent final : public Event {
+public:
+ TimerEvent() : Event(Event::Timer) { }
+ ~TimerEvent() { }
+};
+
diff --git a/Widgets/Makefile b/Widgets/Makefile
index f11a3980df..818de90d2d 100644
--- a/Widgets/Makefile
+++ b/Widgets/Makefile
@@ -22,11 +22,12 @@ VFS_OBJS = \
WindowManager.o \
Font.o \
Window.o \
+ ClockWidget.o \
test.o
OBJS = $(AK_OBJS) $(VFS_OBJS)
-CXXFLAGS = -std=c++17 -O0 -W -Wall -Wextra -Wconversion -I. -I.. -g `sdl2-config --cflags`
+CXXFLAGS = -std=c++17 -O0 -W -Wall -Wextra -Wconversion -I. -I.. -g `sdl2-config --cflags` -DUSE_SDL
LDFLAGS = `sdl2-config --libs`
diff --git a/Widgets/Object.cpp b/Widgets/Object.cpp
index 57216928a2..a46657a6d0 100644
--- a/Widgets/Object.cpp
+++ b/Widgets/Object.cpp
@@ -1,7 +1,12 @@
#include "Object.h"
#include "Event.h"
+#include "EventLoop.h"
#include <AK/Assertions.h>
+#ifdef USE_SDL
+#include <SDL.h>
+#endif
+
Object::Object(Object* parent)
: m_parent(parent)
{
@@ -21,6 +26,8 @@ Object::~Object()
void Object::event(Event& event)
{
switch (event.type()) {
+ case Event::Timer:
+ return onTimer(static_cast<TimerEvent&>(event));
case Event::Invalid:
ASSERT_NOT_REACHED();
break;
@@ -44,3 +51,35 @@ void Object::removeChild(Object& object)
}
m_children = std::move(newList);
}
+
+void Object::onTimer(TimerEvent&)
+{
+}
+
+#ifdef USE_SDL
+static dword sdlTimerCallback(dword interval, void* param)
+{
+ EventLoop::main().postEvent(static_cast<Object*>(param), make<TimerEvent>());
+ return interval;
+}
+#endif
+
+void Object::startTimer(int ms)
+{
+ if (m_timerID) {
+ printf("Object{%p} already has a timer!\n", this);
+ ASSERT_NOT_REACHED();
+ }
+#if USE_SDL
+ m_timerID = SDL_AddTimer(ms, sdlTimerCallback, this);
+#endif
+}
+
+void Object::stopTimer()
+{
+ if (!m_timerID)
+ return;
+ SDL_RemoveTimer(m_timerID);
+ m_timerID = 0;
+}
+
diff --git a/Widgets/Object.h b/Widgets/Object.h
index 3ecd19db5b..028515ce1a 100644
--- a/Widgets/Object.h
+++ b/Widgets/Object.h
@@ -3,6 +3,7 @@
#include <AK/Vector.h>
class Event;
+class TimerEvent;
class Object {
public:
@@ -18,11 +19,19 @@ public:
Object* parent() { return m_parent; }
const Object* parent() const { return m_parent; }
+ void startTimer(int ms);
+ void stopTimer();
+ bool hasTimer() const { return m_timerID; }
+
private:
+ virtual void onTimer(TimerEvent&);
+
void addChild(Object&);
void removeChild(Object&);
Object* m_parent { nullptr };
+ int m_timerID { 0 };
+
Vector<Object*> m_children;
};
diff --git a/Widgets/Painter.cpp b/Widgets/Painter.cpp
index c5c8d7adbd..c872d22868 100644
--- a/Widgets/Painter.cpp
+++ b/Widgets/Painter.cpp
@@ -11,7 +11,6 @@ Painter::Painter(Widget& widget)
, m_font(Font::defaultFont())
{
if (auto* window = widget.window()) {
- printf("window :: %s\n", window->title().characters());
m_translation = window->position();
m_translation.moveBy(widget.position());
} else {
diff --git a/Widgets/Widget.cpp b/Widgets/Widget.cpp
index ecaf60328d..da4fe8914c 100644
--- a/Widgets/Widget.cpp
+++ b/Widgets/Widget.cpp
@@ -2,6 +2,7 @@
#include "Event.h"
#include "EventLoop.h"
#include "WindowManager.h"
+#include "Window.h"
#include <AK/Assertions.h>
Widget::Widget(Widget* parent)
@@ -26,6 +27,10 @@ void Widget::event(Event& event)
{
switch (event.type()) {
case Event::Paint:
+ if (auto* win = window()) {
+ if (win->isBeingDragged())
+ return;
+ }
m_hasPendingPaintEvent = false;
return onPaint(static_cast<PaintEvent&>(event));
case Event::Show:
diff --git a/Widgets/Window.cpp b/Widgets/Window.cpp
index 230150bfb5..118c75cc27 100644
--- a/Widgets/Window.cpp
+++ b/Widgets/Window.cpp
@@ -50,10 +50,12 @@ void Window::event(Event& event)
}
if (event.isPaintEvent()) {
- if (m_mainWidget) {
- printf("forward to main widget\n");
- return m_mainWidget->event(event);
+ if (isBeingDragged()) {
+ // Ignore paint events during window drag.
+ return;
}
+ if (m_mainWidget)
+ return m_mainWidget->event(event);
}
return Object::event(event);
diff --git a/Widgets/Window.h b/Widgets/Window.h
index 93119c08f9..f37f75c757 100644
--- a/Widgets/Window.h
+++ b/Widgets/Window.h
@@ -32,9 +32,13 @@ public:
virtual void event(Event&) override;
+ bool isBeingDragged() const { return m_isBeingDragged; }
+ void setIsBeingDragged(bool b) { m_isBeingDragged = b; }
+
private:
String m_title;
Rect m_rect;
Widget* m_mainWidget { nullptr };
+ bool m_isBeingDragged { false };
};
diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp
index 03e5a6cb2e..f12405a8b9 100644
--- a/Widgets/WindowManager.cpp
+++ b/Widgets/WindowManager.cpp
@@ -124,6 +124,7 @@ void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event)
m_dragWindow = &window;
m_dragOrigin = event.position();
m_dragWindowOrigin = window.position();
+ window.setIsBeingDragged(true);
return;
}
#if 0
@@ -140,6 +141,7 @@ void WindowManager::processMouseEvent(MouseEvent& event)
if (event.type() == Event::MouseUp) {
if (m_dragWindow) {
printf("[WM] Finish dragging Window{%p}\n", m_dragWindow);
+ m_dragWindow->setIsBeingDragged(false);
m_dragWindow = nullptr;
EventLoop::main().postEvent(this, make<PaintEvent>());
return;
diff --git a/Widgets/test.cpp b/Widgets/test.cpp
index 0b2bad48ab..43a5a82e58 100644
--- a/Widgets/test.cpp
+++ b/Widgets/test.cpp
@@ -6,6 +6,7 @@
#include "TerminalWidget.h"
#include "WindowManager.h"
#include "Window.h"
+#include "ClockWidget.h"
#include <cstdio>
int main(int c, char** v)
@@ -20,38 +21,43 @@ int main(int c, char** v)
auto* fontTestWindow = new Window;
fontTestWindow->setTitle("Font test");
- fontTestWindow->setRect({100, 100, 300, 80 });
+ fontTestWindow->setRect({ 100, 100, 300, 80 });
auto* fontTestWindowWidget = new Widget;
fontTestWindow->setMainWidget(fontTestWindowWidget);
- fontTestWindowWidget->setRect({0, 0, 300, 80 });
+ fontTestWindowWidget->setRect({ 0, 0, 300, 80 });
auto* l1 = new Label(fontTestWindowWidget);
- l1->setRect(Rect(0, 0, 300, 20));
+ l1->setRect({ 0, 0, 300, 20 });
l1->setText("0123456789");
auto* l2 = new Label(fontTestWindowWidget);
- l2->setRect(Rect(0, 20, 300, 20));
+ l2->setRect({ 0, 20, 300, 20 });
l2->setText("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
auto* l3 = new Label(fontTestWindowWidget);
- l3->setRect(Rect(0, 40, 300, 20));
+ l3->setRect({ 0, 40, 300, 20 });
l3->setText("abcdefghijklmnopqrstuvwxyz");
auto* l4 = new Label(fontTestWindowWidget);
- l4->setRect(Rect(0, 60, 300, 20));
+ l4->setRect({ 0, 60, 300, 20 });
l4->setText("!\"#$%&'()*+,-./:;<=>?@[\\]^_{|}~");
auto* b = new Button(&w);
- b->setRect(Rect(10, 10, 100, 30));
+ b->setRect({ 10, 10, 100, 30 });
b->setCaption("Button!");
auto* win = new Window;
win->setTitle("Console");
- win->setRect({100, 300, 644, 254});
+ win->setRect({ 100, 300, 644, 254 });
auto* t = new TerminalWidget(nullptr);
win->setMainWidget(t);
+ auto* clockWin = new Window;
+ clockWin->setTitle("Clock");
+ clockWin->setRect({ 500, 50, 100, 40 });
+ clockWin->setMainWidget(new ClockWidget);
+
return loop.exec();
}