- attempt to make app easier to understand using state management
This commit is contained in:
parent
fff67bbedb
commit
266d6ddf09
@ -83,16 +83,16 @@ void MainWindow::init()
|
|||||||
mLastIdleMilliseconds = 0;
|
mLastIdleMilliseconds = 0;
|
||||||
|
|
||||||
// Timer to start break
|
// Timer to start break
|
||||||
mTimer = new QTimer(this);
|
mBreakStartTimer = new QTimer(this);
|
||||||
mTimer->setTimerType(Qt::TimerType::CoarseTimer);
|
mBreakStartTimer->setTimerType(Qt::TimerType::CoarseTimer);
|
||||||
mTimer->setSingleShot(true);
|
mBreakStartTimer->setSingleShot(true);
|
||||||
connect(mTimer, SIGNAL(timeout()), this, SLOT(onLongBreakStart()));
|
connect(mBreakStartTimer, SIGNAL(timeout()), this, SLOT(onLongBreakStart()));
|
||||||
|
|
||||||
// Timer to run notification about upcoming break
|
// Timer to run notification about upcoming break
|
||||||
mNotifyTimer = new QTimer(this);
|
mBreakNotifyTimer = new QTimer(this);
|
||||||
mNotifyTimer->setTimerType(Qt::TimerType::CoarseTimer);
|
mBreakNotifyTimer->setTimerType(Qt::TimerType::CoarseTimer);
|
||||||
mNotifyTimer->setSingleShot(true);
|
mBreakNotifyTimer->setSingleShot(true);
|
||||||
connect(mNotifyTimer, SIGNAL(timeout()), this, SLOT(onLongBreakNotify()));
|
connect(mBreakNotifyTimer, SIGNAL(timeout()), this, SLOT(onLongBreakNotify()));
|
||||||
|
|
||||||
// Just update UI once per minute
|
// Just update UI once per minute
|
||||||
mUpdateUITimer = new QTimer(this);
|
mUpdateUITimer = new QTimer(this);
|
||||||
@ -114,8 +114,7 @@ void MainWindow::init()
|
|||||||
// Use the latest config
|
// Use the latest config
|
||||||
applyConfig();
|
applyConfig();
|
||||||
|
|
||||||
// Refresh UI
|
shiftTo(AppState::Counting);
|
||||||
onUpdateUI();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::loadConfig()
|
void MainWindow::loadConfig()
|
||||||
@ -126,17 +125,17 @@ void MainWindow::loadConfig()
|
|||||||
|
|
||||||
void MainWindow::applyConfig()
|
void MainWindow::applyConfig()
|
||||||
{
|
{
|
||||||
if (mTimer)
|
if (mBreakStartTimer)
|
||||||
{
|
{
|
||||||
if (mTimer->interval() != mAppConfig.longbreak_interval)
|
if (mBreakStartTimer->interval() != mAppConfig.longbreak_interval)
|
||||||
{
|
{
|
||||||
mTimer->stop();
|
mBreakStartTimer->stop();
|
||||||
mTimer->setInterval(std::chrono::seconds(mAppConfig.longbreak_interval));
|
mBreakStartTimer->setInterval(std::chrono::seconds(mAppConfig.longbreak_interval));
|
||||||
mTimer->start();
|
mBreakStartTimer->start();
|
||||||
|
|
||||||
mNotifyTimer->stop();
|
mBreakNotifyTimer->stop();
|
||||||
mNotifyTimer->setInterval(std::chrono::seconds(mAppConfig.longbreak_interval - 30));
|
mBreakNotifyTimer->setInterval(std::chrono::seconds(mAppConfig.longbreak_interval - 30));
|
||||||
mNotifyTimer->start();
|
mBreakNotifyTimer->start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +209,10 @@ void MainWindow::showMe()
|
|||||||
// qDebug() << "Window moved to screen " << screen->name() + " / " + screen->model() + " " + screen->manufacturer();
|
// qDebug() << "Window moved to screen " << screen->name() + " / " + screen->model() + " " + screen->manufacturer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(DEBUG)
|
||||||
showFullScreen();
|
showFullScreen();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::hideMe()
|
void MainWindow::hideMe()
|
||||||
@ -262,79 +264,90 @@ static int msec2min(int msec)
|
|||||||
return (int)(min_f + 0.5f);
|
return (int)(min_f + 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onUpdateUI()
|
void MainWindow::shiftTo(AppState newState)
|
||||||
{
|
{
|
||||||
if (mAppConfig.idle_timeout != 0 && (mTimer->isActive() || mIdleStart))
|
if (newState == mState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (newState)
|
||||||
{
|
{
|
||||||
int idle_milliseconds = get_idle_time_dynamically();
|
case AppState::None:
|
||||||
if (idle_milliseconds >= mAppConfig.idle_timeout * 60 * 1000)
|
// Do nothing, app is not started
|
||||||
{
|
break;
|
||||||
if (!mIdleStart)
|
|
||||||
{
|
|
||||||
// Idle could start before timer start
|
|
||||||
// Check and shrink the found idle interval if needed
|
|
||||||
auto current_time = std::chrono::steady_clock::now();
|
|
||||||
auto proposed_idle_start = current_time - std::chrono::milliseconds(idle_milliseconds);
|
|
||||||
auto timer_start = std::chrono::steady_clock::now() - (std::chrono::milliseconds(mTimer->interval() - mTimer->remainingTime()));
|
|
||||||
mIdleStart = std::max(timer_start, proposed_idle_start);
|
|
||||||
|
|
||||||
// Start idle mode. Save idle start time
|
case AppState::Idle:
|
||||||
// mIdleStart = std::chrono::steady_clock::now() - std::chrono::milliseconds(idle_milliseconds);
|
onIdleStart();
|
||||||
if (mTimer->isActive())
|
break;
|
||||||
{
|
|
||||||
// Correct duration of idle
|
|
||||||
idle_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(current_time - mIdleStart.value()).count();
|
|
||||||
|
|
||||||
// Save how much time was remaininig when idle was detected + add idle length
|
case AppState::Break:
|
||||||
// Later timer will restart with this interval time
|
// Break is active
|
||||||
mIdleRemaining = mTimer->remainingTime() + idle_milliseconds;
|
onLongBreakStart();
|
||||||
|
break;
|
||||||
|
|
||||||
// Stop counting
|
case AppState::Counting:
|
||||||
mTimer->stop();
|
// Working, break is closing
|
||||||
mNotifyTimer->stop();
|
if (mState == AppState::Break)
|
||||||
|
onLongBreakEnd();
|
||||||
// Update "Remaining ..." label
|
else
|
||||||
mTrayIcon->setToolTip(tr("There are %1 minutes left until the next break.").arg(msec2min(mIdleRemaining)));
|
if (mState == AppState::Idle)
|
||||||
}
|
onIdleEnd();
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
{
|
|
||||||
// Do nothing here - main timer is stopped, idle time & timer remaining duration are recorded already
|
|
||||||
// How much time remains ?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mIdleStart)
|
|
||||||
{
|
|
||||||
// Idle interval ended
|
|
||||||
mIdleStart.reset();
|
|
||||||
mTimer->start(mIdleRemaining);
|
|
||||||
mNotifyTimer->start(std::max(1, mIdleRemaining - 30 * 1000));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Do nothing here - timer is running already
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTrayIcon)
|
mState = newState;
|
||||||
|
onUpdateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onUpdateUI()
|
||||||
|
{
|
||||||
|
int idle_milliseconds = 0;
|
||||||
|
switch (mState)
|
||||||
{
|
{
|
||||||
if (mProgressTimer->isActive())
|
case AppState::None:
|
||||||
|
// Do nothing, app is not started
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AppState::Idle:
|
||||||
|
// Detected idle, don't count this time as working
|
||||||
|
// But check - maybe idle is over
|
||||||
|
idle_milliseconds = get_idle_time_dynamically();
|
||||||
|
if (idle_milliseconds < mAppConfig.idle_timeout * 60 * 1000)
|
||||||
{
|
{
|
||||||
// Break is in effect now
|
shiftTo(AppState::Counting);
|
||||||
mTrayIcon->setToolTip(QString());
|
return;
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
if (mTimer->isActive())
|
|
||||||
|
case AppState::Break:
|
||||||
|
// Break is active
|
||||||
|
if (mTrayIcon)
|
||||||
|
mTrayIcon->setToolTip(QString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AppState::Counting:
|
||||||
|
// Working, break is closing
|
||||||
|
// Check maybe it is idle ?
|
||||||
|
if (!mIdleStart && mAppConfig.idle_timeout)
|
||||||
{
|
{
|
||||||
auto remaining_milliseconds = mTimer->remainingTime();
|
idle_milliseconds = get_idle_time_dynamically();
|
||||||
|
if (idle_milliseconds >= mAppConfig.idle_timeout * 60 * 1000)
|
||||||
|
{
|
||||||
|
shiftTo(AppState::Idle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update tray icon
|
||||||
|
if (mTrayIcon)
|
||||||
|
{
|
||||||
|
auto remaining_milliseconds = mBreakStartTimer->remainingTime();
|
||||||
if (remaining_milliseconds < 60000)
|
if (remaining_milliseconds < 60000)
|
||||||
mTrayIcon->setToolTip(tr("Less than a minute left until the next break."));
|
mTrayIcon->setToolTip(tr("Less than a minute left until the next break."));
|
||||||
else
|
else
|
||||||
mTrayIcon->setToolTip(tr("There are %1 minutes left until the next break.").arg(msec2min(remaining_milliseconds)));
|
mTrayIcon->setToolTip(tr("There are %1 minutes left until the next break.").arg(msec2min(remaining_milliseconds)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->mSkipButton->setVisible(mPostponeCount > 0);
|
ui->mSkipButton->setVisible(mPostponeCount > 0);
|
||||||
@ -350,18 +363,19 @@ void MainWindow::onLongBreakNotify()
|
|||||||
|
|
||||||
void MainWindow::onLongBreakStart()
|
void MainWindow::onLongBreakStart()
|
||||||
{
|
{
|
||||||
// qDebug() << "Long break starts for " << secondsToText(mAppConfig.longbreak_postpone_interval);
|
mBreakStartTimer->stop();
|
||||||
|
mBreakNotifyTimer->stop();
|
||||||
mTimer->stop();
|
|
||||||
mNotifyTimer->stop();
|
|
||||||
|
|
||||||
// Reset idle counter
|
// Reset idle counter
|
||||||
|
mIdleStart.reset();
|
||||||
|
|
||||||
mLastIdleMilliseconds = 0;
|
// Show the button "Postpone"
|
||||||
|
|
||||||
ui->mPostponeButton->setText(tr("Postpone for ") + secondsToText(mAppConfig.longbreak_postpone_interval));
|
ui->mPostponeButton->setText(tr("Postpone for ") + secondsToText(mAppConfig.longbreak_postpone_interval));
|
||||||
|
|
||||||
|
// Show the screen
|
||||||
showMe();
|
showMe();
|
||||||
|
|
||||||
|
// Save start time
|
||||||
mBreakStartTime = std::chrono::steady_clock::now();
|
mBreakStartTime = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
// Start progress bar
|
// Start progress bar
|
||||||
@ -387,10 +401,10 @@ void MainWindow::onLongBreakEnd()
|
|||||||
mProgressTimer->stop();
|
mProgressTimer->stop();
|
||||||
|
|
||||||
// Start new timer
|
// Start new timer
|
||||||
mTimer->stop();
|
mBreakStartTimer->stop();
|
||||||
mTimer->start(std::chrono::seconds(mAppConfig.longbreak_interval));
|
mBreakStartTimer->start(std::chrono::seconds(mAppConfig.longbreak_interval));
|
||||||
mNotifyTimer->stop();
|
mBreakNotifyTimer->stop();
|
||||||
mNotifyTimer->start(std::chrono::seconds(mAppConfig.longbreak_interval - 30));
|
mBreakNotifyTimer->start(std::chrono::seconds(mAppConfig.longbreak_interval - 30));
|
||||||
|
|
||||||
// Refresh UI
|
// Refresh UI
|
||||||
onUpdateUI();
|
onUpdateUI();
|
||||||
@ -418,10 +432,10 @@ void MainWindow::onLongBreakPostpone()
|
|||||||
ui->mProgressBar->setValue(0);
|
ui->mProgressBar->setValue(0);
|
||||||
|
|
||||||
// Start timer again
|
// Start timer again
|
||||||
mTimer->stop();
|
mBreakStartTimer->stop();
|
||||||
mTimer->start(std::chrono::seconds(mAppConfig.longbreak_postpone_interval));
|
mBreakStartTimer->start(std::chrono::seconds(mAppConfig.longbreak_postpone_interval));
|
||||||
mNotifyTimer->stop();
|
mBreakNotifyTimer->stop();
|
||||||
mNotifyTimer->start(std::chrono::seconds(mAppConfig.longbreak_postpone_interval - 30));
|
mBreakNotifyTimer->start(std::chrono::seconds(mAppConfig.longbreak_postpone_interval - 30));
|
||||||
|
|
||||||
// Refresh UI
|
// Refresh UI
|
||||||
onUpdateUI();
|
onUpdateUI();
|
||||||
@ -443,7 +457,7 @@ void MainWindow::onProgress()
|
|||||||
if (percents > 100)
|
if (percents > 100)
|
||||||
{
|
{
|
||||||
mProgressTimer->stop();
|
mProgressTimer->stop();
|
||||||
onLongBreakEnd();
|
shiftTo(AppState::Counting);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
showMe();
|
showMe();
|
||||||
@ -451,13 +465,40 @@ void MainWindow::onProgress()
|
|||||||
|
|
||||||
void MainWindow::onNextBreak()
|
void MainWindow::onNextBreak()
|
||||||
{
|
{
|
||||||
mIdleRemaining = 0;
|
shiftTo(AppState::Break);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onIdleStart()
|
||||||
|
{
|
||||||
|
if (mState != AppState::Counting)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Detected idle
|
||||||
|
// Timestamp when idle started
|
||||||
|
mIdleStart = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
// How much working time remains
|
||||||
|
mWorkInterval = mBreakStartTimer->remainingTime();
|
||||||
|
|
||||||
|
// Stop main & notify timers
|
||||||
|
mBreakStartTimer->stop();
|
||||||
|
mBreakNotifyTimer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onIdleEnd()
|
||||||
|
{
|
||||||
|
if (mState != AppState::Idle)
|
||||||
|
return;
|
||||||
|
|
||||||
mIdleStart.reset();
|
mIdleStart.reset();
|
||||||
|
|
||||||
mTimer->stop();
|
// Update timer(s) duration
|
||||||
mNotifyTimer->stop();
|
mBreakStartTimer->setInterval(mWorkInterval);
|
||||||
|
if (mWorkInterval > INTERVAL_NOTIFICATION)
|
||||||
|
mBreakNotifyTimer->setInterval(mWorkInterval - INTERVAL_NOTIFICATION);
|
||||||
|
|
||||||
onLongBreakStart();
|
mWorkInterval = mAppConfig.longbreak_interval * 1000;
|
||||||
|
shiftTo(AppState::Counting);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onSettings()
|
void MainWindow::onSettings()
|
||||||
|
|||||||
@ -40,16 +40,16 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
QTimer* mMainTimer;
|
QTimer* mBreakStartTimer; // Main timer - triggers when break occurs
|
||||||
QTimer* mNotifyTimer;
|
QTimer* mBreakNotifyTimer; // Timer to show notification from system tray
|
||||||
QTimer* mUpdateUITimer;
|
QTimer* mUpdateUITimer; // Update UI timer - triggers every minute to update UI and checks for idle
|
||||||
QTimer* mProgressTimer;
|
QTimer* mProgressTimer; // Break progress timer
|
||||||
QSystemTrayIcon* mTrayIcon;
|
QSystemTrayIcon* mTrayIcon;
|
||||||
SettingsDialog* mSettingsDialog;
|
SettingsDialog* mSettingsDialog;
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point mBreakStartTime;
|
std::chrono::steady_clock::time_point mBreakStartTime;
|
||||||
|
|
||||||
// How much seconds remains for main break
|
// How much milliseconds remains for main break
|
||||||
int mWorkInterval = -1;
|
int mWorkInterval = -1;
|
||||||
|
|
||||||
app_settings::config mAppConfig;
|
app_settings::config mAppConfig;
|
||||||
@ -84,6 +84,8 @@ public slots:
|
|||||||
void onLongBreakStart();
|
void onLongBreakStart();
|
||||||
void onLongBreakPostpone();
|
void onLongBreakPostpone();
|
||||||
void onLongBreakEnd();
|
void onLongBreakEnd();
|
||||||
|
void onIdleStart();
|
||||||
|
void onIdleEnd();
|
||||||
|
|
||||||
void onProgress();
|
void onProgress();
|
||||||
void onNextBreak();
|
void onNextBreak();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user