summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/shell/quickshell-plugins
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/gkleen@sif/shell/quickshell-plugins')
-rw-r--r--accounts/gkleen@sif/shell/quickshell-plugins/CMakeLists.txt1
-rw-r--r--accounts/gkleen@sif/shell/quickshell-plugins/Chrono.cpp12
-rw-r--r--accounts/gkleen@sif/shell/quickshell-plugins/Chrono.hpp14
-rw-r--r--accounts/gkleen@sif/shell/quickshell-plugins/FileSelector.cpp99
-rw-r--r--accounts/gkleen@sif/shell/quickshell-plugins/FileSelector.hpp52
5 files changed, 162 insertions, 16 deletions
diff --git a/accounts/gkleen@sif/shell/quickshell-plugins/CMakeLists.txt b/accounts/gkleen@sif/shell/quickshell-plugins/CMakeLists.txt
index aa363c4c..2123ed35 100644
--- a/accounts/gkleen@sif/shell/quickshell-plugins/CMakeLists.txt
+++ b/accounts/gkleen@sif/shell/quickshell-plugins/CMakeLists.txt
@@ -104,6 +104,7 @@ qt6_add_qml_module(customplugin
104 104
105target_sources(customplugin PRIVATE 105target_sources(customplugin PRIVATE
106 Chrono.cpp Chrono.hpp 106 Chrono.cpp Chrono.hpp
107 FileSelector.cpp FileSelector.hpp
107) 108)
108 109
109target_compile_features(customplugin PUBLIC cxx_std_26) 110target_compile_features(customplugin PUBLIC cxx_std_26)
diff --git a/accounts/gkleen@sif/shell/quickshell-plugins/Chrono.cpp b/accounts/gkleen@sif/shell/quickshell-plugins/Chrono.cpp
index 929b7be6..df0c5781 100644
--- a/accounts/gkleen@sif/shell/quickshell-plugins/Chrono.cpp
+++ b/accounts/gkleen@sif/shell/quickshell-plugins/Chrono.cpp
@@ -75,14 +75,10 @@ void Chrono::schedule(const std::chrono::time_point<std::chrono::system_clock>&
75 this->timer.start(delay); 75 this->timer.start(delay);
76} 76}
77 77
78QString Chrono::format() const { return this->mFormat; } 78QString Chrono::format(const QString& fmt) const {
79void Chrono::setFormat(QString format) { 79 return QString::fromStdString(std::format(std::runtime_format(fmt.toStdString()), std::chrono::zoned_time(std::chrono::current_zone(), std::chrono::time_point_cast<std::chrono::seconds>(this->currentTime))));
80 if (format == this->mFormat) return;
81 this->mFormat = format;
82 emit this->formatChanged();
83 this->update();
84} 80}
85 81
86QString Chrono::date() const { 82QDateTime Chrono::date() const {
87 return QString::fromStdString(std::format(std::runtime_format(this->mFormat.toStdString()), std::chrono::zoned_time(std::chrono::current_zone(), std::chrono::time_point_cast<std::chrono::seconds>(this->currentTime)))); 83 return QDateTime::fromStdTimePoint(std::chrono::time_point_cast<std::chrono::milliseconds>(this->currentTime));
88} 84}
diff --git a/accounts/gkleen@sif/shell/quickshell-plugins/Chrono.hpp b/accounts/gkleen@sif/shell/quickshell-plugins/Chrono.hpp
index 788fa88e..04080187 100644
--- a/accounts/gkleen@sif/shell/quickshell-plugins/Chrono.hpp
+++ b/accounts/gkleen@sif/shell/quickshell-plugins/Chrono.hpp
@@ -1,17 +1,18 @@
1#pragma once 1#pragma once
2 2
3#include <chrono>
4
5#include <QDateTime>
3#include <QObject> 6#include <QObject>
4#include <QTimer> 7#include <QTimer>
5 8
6#include <qqmlintegration.h> 9#include <qqmlintegration.h>
7#include <chrono>
8 10
9class Chrono : public QObject { 11class Chrono : public QObject {
10 Q_OBJECT; 12 Q_OBJECT;
11 Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged); 13 Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged);
12 Q_PROPERTY(Chrono::Precision precision READ precision WRITE setPrecision NOTIFY precisionChanged); 14 Q_PROPERTY(Chrono::Precision precision READ precision WRITE setPrecision NOTIFY precisionChanged);
13 Q_PROPERTY(QString format READ format WRITE setFormat NOTIFY formatChanged); 15 Q_PROPERTY(QDateTime date READ date NOTIFY dateChanged)
14 Q_PROPERTY(QString date READ date NOTIFY dateChanged);
15 QML_ELEMENT; 16 QML_ELEMENT;
16 17
17public: 18public:
@@ -30,15 +31,13 @@ public:
30 Chrono::Precision precision() const; 31 Chrono::Precision precision() const;
31 void setPrecision(Chrono::Precision precision); 32 void setPrecision(Chrono::Precision precision);
32 33
33 QString format() const; 34 Q_INVOKABLE QString format(const QString& fmt) const;
34 void setFormat (QString format);
35 35
36 QString date() const; 36 QDateTime date() const;
37 37
38signals: 38signals:
39 void enabledChanged(); 39 void enabledChanged();
40 void precisionChanged(); 40 void precisionChanged();
41 void formatChanged();
42 void dateChanged(); 41 void dateChanged();
43 42
44private slots: 43private slots:
@@ -47,7 +46,6 @@ private slots:
47private: 46private:
48 bool mEnabled = true; 47 bool mEnabled = true;
49 Chrono::Precision mPrecision = Chrono::Seconds; 48 Chrono::Precision mPrecision = Chrono::Seconds;
50 QString mFormat = "{:%c}";
51 QTimer timer; 49 QTimer timer;
52 std::chrono::time_point<std::chrono::system_clock> currentTime, targetTime; 50 std::chrono::time_point<std::chrono::system_clock> currentTime, targetTime;
53 51
diff --git a/accounts/gkleen@sif/shell/quickshell-plugins/FileSelector.cpp b/accounts/gkleen@sif/shell/quickshell-plugins/FileSelector.cpp
new file mode 100644
index 00000000..3a0537b6
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell-plugins/FileSelector.cpp
@@ -0,0 +1,99 @@
1#include "FileSelector.hpp"
2
3#include <sstream>
4#include <vector>
5#include <random>
6#include <algorithm>
7
8#include <iostream>
9#include <format>
10
11namespace fs = std::filesystem;
12
13FileSelector::FileSelector(QObject* parent): QObject(parent) {
14 QObject::connect(&this->timer, &QTimer::timeout, this, &FileSelector::onTimeout);
15}
16
17QString FileSelector::directory() const {
18 return QString::fromStdString(this->mDirectory->string());
19}
20void FileSelector::setDirectory(QString directory) {
21 this->mDirectory = directory.toStdString();
22 if (this->mDirectory && this->mEpoch)
23 this->update();
24 emit this->directoryChanged();
25}
26
27unsigned int FileSelector::epoch() const {
28 return std::chrono::duration_cast<std::chrono::milliseconds>(*this->mEpoch).count();
29}
30void FileSelector::setEpoch(unsigned int epoch) {
31 this->mEpoch = std::chrono::milliseconds{epoch};
32 if (this->mDirectory && this->mEpoch)
33 this->update();
34 emit this->epochChanged();
35}
36
37QString FileSelector::seed() const {
38 return this->mSeed;
39}
40void FileSelector::setSeed(QString seed) {
41 this->mSeed = seed;
42 emit this->seedChanged();
43}
44
45QString FileSelector::selected() const {
46 if (!this->mDirectory || !this->mEpoch)
47 return QString();
48
49 std::vector<fs::path> shuffled(this->mFiles.begin(), this->mFiles.end());
50 std::sort(shuffled.begin(), shuffled.end());
51
52 auto currentTime = std::chrono::system_clock::now();
53 uint64_t currentEpoch = currentTime.time_since_epoch() / *this->mEpoch;
54 std::chrono::milliseconds timeInEpoch = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime.time_since_epoch()) % *this->mEpoch;
55
56 std::ostringstream seed;
57 seed << this->mSeed.size() << ";" << this->mSeed.toStdString() << ";";
58 seed << *this->mEpoch << ";";
59 seed << currentEpoch << ";";
60 seed << this->mDirectory->string().size() << ";" << *this->mDirectory << ";";
61 seed << this->mFiles.size() << ";";
62 for (const fs::path& p: this->mFiles)
63 seed << p.string().size() << ";" << p << ";";
64
65 std::vector<std::seed_seq::result_type> v;
66 v.reserve(seed.str().size());
67 for (const char& c: seed.str())
68 v.push_back(c);
69
70 std::seed_seq engine_seed(v.begin(), v.end());
71 std::mt19937 g(engine_seed);
72 std::shuffle(shuffled.begin(), shuffled.end(), g);
73
74 std::vector<fs::path>::size_type ix = shuffled.size() * timeInEpoch / *this->mEpoch;
75 return QString::fromStdString((*this->mDirectory / shuffled[ix]).string());
76}
77
78void FileSelector::onTimeout() {
79 if (!this->mFiles.size())
80 return;
81
82 auto currentTime = std::chrono::system_clock::now();
83 uint64_t currentMinorEpoch = currentTime.time_since_epoch() / (*this->mEpoch / this->mFiles.size());
84 auto nextTime = std::chrono::time_point<std::chrono::system_clock>((2 * currentMinorEpoch + 3) * (*this->mEpoch / (this->mFiles.size() * 2)));
85 this->timer.start(std::chrono::duration_cast<std::chrono::milliseconds>(nextTime - currentTime).count());
86
87 emit this->selectedChanged();
88}
89
90void FileSelector::update() {
91 this->mFiles = std::set<fs::path>{};
92 for (const fs::directory_entry& entry:
93 fs::recursive_directory_iterator(*this->mDirectory, fs::directory_options::follow_directory_symlink))
94 {
95 this->mFiles.insert(fs::relative(entry, *this->mDirectory));
96 }
97
98 this->onTimeout();
99}
diff --git a/accounts/gkleen@sif/shell/quickshell-plugins/FileSelector.hpp b/accounts/gkleen@sif/shell/quickshell-plugins/FileSelector.hpp
new file mode 100644
index 00000000..72c4f2a7
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell-plugins/FileSelector.hpp
@@ -0,0 +1,52 @@
1#pragma once
2
3#include <filesystem>
4#include <chrono>
5#include <set>
6#include <optional>
7
8#include <QObject>
9#include <QTimer>
10
11#include <qqmlintegration.h>
12
13class FileSelector : public QObject {
14 Q_OBJECT;
15 Q_PROPERTY(QString directory READ directory WRITE setDirectory NOTIFY directoryChanged REQUIRED);
16 Q_PROPERTY(unsigned int epoch READ epoch WRITE setEpoch NOTIFY epochChanged REQUIRED);
17 Q_PROPERTY(QString seed READ seed WRITE setSeed NOTIFY seedChanged);
18 Q_PROPERTY(QString selected READ selected NOTIFY selectedChanged);
19 QML_ELEMENT;
20
21public:
22 explicit FileSelector(QObject* parent = nullptr);
23
24 QString directory() const;
25 void setDirectory(QString directory);
26
27 unsigned int epoch() const;
28 void setEpoch(unsigned int epoch);
29
30 QString seed() const;
31 void setSeed(QString seed);
32
33 QString selected() const;
34
35signals:
36 void directoryChanged();
37 void epochChanged();
38 void seedChanged();
39 void selectedChanged();
40
41private slots:
42 void onTimeout();
43
44private:
45 std::optional<std::filesystem::path> mDirectory;
46 std::optional<std::chrono::milliseconds> mEpoch;
47 std::set<std::filesystem::path> mFiles;
48 QString mSeed;
49 QTimer timer;
50
51 void update();
52};