Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reset timers feature #52

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Source/EyesGuard.Data/Languages/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Translation:
- In this mode, Eyes Guard automatically pauses down-counting.
- Notice that this feature can disable guarding your eyes when you are not
interacting with your PC, for example when watching movies.
ResetTimersAfterIdleGap: 'Reset timers when system goes to idle mode exceeds:'
StatsSettings:
Title: Stats
YesDeleteData: Yes, Sure
Expand Down
7 changes: 6 additions & 1 deletion Source/EyesGuard.Data/Languages/zh-CN.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ Meta:
- Name: 七夕泥
GitHubUsername: Qixiny
Website: https://github.com/Qxiny
Notes: '第一次翻译软件请多多指教,翻译的有些太可爱了~ 邮箱:[email protected]'
Notes: '第一次翻译软件请多多指教,翻译的有些太可爱了~ 邮箱:[email protected]'
- Name: 0ow
GitHubUsername: z0ow
Website: https://github.com/z0ow
Notes: '新增计时器重置翻译选项(仅中文)'

Translation:
Application:
Expand Down Expand Up @@ -113,6 +117,7 @@ Translation:
ShortBreakAllowCloseWithRightCLick: 鼠标右键关闭让你去小型休息的提示
ShortBreakAllowCloseWithRightCLickToolTip: 允许你在那个烦人的窗口跳出来的时候右键把它关掉(然后你的眼睛就......)
SystemIdle: 你不动电脑的时候护眼姬自动帮你暂停
ResetTimersAfterIdleGap: '当系统空闲超过该时间后重置所有计时器:'
SystemIdleToolTip:
- 当你不动电脑的时候将会自动暂停休息系统
- 例如你电脑搁着忘关了,或者是在看电影
Expand Down
19 changes: 16 additions & 3 deletions Source/EyesGuard/App.Initialization.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private void Application_Startup(object sender, StartupEventArgs e)
Shutdown();
}

InitializeIdleDetector(Configuration.SystemIdleDetectionEnabled);
InitializeIdleDetector(Configuration.SystemIdleDetectionEnabled | Configuration.EnableResetTimerAfterIdleDuration);

ToolTipService.ShowDurationProperty.OverrideMetadata(
typeof(DependencyObject), new FrameworkPropertyMetadata(int.MaxValue));
Expand Down Expand Up @@ -152,8 +152,7 @@ private void InitializeIdleDetector(bool initialStart)
SystemIdleDetector = new IdleDetector()
{
IdleThreshold = EyesGuardIdleDetectionThreshold,
DeferUpdate = false,
EnableRaisingEvents = initialStart
DeferUpdate = false
};
SystemIdleDetector.IdleStateChanged += SystemIdleDetector_IdleStateChanged;

Expand All @@ -166,6 +165,20 @@ private void InitializeIdleDetector(bool initialStart)
private void SystemIdleDetector_IdleStateChanged(object sender, IdleStateChangedEventArgs e)
{
UpdateIdleActions();

if (App.Configuration.EnableResetTimerAfterIdleDuration &&
!CheckIfResting(showWarning: false) &&
e.IdleState &&
e.Duration > App.Configuration.ResetTimersAfterIdleDuration.TotalSeconds)
{
ShortBreakHandler.Stop();
LongBreakHandler.Stop();
NextShortBreak = App.Configuration.ShortBreakGap;
NextLongBreak = App.Configuration.LongBreakGap;
ShortBreakHandler.Start();
LongBreakHandler.Start();
}

}

public static void UpdateIdleActions()
Expand Down
1 change: 0 additions & 1 deletion Source/EyesGuard/App.Properties.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public static bool IsProtectionPaused
.ShortLongBreakTimeRemaining
.IsProtectionPaused = value;
UIViewModels.NotifyIcon.PausedVisibility = value ? Visibility.Visible : Visibility.Collapsed;
SystemIdleDetector.EnableRaisingEvents = !value;
}
}

Expand Down
31 changes: 31 additions & 0 deletions Source/EyesGuard/Configurations/ConfigurationProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public partial class Configuration
private bool _keyTimeVisible = true;
private bool runAtStartup = false;
private bool _systemIdleDetectionEnabled = false;
private bool _enableResetTimerAfterIdleDuration = false;
#endregion

#region Config :: Fields :: Public Properties
Expand Down Expand Up @@ -110,6 +111,36 @@ public bool SystemIdleDetectionEnabled
}
}

public bool EnableResetTimerAfterIdleDuration
{
get => _enableResetTimerAfterIdleDuration;
set
{
_enableResetTimerAfterIdleDuration = value;

if (SystemIdleDetector != null)
{
if (value && SystemIdleDetector.State == IdleDetectorState.Stopped)
{
_ = SystemIdleDetector.RequestStart();
}
else if (!value && SystemIdleDetector.State == IdleDetectorState.Running)
{
_ = SystemIdleDetector.RequestCancel();
}
}
}
}

