working timer
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "connection/dbus/notification.hpp"
|
||||
#include "connection/dbus/tray.hpp"
|
||||
#include "services/hyprland.hpp"
|
||||
#include "widgets/wallpaperWindow.hpp"
|
||||
|
||||
#include "glibmm/refptr.h"
|
||||
#include "gtkmm/application.h"
|
||||
@@ -21,6 +22,7 @@ class App {
|
||||
private:
|
||||
Glib::RefPtr<Gtk::Application> app;
|
||||
std::vector<std::shared_ptr<Bar>> bars;
|
||||
std::vector<std::shared_ptr<WallpaperWindow>> wallpaperWindows;
|
||||
std::shared_ptr<NotificationService> notificationService = nullptr;
|
||||
std::shared_ptr<MprisController> mprisController = nullptr;
|
||||
HyprlandService *hyprlandService = nullptr;
|
||||
|
||||
105
include/components/timer.hpp
Normal file
105
include/components/timer.hpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "components/button/iconButton.hpp"
|
||||
#include "services/timerService.hpp"
|
||||
|
||||
#include "gtkmm/box.h"
|
||||
#include "gtkmm/label.h"
|
||||
|
||||
namespace {
|
||||
std::string format_duration(const std::string &digits) {
|
||||
std::string d = digits;
|
||||
if (d.size() > 6) {
|
||||
d = d.substr(d.size() - 6);
|
||||
}
|
||||
if (d.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string padded = std::string(6 - d.size(), '0') + d;
|
||||
|
||||
int h = std::stoi(padded.substr(0, 2));
|
||||
int m = std::stoi(padded.substr(2, 2));
|
||||
int s = std::stoi(padded.substr(4, 2));
|
||||
|
||||
std::ostringstream out;
|
||||
if (h > 0) {
|
||||
out << h << "h " << std::setw(2) << std::setfill('0') << m << "m "
|
||||
<< std::setw(2) << std::setfill('0') << s << "s";
|
||||
} else if (m > 0) {
|
||||
out << m << "m " << std::setw(2) << std::setfill('0') << s << "s";
|
||||
} else {
|
||||
out << s << "s";
|
||||
}
|
||||
|
||||
return out.str();
|
||||
}
|
||||
} // namespace
|
||||
class Timer : public Gtk::Box {
|
||||
public:
|
||||
Timer(const std::string &duration, uint64_t timerId) {
|
||||
uint32_t totalTime = std::stoul(duration);
|
||||
u_int64_t seconds = totalTime % 100;
|
||||
u_int64_t minutes = (totalTime / 100) % 100;
|
||||
u_int64_t hours = totalTime / 10000;
|
||||
|
||||
u_int64_t totalSeconds = hours * 3600 + minutes * 60 + seconds + 1; // +1 to account for the first tick happening after 1 second
|
||||
|
||||
this->timeLeft = totalSeconds;
|
||||
this->timerLabel = std::make_shared<Gtk::Label>(format_duration(duration));
|
||||
timerLabel->add_css_class("control-center-timer-label");
|
||||
|
||||
auto timerBox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 5);
|
||||
timerBox->append(*timerLabel);
|
||||
|
||||
auto cancelButton = Gtk::make_managed<IconButton>(Icon::Type::TOKEN);
|
||||
cancelButton->set_tooltip_text("Cancel Timer");
|
||||
cancelButton->signal_clicked().connect([this, timerId]() {
|
||||
this->timerService->removeTimer(timerId);
|
||||
});
|
||||
timerBox->append(*cancelButton);
|
||||
this->append(*timerBox);
|
||||
}
|
||||
|
||||
void activateTimer() {
|
||||
std::cout << "Timer activated" << std::endl;
|
||||
}
|
||||
|
||||
void updateTimeLeft(uint64_t timeValue) {
|
||||
uint64_t s = timeValue % 100;
|
||||
uint64_t m = (timeValue / 100) % 100;
|
||||
uint64_t h = timeValue / 10000;
|
||||
uint64_t totalSeconds = h * 3600 + m * 60 + s;
|
||||
this->timeLeft = totalSeconds;
|
||||
|
||||
std::ostringstream out;
|
||||
if (h > 0) {
|
||||
out << h << "h " << std::setw(2) << std::setfill('0') << m << "m "
|
||||
<< std::setw(2) << std::setfill('0') << s << "s";
|
||||
} else if (m > 0) {
|
||||
out << m << "m " << std::setw(2) << std::setfill('0') << s << "s";
|
||||
} else {
|
||||
out << s << "s";
|
||||
}
|
||||
|
||||
this->timerLabel->set_text(out.str());
|
||||
}
|
||||
|
||||
void tickDown() {
|
||||
if (timeLeft > 0) {
|
||||
this->updateTimeLeft(this->timeLeft - 1);
|
||||
} else {
|
||||
timeLeft = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<TimerService> timerService = TimerService::getInstance();
|
||||
uint64_t timeLeft;
|
||||
std::shared_ptr<Gtk::Label> timerLabel;
|
||||
};
|
||||
83
include/services/timerService.hpp
Normal file
83
include/services/timerService.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "glibmm/main.h"
|
||||
#include "sigc++/signal.h"
|
||||
class TimerService {
|
||||
struct TimerData {
|
||||
uint64_t duration;
|
||||
uint64_t timerId;
|
||||
};
|
||||
|
||||
public:
|
||||
static std::shared_ptr<TimerService> getInstance() {
|
||||
if (!instance) {
|
||||
instance = std::make_shared<TimerService>();
|
||||
|
||||
// add a timer to tick every second
|
||||
Glib::signal_timeout().connect([]() {
|
||||
instance->tick();
|
||||
return true; // continue calling every second
|
||||
},
|
||||
1000);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
void addTimer(uint64_t duration) {
|
||||
this->timerAddedSignal.emit(std::to_string(duration), timerIdCounter);
|
||||
|
||||
this->activeTimers[timerIdCounter] = TimerData{.duration = duration, .timerId = timerIdCounter};
|
||||
|
||||
timerIdCounter++;
|
||||
}
|
||||
|
||||
void expireTimer(uint64_t timerId) {
|
||||
this->timerExpiredSignal.emit(timerId);
|
||||
}
|
||||
|
||||
void removeTimer(uint64_t timerId) {
|
||||
this->activeTimers.erase(timerId);
|
||||
this->timerCancelledSignal.emit(timerId);
|
||||
}
|
||||
|
||||
sigc::signal<void(const std::string &, u_int64_t)> &getSignalTimerSet() {
|
||||
return this->timerAddedSignal;
|
||||
}
|
||||
|
||||
sigc::signal<void(u_int64_t)> &getSignalTimerExpired() {
|
||||
return this->timerExpiredSignal;
|
||||
}
|
||||
|
||||
sigc::signal<void(u_int64_t)> &getSignalTimerCancelled() {
|
||||
return this->timerCancelledSignal;
|
||||
}
|
||||
|
||||
sigc::signal<void()> tickSignal;
|
||||
|
||||
private:
|
||||
static inline uint64_t timerIdCounter = 0;
|
||||
sigc::signal<void(const std::string &, u_int64_t)> timerAddedSignal;
|
||||
sigc::signal<void(u_int64_t)> timerCancelledSignal;
|
||||
sigc::signal<void(u_int64_t)> timerExpiredSignal;
|
||||
inline static std::shared_ptr<TimerService> instance = nullptr;
|
||||
|
||||
std::map<uint64_t, TimerData> activeTimers;
|
||||
|
||||
void tick() {
|
||||
for (auto &[id, timer] : activeTimers) {
|
||||
|
||||
if (timer.duration > 0) {
|
||||
timer.duration--;
|
||||
} else if (timer.duration == 0) {
|
||||
expireTimer(timer.timerId);
|
||||
timer.duration = -1; // Mark as expired to prevent multiple expirations
|
||||
}
|
||||
}
|
||||
|
||||
tickSignal.emit();
|
||||
}
|
||||
};
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "components/button/tabButton.hpp"
|
||||
#include "components/popover.hpp"
|
||||
#include "widgets/controlCenter/mediaWidget.hpp"
|
||||
#include "widgets/controlCenter/timer.hpp"
|
||||
#include "widgets/weather.hpp"
|
||||
|
||||
#include "gtkmm/box.h"
|
||||
@@ -29,6 +30,7 @@ class ControlCenter : public Popover {
|
||||
|
||||
std::unique_ptr<WeatherWidget> weatherWidget;
|
||||
std::unique_ptr<MediaWidget> mediaControlWidget;
|
||||
std::unique_ptr<TimerWidget> timerWidget;
|
||||
|
||||
void addPlayerWidget(const std::string &bus_name);
|
||||
void removePlayerWidget(const std::string &bus_name);
|
||||
|
||||
22
include/widgets/controlCenter/timer.hpp
Normal file
22
include/widgets/controlCenter/timer.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <sys/types.h>
|
||||
#include "components/timer.hpp"
|
||||
#include "services/timerService.hpp"
|
||||
#include "gtkmm/box.h"
|
||||
|
||||
class TimerWidget : public Gtk::Box {
|
||||
public:
|
||||
TimerWidget();
|
||||
void addTimer(const std::string &duration, uint64_t timerId);
|
||||
void removeTimer(uint64_t timerId);
|
||||
void activateTimer(uint64_t timerId);
|
||||
|
||||
private:
|
||||
std::shared_ptr<TimerService> timerService = TimerService::getInstance();
|
||||
bool updatingText = false;
|
||||
std::string rawDigits;
|
||||
|
||||
std::map<uint64_t, std::unique_ptr<Timer>> activeTimers;
|
||||
};
|
||||
16
include/widgets/wallpaperWindow.hpp
Normal file
16
include/widgets/wallpaperWindow.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk4-layer-shell/gtk4-layer-shell.h>
|
||||
#include <gtkmm.h>
|
||||
#include <string>
|
||||
|
||||
class WallpaperWindow : public Gtk::Window {
|
||||
public:
|
||||
WallpaperWindow(GdkMonitor *monitor, const std::string &imagePath);
|
||||
|
||||
private:
|
||||
Gtk::Picture picture;
|
||||
|
||||
static std::string expand_user_path(const std::string &path);
|
||||
static Glib::RefPtr<Gdk::Texture> load_texture(const std::string &path);
|
||||
};
|
||||
Reference in New Issue
Block a user