long/short breaks

This commit is contained in:
2020-04-24 16:51:52 +03:00
parent 214538cda7
commit a5fafb4e6e
6 changed files with 233 additions and 46 deletions

View File

@@ -13,10 +13,7 @@
<Page.Resources> <Page.Resources>
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" /> <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<converters:FormatStringConverter x:Key="FormatStringConverter" /> <converters:FormatStringConverter x:Key="FormatStringConverter" />
<converters:BoolToObjectConverter <local:PeriodToStringConverter x:Key="PeriodToStringConverter" />
x:Key="BoolToWorkRestConverter"
FalseValue="Work"
TrueValue="Rest" />
</Page.Resources> </Page.Resources>
<Grid> <Grid>
@@ -65,13 +62,14 @@
VerticalAlignment="Top" VerticalAlignment="Top"
FontSize="30" FontSize="30"
FontWeight="Light" FontWeight="Light"
Text="{x:Bind runningState.OnRest, Converter={StaticResource BoolToWorkRestConverter}, Mode=OneWay}" /> Text="{x:Bind runningState.CurrentPeriod, Converter={StaticResource PeriodToStringConverter}, Mode=OneWay}" />
</Grid> </Grid>
<Grid Grid.Row="0" Grid.Column="1"> <Grid Grid.Row="0" Grid.Column="1">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
@@ -89,17 +87,29 @@
SpinButtonPlacementMode="Inline" SpinButtonPlacementMode="Inline"
Value="{x:Bind WorkMinutes, Mode=TwoWay}" /> Value="{x:Bind WorkMinutes, Mode=TwoWay}" />
<controls:NumberBox <controls:NumberBox
x:Name="RestMinutesInput" x:Name="BreakMinutesInput"
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Grid.Column="0"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Header="Rest time:" Header="Break time:"
LargeChange="5" LargeChange="5"
Minimum="0" Minimum="0"
SmallChange="1" SmallChange="1"
SpinButtonPlacementMode="Inline" SpinButtonPlacementMode="Inline"
Value="{x:Bind RestMinutes, Mode=TwoWay}" /> Value="{x:Bind BreakMinutes, Mode=TwoWay}" />
<controls:NumberBox
x:Name="LongBreakMinutesInput"
Grid.Row="2"
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Header="Long break time:"
LargeChange="15"
Minimum="0"
SmallChange="5"
SpinButtonPlacementMode="Inline"
Value="{x:Bind LongBreakMinutes, Mode=TwoWay}" />
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>

View File

