Skip to content

Commit

Permalink
countdown_timer plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Kolcha committed Aug 28, 2024
1 parent 3483354 commit 835ccb9
Show file tree
Hide file tree
Showing 20 changed files with 1,412 additions and 0 deletions.
1 change: 1 addition & 0 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ add_subdirectory(var_translucency)

if (TARGET Qt6::Multimedia)
add_subdirectory(chime)
add_subdirectory(countdown_timer)
endif()
35 changes: 35 additions & 0 deletions plugins/countdown_timer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# SPDX-FileCopyrightText: 2024 Nick Korotysh <[email protected]>
#
# SPDX-License-Identifier: GPL-3.0-or-later

project(countdown_timer VERSION 2.0.0 LANGUAGES CXX)

qt_add_plugin(${PROJECT_NAME} CLASS_NAME CountdownTimerPluginFactory
gui/hotkeys_settings_widget.cpp
gui/hotkeys_settings_widget.hpp
gui/hotkeys_settings_widget.ui
gui/timer_settings_widget.cpp
gui/timer_settings_widget.hpp
gui/timer_settings_widget.ui
impl/countdown_timer.cpp
impl/countdown_timer.hpp
impl/countdown_timer_plugin_impl.cpp
impl/countdown_timer_plugin_impl.hpp
impl/countdown_timer_settings.cpp
impl/countdown_timer_settings.hpp
impl/utilities.cpp
impl/utilities.hpp
countdown_timer_plugin.cpp
countdown_timer_plugin.hpp
)

add_win_rc_file(${PROJECT_NAME} ${PROJECT_NAME}.rc)

set_clock_plugin_common_properties(${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} PRIVATE PluginCore)
target_link_libraries(${PROJECT_NAME} PRIVATE QHotkey::QHotkey)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Widgets Qt::Multimedia)

configure_file(${PROJECT_NAME}.json.in ${PROJECT_NAME}.json @ONLY)

target_win_deploy_qt(${PROJECT_NAME} "plugins/${PROJECT_NAME}.dll")
7 changes: 7 additions & 0 deletions plugins/countdown_timer/countdown_timer.json.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@PROJECT_NAME@",
"version": "@PROJECT_VERSION@",
"configurable": true,
"settings_listener": true,
"author": "Nick Korotysh"
}
30 changes: 30 additions & 0 deletions plugins/countdown_timer/countdown_timer.rc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
1 VERSIONINFO
FILEVERSION ${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},${BUILD_NUMBER}
PRODUCTVERSION ${CLOCK_VERSION_MAJOR},${CLOCK_VERSION_MINOR},${CLOCK_VERSION_PATCH},0
FILEFLAGSMASK 0x3F
FILEFLAGS 0x0
FILEOS 0x40004
FILETYPE 0x2
FILESUBTYPE 0x0
{
BLOCK "StringFileInfo"
{
BLOCK "040904E4"
{
VALUE "Comments", "${PROJECT_DESCRIPTION}"
VALUE "CompanyName", "Nick Korotysh"
VALUE "FileDescription", "Digital Clock Plugin"
VALUE "FileVersion", "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.${BUILD_NUMBER}"
VALUE "InternalName", "${PROJECT_NAME}.dll"
VALUE "LegalCopyright", "(c) 2017-2024 Nick Korotysh"
VALUE "OriginalFilename", "${PROJECT_NAME}.dll"
VALUE "ProductName", "Digital Clock"
VALUE "ProductVersion", "${CLOCK_VERSION}"
}
}

BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0409, 0x04E4
}
}
202 changes: 202 additions & 0 deletions plugins/countdown_timer/countdown_timer_plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* SPDX-FileCopyrightText: 2024 Nick Korotysh <[email protected]>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

#include "countdown_timer_plugin.hpp"

#include <QMessageBox>
#include <QMouseEvent>

#include <QPushButton>

#include <QMediaPlayer>

#include "gui/hotkeys_settings_widget.hpp"
#include "gui/timer_settings_widget.hpp"