[XmlIgnore]
public TimeSpan ResetTimersAfterIdleDuration { get; set; } = new TimeSpan(0, 45, 0);

public string ResetTimersAfterIdleGapString
{
get { return ResetTimersAfterIdleDuration.ToString(); }
set { ResetTimersAfterIdleDuration = TimeSpan.Parse(value); }
}

public string ApplicationLocale { get; set; } = FsLanguageLoader.DefaultLocale;

public bool UseLanguageProvedidShortMessages { get; set; } = true;
Expand Down
16 changes: 11 additions & 5 deletions Source/EyesGuard/IdleDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public enum IdleDetectorState
public class IdleStateChangedEventArgs : EventArgs
{
public bool IdleState { get; set; }
public long Duration { get; set; }
}

public class IdleDetector
Expand All @@ -39,8 +40,6 @@ public class IdleDetector

private bool cancelRequested = false;

public bool EnableRaisingEvents { get; set; } = false;

public event EventHandler<IdleStateChangedEventArgs> IdleStateChanged;

internal struct LASTINPUTINFO
Expand All @@ -55,6 +54,7 @@ public async Task RequestStart()
LASTINPUTINFO lastInPut = new LASTINPUTINFO();
lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut);
State = IdleDetectorState.Running;
int lastTriggerTime = Environment.TickCount;

while (!cancelRequested)
{
Expand All @@ -64,15 +64,21 @@ public async Task RequestStart()
}
catch
{
EnableRaisingEvents = false;
break;
}
IdleDuration = (Environment.TickCount - lastInPut.dwTime) / 1000;

if (EnableRaisingEvents && (IsSystemIdle() != previousSystemInputIdle))
if ((App.Configuration.ProtectionState == App.GuardStates.Protecting) &&
(IsSystemIdle() != previousSystemInputIdle))
{
IdleStateChangedEventArgs lastEventStateArgs = new IdleStateChangedEventArgs()
{
IdleState = previousSystemInputIdle,
Duration = (Environment.TickCount - lastTriggerTime) / 1000
};
lastTriggerTime = Environment.TickCount;
previousSystemInputIdle = IsSystemIdle();
IdleStateChanged?.Invoke(null, null);
IdleStateChanged?.Invoke(null, lastEventStateArgs);
}
await Task.Delay(UpdateInterval);
}
Expand Down
77 changes: 72 additions & 5 deletions Source/EyesGuard/Views/Pages/Settings.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,16 @@
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15" />
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border
Grid.RowSpan="7"
Grid.RowSpan="8"
Grid.Column="0"
Margin="6,-0.5,0,0"
BorderBrush="White"
Expand All @@ -333,6 +335,7 @@
<StackPanel
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="5"
Orientation="Horizontal">
<CheckBox
Expand All @@ -348,6 +351,7 @@
<StackPanel
Grid.Row="3"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="5"
Orientation="Horizontal">
<CheckBox
Expand All @@ -361,7 +365,8 @@

<StackPanel
Grid.Row="4"
Grid.Column="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="5"
Orientation="Horizontal"
ToolTip="{lang:LocalizedString 'EyesGuard.Settings.UserSettings.StartupApplicationToolTip'}">
Expand All @@ -379,7 +384,8 @@

<StackPanel
Grid.Row="5"
Grid.Column="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="5"
Orientation="Horizontal">
<CheckBox
Expand All @@ -391,11 +397,72 @@
ToolTip="{lang:LocalizedString 'EyesGuard.Settings.UserSettings.SystemIdleToolTipJoined'}" />

</StackPanel>
<StackPanel
<CheckBox
Grid.Row="6"
Grid.Column="1"
Margin="5"
Orientation="Horizontal">
x:Name="resetTimersAfterIdleDurationCheckbox"
VerticalAlignment="Center"
Checked="resetTimersAfterIdleDurationCheckbox_Checked"
Unchecked="resetTimersAfterIdleDurationCheckbox_Unchecked"
Content="{lang:LocalizedString 'EyesGuard.Settings.UserSettings.ResetTimersAfterIdleGap'}"
Foreground="White"
IsChecked="False"
Style="{DynamicResource WhiteCheckbox}" />
<StackPanel
x:Name="resetTimersAfterIdleGapInputStack"
Grid.Row="6"
Grid.Column="2"
Margin="5"
Orientation="Horizontal"
IsEnabled="False">
<c:NumOnlyTextbox
x:Name="resetTimersAfterIdleDurationHours"
MinWidth="50"
Margin="10,0,0,0"
MaxLength="2"
Style="{DynamicResource WhiteTextBox}"
Text="0"
TextAlignment="Center" />
<TextBlock
Margin="5,0,0,0"
VerticalAlignment="Center"
Foreground="White"
Text="{lang:LocalizedString 'EyesGuard.Settings.TimeSeparators.Hour'}" />
<c:NumOnlyTextbox
x:Name="resetTimersAfterIdleDurationMinutes"
MinWidth="50"
Margin="5,0,0,0"
MaxLength="2"
Style="{DynamicResource WhiteTextBox}"
Text="0"
TextAlignment="Center" />
<TextBlock
Margin="5,0,0,0"
VerticalAlignment="Center"
Foreground="White"
Text="{lang:LocalizedString 'EyesGuard.Settings.TimeSeparators.Minutes'}" />
<c:NumOnlyTextbox
x:Name="resetTimersAfterIdleDurationSeconds"
MinWidth="50"
Margin="5,0,0,0"
MaxLength="2"
Style="{DynamicResource WhiteTextBox}"
Text="0"
TextAlignment="Center" />
<TextBlock
Margin="5,0,0,0"
VerticalAlignment="Center"
Foreground="White"
Text="{lang:LocalizedString 'EyesGuard.Settings.TimeSeparators.Second'}" />