@@ -15,6 +15,8 @@ using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
using Windows.Storage; using Windows.Storage;
using Windows.System.Threading;
using Windows.UI.Core;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
@@ -26,11 +28,16 @@ namespace PomoTime
/// </summary> /// </summary>
public sealed partial class MainPage : Page public sealed partial class MainPage : Page
{ {
private DispatcherTimer dispatcherTimer;
public RunningState runningState = new RunningState(); public RunningState runningState = new RunningState();
private const int DefaultBreakMinutes = 5;
private const int DefaultWorkMinutes = 25;
private const int DefaultLongBreakMinutes = 15;
private int RestMinutes { get; set; }
private int BreakMinutes { get; set; }
private int WorkMinutes { get; set; } private int WorkMinutes { get; set; }
private int LongBreakMinutes { get; set; }
public MainPage() public MainPage()
{ {
@@ -50,44 +57,84 @@ namespace PomoTime
Windows.Storage.ApplicationDataCompositeValue minutes = (ApplicationDataCompositeValue)roamingSettings.Values["Minutes"]; Windows.Storage.ApplicationDataCompositeValue minutes = (ApplicationDataCompositeValue)roamingSettings.Values["Minutes"];
if (minutes != null) if (minutes != null)
{ {
WorkMinutes = (int)minutes["WorkMinutes"]; if (minutes["WorkMinutes"] != null)
RestMinutes = (int)minutes["RestMinutes"]; {
WorkMinutes = (int)minutes["WorkMinutes"];
}
else
{
WorkMinutes = DefaultWorkMinutes;
}
if (minutes["BreakMinutes"] != null)
{
BreakMinutes = (int)minutes["BreakMinutes"];
}
else
{
BreakMinutes = DefaultBreakMinutes;
}
if (minutes["LongBreakMinutes"] != null)
{
LongBreakMinutes = (int)minutes["LongBreakMinutes"];
}
else
{
LongBreakMinutes = DefaultLongBreakMinutes;
}
} }
else else
{ {
// Some maigc defualt numbers // Some maigc defualt numbers
WorkMinutes = 40; WorkMinutes = DefaultWorkMinutes;
RestMinutes = 5; BreakMinutes = DefaultBreakMinutes;
LongBreakMinutes = DefaultLongBreakMinutes;
} }
runningState.MinutesLeft = WorkMinutes; runningState.MinutesLeft = WorkMinutes;
runningState.SecondsLeft = 0; runningState.SecondsLeft = 0;
} }
public void DispatcherTimerSetup()
{
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
}
void dispatcherTimer_Tick(object sender, object e) void timer_Tick()
{ {
if (!runningState.IsRunning)
{
return;
}
if (runningState.SecondsLeft == 0) if (runningState.SecondsLeft == 0)
{ {
runningState.SecondsLeft = 59; runningState.SecondsLeft = 59;
if (runningState.MinutesLeft == 0) if (runningState.MinutesLeft == 0)
{ {
if (runningState.OnRest) switch (runningState.CurrentPeriod)
{ {
runningState.OnRest = false; case Period.Work:
runningState.MinutesLeft = WorkMinutes; if (runningState.PreviousShortBreaks != 4)
runningState.SecondsLeft = 0; {
} runningState.CurrentPeriod = Period.ShortBreak;
else runningState.MinutesLeft = BreakMinutes;
{ }
runningState.OnRest = true; else
runningState.MinutesLeft = RestMinutes; {
runningState.SecondsLeft = 0; runningState.CurrentPeriod = Period.LongBreak;
runningState.MinutesLeft = LongBreakMinutes;
}
runningState.SecondsLeft = 0;
break;
case Period.ShortBreak:
runningState.CurrentPeriod = Period.Work;
runningState.PreviousShortBreaks += 1;
runningState.MinutesLeft = WorkMinutes;
runningState.SecondsLeft = 0;
break;
case Period.LongBreak:
runningState.CurrentPeriod = Period.Work;
runningState.PreviousShortBreaks = 0;
runningState.MinutesLeft = WorkMinutes;
runningState.SecondsLeft = 0;
break;
default:
throw new ArgumentOutOfRangeException();
} }
} }
else else
@@ -105,24 +152,21 @@ namespace PomoTime
private void PlayButton_Click(object sender, RoutedEventArgs e) private void PlayButton_Click(object sender, RoutedEventArgs e)
{ {
AppBarButton b = sender as AppBarButton; AppBarButton b = sender as AppBarButton;
dispatcherTimer.Start();
runningState.IsRunning = true; runningState.IsRunning = true;
} }
private void PauseButton_Click(object sender, RoutedEventArgs e) private void PauseButton_Click(object sender, RoutedEventArgs e)
{ {
AppBarButton b = sender as AppBarButton; AppBarButton b = sender as AppBarButton;
dispatcherTimer.Stop();
runningState.IsRunning = false; runningState.IsRunning = false;
} }
private void ResetButton_Click(object sender, RoutedEventArgs e) private void ResetButton_Click(object sender, RoutedEventArgs e)
{ {
AppBarButton b = sender as AppBarButton; AppBarButton b = sender as AppBarButton;
dispatcherTimer.Stop();
runningState.IsRunning = false; runningState.IsRunning = false;
runningState.OnRest = false; runningState.CurrentPeriod = Period.Work;
runningState.MinutesLeft = WorkMinutes; runningState.MinutesLeft = WorkMinutes;
runningState.SecondsLeft = 0; runningState.SecondsLeft = 0;
} }
@@ -150,14 +194,22 @@ namespace PomoTime
ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings; ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
Windows.Storage.ApplicationDataCompositeValue minutes = new Windows.Storage.ApplicationDataCompositeValue(); Windows.Storage.ApplicationDataCompositeValue minutes = new Windows.Storage.ApplicationDataCompositeValue();
minutes["WorkMinutes"] = WorkMinutes; minutes["WorkMinutes"] = WorkMinutes;
minutes["RestMinutes"] = RestMinutes; minutes["BreakMinutes"] = BreakMinutes;
minutes["LongBreakMinutes"] = LongBreakMinutes;
roamingSettings.Values["Minutes"] = minutes; roamingSettings.Values["Minutes"] = minutes;
deferral.Complete(); deferral.Complete();
} }
private void MainPageLoaded(object sender, RoutedEventArgs e) private void MainPageLoaded(object sender, RoutedEventArgs e)
{ {
DispatcherTimerSetup(); ThreadPoolTimer timer = ThreadPoolTimer.CreatePeriodicTimer(async (t) =>
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
timer_Tick();
});
}, TimeSpan.FromSeconds(1));
} }
} }
} }

View File

@@ -35,10 +35,11 @@
DisplayName="PomoTime" DisplayName="PomoTime"
Square150x150Logo="Assets\Square150x150Logo.png" Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png" Square44x44Logo="Assets\Square44x44Logo.png"
Description="PomoTime" Description="A qute little pomodoro technique timer, which does exactly what you think it does - counts (by default) 40 minutes of work time and then 5 minutes of rest time. And repeats until you stop it."
BackgroundColor="transparent"> BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/> <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square71x71Logo="Assets\SmallTile.png" Square310x310Logo="Assets\LargeTile.png"/>
<uap:SplashScreen Image="Assets\SplashScreen.png" /> <uap:SplashScreen Image="Assets\SplashScreen.png" />
<uap:LockScreen BadgeLogo="Assets\BadgeLogo.png" Notification="badge"/>
</uap:VisualElements> </uap:VisualElements>
</Application> </Application>
</Applications> </Applications>

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace PomoTime
{
public class PeriodToStringConverter : IValueConverter
{
#region IValueConverter Members
// Define the Convert method to change a DateTime object to
// a month string.
public object Convert(object value, Type targetType,
object parameter, string language)
{
// The value parameter is the data from the source object.
Period period = (Period)value;
string output;
switch (period)
{
case Period.LongBreak:
output = "Long break";
break;
case Period.ShortBreak:
output = "Short break";
break;
case Period.Work:
output = "Work";
break;
default:
output = "Something wrong";
break;
}
// Return the month value to pass to the target.
return output;
}
// ConvertBack is not implemented for a OneWay binding.
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
throw new NotImplementedException();
}
#endregion
}
}