class CountdownTimerWidget : public GraphicsTextWidget
{
Q_OBJECT

public:
explicit CountdownTimerWidget(QWidget* parent = nullptr);

signals:
void clicked();
void doubleClicked();

protected:
void mouseReleaseEvent(QMouseEvent* event) override;
void mouseDoubleClickEvent(QMouseEvent* event) override;
};


CountdownTimerWidget::CountdownTimerWidget(QWidget* parent)
: GraphicsTextWidget(parent)
{
}

void CountdownTimerWidget::mouseReleaseEvent(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton) {
emit clicked();
}
GraphicsTextWidget::mouseReleaseEvent(event);
}

void CountdownTimerWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton) {
emit doubleClicked();
}
GraphicsTextWidget::mouseDoubleClickEvent(event);
}


CountdownTimerPlugin::CountdownTimerPlugin()
: _impl(std::make_unique<CountdownTimerPluginImpl>())
{
}

CountdownTimerPlugin::~CountdownTimerPlugin() = default;

void CountdownTimerPlugin::saveState(StateClient& st) const
{
}

void CountdownTimerPlugin::loadState(const StateClient& st)
{
}

void CountdownTimerPlugin::initSettings(const SettingsClient& st)
{
_impl->initSettings(st);
_impl->updateWidgetText();
WidgetPluginBase::initSettings(st);
}

void CountdownTimerPlugin::accepted()
{
if (_impl->timer)
_impl->initTimer();
WidgetPluginBase::accepted();
}

void CountdownTimerPlugin::rejected()
{
WidgetPluginBase::rejected();
}

void CountdownTimerPlugin::init()
{
using countdown_timer::CountdownTimer;
_impl->timer = std::make_unique<CountdownTimer>();

connect(_impl->timer.get(), &CountdownTimer::timeLeftChanged, this, &CountdownTimerPlugin::onUpdate);
connect(_impl->timer.get(), &CountdownTimer::timeout, this, &CountdownTimerPlugin::onTimeout);

_player = std::make_unique<QMediaPlayer>();

connect(_impl->pause_hotkey.get(), &QHotkey::activated, this, &CountdownTimerPlugin::onWidgetClicked);
connect(_impl->restart_hotkey.get(), &QHotkey::activated, this, &CountdownTimerPlugin::onWidgetDblclicked);

WidgetPluginBase::init();

_impl->applySettings();
_impl->initTimer();
}

void CountdownTimerPlugin::shutdown()
{
if (_impl->timer->isActive())
_impl->timer->stop();
// shortcuts must be destroyed explicitly...
// if not, it causes the crash for some reason
_impl->pause_hotkey.reset();
_impl->restart_hotkey.reset();

WidgetPluginBase::shutdown();
}

QList<QWidget*> CountdownTimerPlugin::customConfigure(SettingsClient& s, StateClient& t)
{
auto timer_tab = new TimerSettingsWidget(s, t, _impl.get());
auto hotkeys_tab = new HotkeysSettingsWidget(s, t, _impl.get());
return {timer_tab, hotkeys_tab};
}

std::shared_ptr<GraphicsWidgetBase> CountdownTimerPlugin::createWidget()
{
auto w = std::make_shared<CountdownTimerWidget>();

connect(w.get(), &CountdownTimerWidget::clicked, this, &CountdownTimerPlugin::onWidgetClicked);
connect(w.get(), &CountdownTimerWidget::doubleClicked, this, &CountdownTimerPlugin::onWidgetDblclicked);

_impl->widget = std::move(w);
_impl->updateWidgetText();
return _impl->widget;
}

void CountdownTimerPlugin::destroyWidget()
{
_impl->widget.reset();
}

void CountdownTimerPlugin::onWidgetClicked()
{
if (_impl->timer->isActive()) {
_impl->timer->stop();
} else {
_impl->timer->start();
}
}

void CountdownTimerPlugin::onWidgetDblclicked()
{
if (_impl->restart_on_dbl_click) {
_impl->timer->stop();
_impl->initTimer();
_impl->timer->start();
}
}

void CountdownTimerPlugin::onUpdate()
{
_impl->updateWidgetText();
}