</StackPanel>
<StackPanel
Grid.Row="7"
Grid.Column="1"
Margin="5"
Orientation="Horizontal"
Grid.ColumnSpan="2">
<CheckBox
x:Name="shortBreakAllowCloseWithRightCLick"
VerticalAlignment="Center"
Expand Down
24 changes: 23 additions & 1 deletion Source/EyesGuard/Views/Pages/Settings.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ private void Page_Loaded(object sender, RoutedEventArgs e)

sytemIdleCheckbox.IsChecked = App.Configuration.SystemIdleDetectionEnabled;

resetTimersAfterIdleDurationCheckbox.IsChecked = App.Configuration.EnableResetTimerAfterIdleDuration;
resetTimersAfterIdleDurationHours.Text = App.Configuration.ResetTimersAfterIdleDuration.Hours.ToString();
resetTimersAfterIdleDurationMinutes.Text = App.Configuration.ResetTimersAfterIdleDuration.Minutes.ToString();
resetTimersAfterIdleDurationSeconds.Text = App.Configuration.ResetTimersAfterIdleDuration.Seconds.ToString();

UseLanguageAsSourceCheckbox.IsChecked = App.Configuration.UseLanguageProvedidShortMessages;
}

Expand Down Expand Up @@ -125,7 +130,8 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
// sd: Short Duration
// lg: Long Gap
// ld: Long Duration
int sgH, sgM, sgS, sdH, sdM, sdS, lgH, lgM, lgS, ldH, ldM, ldS;
// rd: Reset Duration
int sgH, sgM, sgS, sdH, sdM, sdS, lgH, lgM, lgS, ldH, ldM, ldS, rdH, rdM, rdS;

sgH = int.Parse(shortGapHours.Text);
sgM = int.Parse(shortGapMinutes.Text);
Expand All @@ -143,6 +149,10 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
ldM = int.Parse(longDurationMinutes.Text);
ldS = int.Parse(longDurationSeconds.Text);

rdH = int.Parse(resetTimersAfterIdleDurationHours.Text);
rdM = int.Parse(resetTimersAfterIdleDurationMinutes.Text);
rdS = int.Parse(resetTimersAfterIdleDurationSeconds.Text);

if (sgH > 11 || sdH > 11 || lgH > 11 || ldH > 11)
warning += "» " + App.LocalizedEnvironment.Translation.EyesGuard.TimeManipulation.HoursLimit.FormatWith(new { Hours = 11 });

Expand Down Expand Up @@ -217,6 +227,8 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
App.Configuration.AlertBeforeLongBreak = alertBeforeLongbreak.IsChecked.Value;
App.Configuration.ShortBreakAllowCloseWithRightCLick = shortBreakAllowCloseWithRightCLick.IsChecked.Value;
App.Configuration.SystemIdleDetectionEnabled = sytemIdleCheckbox.IsChecked.Value;
App.Configuration.EnableResetTimerAfterIdleDuration = resetTimersAfterIdleDurationCheckbox.IsChecked.Value;
App.Configuration.ResetTimersAfterIdleDuration = new TimeSpan(rdH, rdM, rdS);
App.Configuration.ApplicationLocale = (LanguagesCombo.SelectedItem as LanguageHolder)?.Name ?? FsLanguageLoader.DefaultLocale;
App.Configuration.UseLanguageProvedidShortMessages = UseLanguageAsSourceCheckbox.IsChecked.Value;

Expand Down Expand Up @@ -364,5 +376,15 @@ private void forceUserCheckbox_Unchecked(object sender, RoutedEventArgs e)
{
shortBreakAllowCloseWithRightCLick.IsEnabled = true;
}

private void resetTimersAfterIdleDurationCheckbox_Checked(object sender, RoutedEventArgs e)
{
resetTimersAfterIdleGapInputStack.IsEnabled = true;
}

private void resetTimersAfterIdleDurationCheckbox_Unchecked(object sender, RoutedEventArgs e)
{
resetTimersAfterIdleGapInputStack.IsEnabled = false;
}
}
}