View File

@@ -122,6 +122,7 @@
<Compile Include="MainPage.xaml.cs"> <Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon> <DependentUpon>MainPage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="PeriodToStringConverter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RunningState.cs" /> <Compile Include="RunningState.cs" />
</ItemGroup> </ItemGroup>
@@ -131,13 +132,62 @@
</AppxManifest> </AppxManifest>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Assets\BadgeLogo.scale-100.png" />
<Content Include="Assets\BadgeLogo.scale-125.png" />
<Content Include="Assets\BadgeLogo.scale-150.png" />
<Content Include="Assets\BadgeLogo.scale-200.png" />
<Content Include="Assets\BadgeLogo.scale-400.png" />
<Content Include="Assets\LargeTile.scale-100.png" />
<Content Include="Assets\LargeTile.scale-125.png" />
<Content Include="Assets\LargeTile.scale-150.png" />
<Content Include="Assets\LargeTile.scale-200.png" />
<Content Include="Assets\LargeTile.scale-400.png" />
<Content Include="Assets\SmallTile.scale-100.png" />
<Content Include="Assets\SmallTile.scale-125.png" />
<Content Include="Assets\SmallTile.scale-150.png" />
<Content Include="Assets\SmallTile.scale-200.png" />
<Content Include="Assets\SmallTile.scale-400.png" />
<Content Include="Assets\SplashScreen.scale-100.png" />
<Content Include="Assets\SplashScreen.scale-125.png" />
<Content Include="Assets\SplashScreen.scale-150.png" />
<Content Include="Assets\SplashScreen.scale-400.png" />
<Content Include="Assets\Square150x150Logo.scale-100.png" />
<Content Include="Assets\Square150x150Logo.scale-125.png" />
<Content Include="Assets\Square150x150Logo.scale-150.png" />
<Content Include="Assets\Square150x150Logo.scale-400.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-16.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-24.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-256.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-32.png" />
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-48.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-16.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-256.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-32.png" />
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-48.png" />
<Content Include="Assets\Square44x44Logo.scale-100.png" />
<Content Include="Assets\Square44x44Logo.scale-125.png" />
<Content Include="Assets\Square44x44Logo.scale-150.png" />
<Content Include="Assets\Square44x44Logo.scale-400.png" />
<Content Include="Assets\Square44x44Logo.targetsize-16.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24.png" />
<Content Include="Assets\Square44x44Logo.targetsize-256.png" />
<Content Include="Assets\Square44x44Logo.targetsize-32.png" />
<Content Include="Assets\Square44x44Logo.targetsize-48.png" />
<Content Include="Assets\StoreLogo.scale-100.png" />
<Content Include="Assets\StoreLogo.scale-125.png" />
<Content Include="Assets\StoreLogo.scale-150.png" />
<Content Include="Assets\StoreLogo.scale-200.png" />
<Content Include="Assets\StoreLogo.scale-400.png" />
<Content Include="Assets\Wide310x150Logo.scale-100.png" />
<Content Include="Assets\Wide310x150Logo.scale-125.png" />
<Content Include="Assets\Wide310x150Logo.scale-150.png" />
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
<Content Include="Properties\Default.rd.xml" /> <Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png" /> <Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\SplashScreen.scale-200.png" /> <Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" /> <Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" /> <Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" /> <Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\StoreLogo.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" /> <Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -152,7 +202,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.2.9</Version> <Version>6.2.10</Version>
</PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
<Version>6.0.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Toolkit.Uwp.UI"> <PackageReference Include="Microsoft.Toolkit.Uwp.UI">
<Version>6.0.0</Version> <Version>6.0.0</Version>

View File

@@ -8,6 +8,10 @@ using System.Threading.Tasks;
namespace PomoTime namespace PomoTime
{ {
public enum Period
{
Work, ShortBreak, LongBreak
}
public class RunningState : INotifyPropertyChanged public class RunningState : INotifyPropertyChanged
{ {
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
@@ -52,17 +56,31 @@ namespace PomoTime
} }
public bool _on_rest; public Period _period;
public bool OnRest public Period CurrentPeriod
{ {
get { return _on_rest; } get { return _period; }
set set
{ {
_on_rest = value; _period = value;
NotifyPropertyChanged("OnRest"); NotifyPropertyChanged("CurrentPeriod");
} }
} }
public int _previous_short_breaks;
public int PreviousShortBreaks
{
get { return _previous_short_breaks; }
set
{
_previous_short_breaks = value;
NotifyPropertyChanged("PreviousShortBreaks");
}
}
} }
} }