void CountdownTimerPlugin::onTimeout()
{
if (_impl->chime_on_timeout) {
_player->setSource(QUrl::fromLocalFile(_impl->chime_sound));
_player->play();
}

if (_impl->show_message) {
QMessageBox mb(QMessageBox::Warning,
tr("Countdown timer"),
_impl->message_text);
mb.addButton(QMessageBox::Ok)->setFocusPolicy(Qt::ClickFocus);
mb.exec();
}

if (_impl->restart_on_timeout) {
_impl->initTimer();
_impl->timer->start();
}
}


std::unique_ptr<ClockPluginBase> CountdownTimerPluginFactory::create() const
{
return std::make_unique<CountdownTimerPlugin>();
}

QString CountdownTimerPluginFactory::description() const
{
return tr("Just a countdown timer.");
}

#include "countdown_timer_plugin.moc"
67 changes: 67 additions & 0 deletions plugins/countdown_timer/countdown_timer_plugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* SPDX-FileCopyrightText: 2024 Nick Korotysh <[email protected]>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

#pragma once

#include "widget_plugin_base.hpp"

#include "impl/countdown_timer_plugin_impl.hpp"

class QMediaPlayer;

class CountdownTimerPlugin : public WidgetPluginBase
{
Q_OBJECT

public:
CountdownTimerPlugin();
~CountdownTimerPlugin();

void saveState(StateClient& st) const override;
void loadState(const StateClient& st) override;

void initSettings(const SettingsClient& st) override;

void accepted() override;
void rejected() override;

public slots:
void init() override;
void shutdown() override;

protected:
QList<QWidget*> customConfigure(SettingsClient& s, StateClient& t) override;

std::shared_ptr<GraphicsWidgetBase> createWidget() override;
void destroyWidget() override;

private slots:
void onWidgetClicked();
void onWidgetDblclicked();

void onUpdate();
void onTimeout();

private:
std::unique_ptr<CountdownTimerPluginImpl> _impl;
std::unique_ptr<QMediaPlayer> _player;
};


class CountdownTimerPluginFactory : public ClockPluginFactory
{
Q_OBJECT
Q_PLUGIN_METADATA(IID ClockPluginFactory_iid FILE "countdown_timer.json")
Q_INTERFACES(ClockPluginFactory)

public:
std::unique_ptr<ClockPluginBase> create() const override;

QString title() const override { return tr("Countdown timer"); }
QString description() const override;

bool perClockInstance() const noexcept override { return true; }
};
40 changes: 40 additions & 0 deletions plugins/countdown_timer/gui/hotkeys_settings_widget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2024 Nick Korotysh <[email protected]>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/

#include "hotkeys_settings_widget.hpp"
#include "ui_hotkeys_settings_widget.h"

HotkeysSettingsWidget::HotkeysSettingsWidget(SettingsClient& s, StateClient& t,
CountdownTimerPluginImpl* impl, QWidget* parent)
: QWidget(parent)
, ui(new Ui::HotkeysSettingsWidget)
, cfg(s)
, impl(impl)
{
ui->setupUi(this);

ui->pause_seq_edit->setKeySequence(QKeySequence(cfg.getPauseHotkey()));
ui->restart_seq_edit->setKeySequence(QKeySequence(cfg.getRestartHotkey()));
}

HotkeysSettingsWidget::~HotkeysSettingsWidget()
{
delete ui;
}

void HotkeysSettingsWidget::on_pause_seq_edit_editingFinished()
{
cfg.setPauseHotkey(ui->pause_seq_edit->keySequence().toString());
if (impl->pause_hotkey)
impl->pause_hotkey->setShortcut(ui->pause_seq_edit->keySequence(), true);
}

void HotkeysSettingsWidget::on_restart_seq_edit_editingFinished()
{
cfg.setRestartHotkey(ui->restart_seq_edit->keySequence().toString());
if (impl->restart_hotkey)
impl->restart_hotkey->setShortcut(ui->restart_seq_edit->keySequence(), true);
}
Loading

0 comments on commit 835ccb9

Please sign in to comment.