diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index fbf006b2..c53976ba 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -36,6 +36,7 @@ qt_add_library(quickshell-core STATIC popupanchor.cpp types.cpp qsmenuanchor.cpp + clock.cpp ) set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}") diff --git a/src/core/clock.cpp b/src/core/clock.cpp new file mode 100644 index 00000000..b232d0b1 --- /dev/null +++ b/src/core/clock.cpp @@ -0,0 +1,66 @@ +#include "clock.hpp" + +#include +#include +#include +#include + +#include "util.hpp" + +SystemClock::SystemClock(QObject* parent): QObject(parent) { + QObject::connect(&this->timer, &QTimer::timeout, this, &SystemClock::update); + this->update(); +} + +bool SystemClock::enabled() const { return this->mEnabled; } + +void SystemClock::setEnabled(bool enabled) { + if (enabled == this->mEnabled) return; + this->mEnabled = enabled; + emit this->enabledChanged(); + this->update(); +} + +SystemClock::Enum SystemClock::precision() const { return this->mPrecision; } + +void SystemClock::setPrecision(SystemClock::Enum precision) { + if (precision == this->mPrecision) return; + this->mPrecision = precision; + emit this->precisionChanged(); + this->update(); +} + +void SystemClock::update() { + auto time = QTime::currentTime(); + + if (this->mEnabled) { + auto secondPrecision = this->mPrecision >= SystemClock::Seconds; + auto secondChanged = this->setSeconds(secondPrecision ? time.second() : 0); + + auto minutePrecision = this->mPrecision >= SystemClock::Minutes; + auto minuteChanged = this->setMinutes(minutePrecision ? time.minute() : 0); + + auto hourPrecision = this->mPrecision >= SystemClock::Hours; + auto hourChanged = this->setHours(hourPrecision ? time.hour() : 0); + + DropEmitter::call(secondChanged, minuteChanged, hourChanged); + + auto nextTime = QTime( + hourPrecision ? time.hour() : 0, + minutePrecision ? time.minute() : 0, + secondPrecision ? time.second() : 0 + ); + + if (secondPrecision) nextTime = nextTime.addSecs(1); + else if (minutePrecision) nextTime = nextTime.addSecs(60); + else if (hourPrecision) nextTime = nextTime.addSecs(3600); + + this->timer.start(time.msecsTo(nextTime)); + } else { + this->timer.stop(); + } +} + +DEFINE_MEMBER_GETSET(SystemClock, hours, setHours); +DEFINE_MEMBER_GETSET(SystemClock, minutes, setMinutes); +DEFINE_MEMBER_GETSET(SystemClock, seconds, setSeconds); diff --git a/src/core/clock.hpp b/src/core/clock.hpp new file mode 100644 index 00000000..b3ac1228 --- /dev/null +++ b/src/core/clock.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include +#include + +#include "util.hpp" + +///! System clock accessor. +class SystemClock: public QObject { + Q_OBJECT; + /// If the clock should update. Defaults to true. + /// + /// Setting enabled to false pauses the clock. + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged); + /// The precision the clock should measure at. Defaults to `SystemClock.Seconds`. + Q_PROPERTY(SystemClock::Enum precision READ precision WRITE setPrecision NOTIFY precisionChanged); + /// The current hour. + Q_PROPERTY(quint32 hours READ hours NOTIFY hoursChanged); + /// The current minute, or 0 if @@precision is `SystemClock.Hours`. + Q_PROPERTY(quint32 minutes READ minutes NOTIFY minutesChanged); + /// The current second, or 0 if @@precision is `SystemClock.Hours` or `SystemClock.Minutes`. + Q_PROPERTY(quint32 seconds READ seconds NOTIFY secondsChanged); + QML_ELEMENT; + +public: + // must be named enum until docgen is ready to handle member enums better + enum Enum { + Hours = 1, + Minutes = 2, + Seconds = 3, + }; + Q_ENUM(Enum); + + explicit SystemClock(QObject* parent = nullptr); + + [[nodiscard]] bool enabled() const; + void setEnabled(bool enabled); + + [[nodiscard]] SystemClock::Enum precision() const; + void setPrecision(SystemClock::Enum precision); + +signals: + void enabledChanged(); + void precisionChanged(); + void hoursChanged(); + void minutesChanged(); + void secondsChanged(); + +private slots: + void update(); + +private: + bool mEnabled = true; + SystemClock::Enum mPrecision = SystemClock::Seconds; + quint32 mHours = 0; + quint32 mMinutes = 0; + quint32 mSeconds = 0; + QTimer timer; + + DECLARE_PRIVATE_MEMBER(SystemClock, hours, setHours, mHours, hoursChanged); + DECLARE_PRIVATE_MEMBER(SystemClock, minutes, setMinutes, mMinutes, minutesChanged); + DECLARE_PRIVATE_MEMBER(SystemClock, seconds, setSeconds, mSeconds, secondsChanged); +}; diff --git a/src/core/module.md b/src/core/module.md index 411b1d49..060aca9f 100644 --- a/src/core/module.md +++ b/src/core/module.md @@ -27,5 +27,6 @@ headers = [ "popupanchor.hpp", "types.hpp", "qsmenuanchor.hpp", + "clock.hpp", ] -----