mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +00:00
Add a clock widget.
This commit is contained in:
parent
6637dec958
commit
73895ce043
Notes:
sideshowbarker
2024-07-19 18:50:16 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/73895ce043f
12 changed files with 143 additions and 15 deletions
37
Widgets/ClockWidget.cpp
Normal file
37
Widgets/ClockWidget.cpp
Normal file
|
@ -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();
|
||||
}
|
||||
|
16
Widgets/ClockWidget.h
Normal file
16
Widgets/ClockWidget.h
Normal file
|
@ -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 };
|
||||
};
|
||||
|
|
@ -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() { }
|
||||
};
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue