├── TomatoTimerWPF
├── Resource
│ ├── work_icon.png
│ ├── Roboto-Black.ttf
│ ├── Roboto-Regular.ttf
│ ├── work_bag-512.png
│ ├── work_icon_alpha.png
│ ├── work_bag-32_alpha.png
│ ├── work_bag-512_alpha.png
│ ├── Android_JellyBean
│ │ ├── 9-av-move.png
│ │ ├── 9-av-pause.ico
│ │ ├── 9-av-pause.png
│ │ ├── 9-av-play.ico
│ │ ├── 9-av-play.png
│ │ ├── 9-av-replay.ico
│ │ ├── 9-av-replay.png
│ │ ├── 9-av-stop.png
│ │ ├── 2-action-help.png
│ │ ├── 5-content-edit.png
│ │ ├── 9-av-full-screen.png
│ │ ├── 2-action-settings.png
│ │ ├── 1-navigation-cancel.png
│ │ ├── 10-device-access-time.png
│ │ ├── 12-hardware-gamepad.ico
│ │ ├── 12-hardware-gamepad.png
│ │ ├── 10-device-access-alarms.png
│ │ ├── 10-device-access-volume-on.png
│ │ ├── 4-collections-collection.png
│ │ ├── 4-collections-go-to-today.png
│ │ ├── 4-collections-view-as-list.ico
│ │ ├── 4-collections-view-as-list.png
│ │ ├── 10-device-access-alarms_big.png
│ │ ├── 9-av-make-available-offline.png
│ │ ├── 10-device-access-alarms_big_wbg.ico
│ │ ├── 10-device-access-alarms_big_wbg.pdn
│ │ ├── 10-device-access-alarms_big_wbg.png
│ │ ├── 10-device-access-alarms_shift.png
│ │ ├── 10-device-access-volume-muted.png
│ │ ├── 10-device-access-alarms_big_wbg__.ico
│ │ ├── 10-device-access-volume-on_white.png
│ │ ├── 10-device-access-alarms_big_wbg_wbloom.ico
│ │ ├── 10-device-access-alarms_big_wbg_wbloom.pdn
│ │ └── 10-device-access-alarms_big_wbg_wbloom.png
│ └── TomatoTimerWPF_HowToGetCalenderID.gif
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── app.manifest
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── App.xaml
├── merged64.bat
├── RectConverter.cs
├── Extensions.cs
├── App.xaml.cs
├── TimerSettings.settings
├── App.config
├── EmbeddedAssembly.cs
├── GifImage.cs
├── MainWindow.xaml
├── Pages
│ ├── Page_Buttons.xaml
│ ├── UIStyleResource.xaml
│ ├── Page_Buttons.xaml.cs
│ ├── Page_Settings.xaml
│ ├── Page_Settings.xaml.cs
│ ├── Page_SoundSettings.xaml
│ └── Page_SoundSettings.xaml.cs
├── TimerSettings.Designer.cs
├── TomatoTimerWPF.csproj
└── MainWindow.xaml.cs
├── Packages.dgml
├── TomatoTimerWPF.sln
├── README.md
└── .gitignore
/TomatoTimerWPF/Resource/work_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/work_icon.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Roboto-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Roboto-Black.ttf
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/work_bag-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/work_bag-512.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/work_icon_alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/work_icon_alpha.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/work_bag-32_alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/work_bag-32_alpha.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/work_bag-512_alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/work_bag-512_alpha.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-move.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-pause.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-pause.ico
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-pause.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-play.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-play.ico
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-play.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-replay.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-replay.ico
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-replay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-replay.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-stop.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/2-action-help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/2-action-help.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/5-content-edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/5-content-edit.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-full-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-full-screen.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/TomatoTimerWPF_HowToGetCalenderID.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/TomatoTimerWPF_HowToGetCalenderID.gif
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/2-action-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/2-action-settings.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/1-navigation-cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/1-navigation-cancel.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-time.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/12-hardware-gamepad.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/12-hardware-gamepad.ico
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/12-hardware-gamepad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/12-hardware-gamepad.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-volume-on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-volume-on.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/4-collections-collection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/4-collections-collection.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/4-collections-go-to-today.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/4-collections-go-to-today.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/4-collections-view-as-list.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/4-collections-view-as-list.ico
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/4-collections-view-as-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/4-collections-view-as-list.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/9-av-make-available-offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/9-av-make-available-offline.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg.ico
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg.pdn
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_shift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_shift.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-volume-muted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-volume-muted.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg__.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg__.ico
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-volume-on_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-volume-on_white.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg_wbloom.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg_wbloom.ico
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg_wbloom.pdn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg_wbloom.pdn
--------------------------------------------------------------------------------
/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg_wbloom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Harpseal/TomatoTimerWPF/HEAD/TomatoTimerWPF/Resource/Android_JellyBean/10-device-access-alarms_big_wbg_wbloom.png
--------------------------------------------------------------------------------
/TomatoTimerWPF/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/merged64.bat:
--------------------------------------------------------------------------------
1 | "c:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe" /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" /lib:"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies" /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF" /targetplatform:v4,c:\Windows\Microsoft.NET\Framework64\v4.0.30319 /out:./merged/TomatoTimerWPF.exe TomatoTimerWPF.exe Microsoft.WindowsAPICodePack.dll Microsoft.WindowsAPICodePack.Shell.dll
2 |
--------------------------------------------------------------------------------
/Packages.dgml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18408
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace TomatoTimerWPF.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/RectConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Data;
4 | using System.Windows;
5 |
6 | namespace TomatoTimerWPF
7 | {
8 | class RectConverter : IMultiValueConverter
9 | {
10 | public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
11 | {
12 | if (values != null && values[0] != null && values[1] != null && values[2] != null)
13 | {
14 | double progressBarFillPercentage = (double)values[0];
15 | double textBlockActualyWidth = (double)values[1];
16 | double textBlockHeight = (double)values[2];
17 | return new Rect(0, 0, progressBarFillPercentage / 100.0 * textBlockActualyWidth, textBlockHeight); // ProgressBarFillWidth is calculated by multiplying Fill
18 | // percentage with actual width
19 | }
20 | return new Rect(0, 0, 0, 0); // Default Zero size rectangle
21 | }
22 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
23 | {
24 | throw new NotImplementedException();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Extensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.IO;
5 | using System.Windows;
6 | using System.Windows.Media.Imaging;
7 |
8 | namespace TomatoTimerWPF
9 | {
10 | public static class Extensions
11 | {
12 | public static Visibility ToVisibility(this bool visible)
13 | {
14 | return visible ? Visibility.Visible : Visibility.Collapsed;
15 | }
16 |
17 | public static string ToFormat(this string format, params object[] args)
18 | {
19 | return string.Format(format, args);
20 | }
21 |
22 | public static T Chain(this T target, Action action)
23 | {
24 | action(target);
25 | return target;
26 | }
27 |
28 | //public static BitmapFrame GetBitmapFrame(this Icon icon)
29 | //{
30 | // return BitmapFrame.Create(icon.GetStream());
31 | //}
32 |
33 | //public static Stream GetStream(this Icon icon)
34 | //{
35 | // var stream = new MemoryStream();
36 | // icon.Save(stream);
37 | // return stream;
38 | //}
39 |
40 | public static TimeSpan Milliseconds(this int ms)
41 | {
42 | return new TimeSpan(0, 0, 0, 0, ms);
43 | }
44 |
45 | public static TimeSpan Seconds(this int seconds)
46 | {
47 | return new TimeSpan(0, 0, seconds);
48 | }
49 |
50 | public static TimeSpan Minutes(this int minutes)
51 | {
52 | return new TimeSpan(0, minutes, 0);
53 | }
54 |
55 | public static bool IsNegativeOrZero(this TimeSpan span)
56 | {
57 | return span.TotalMilliseconds <= 0;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/TomatoTimerWPF.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Express 2013 for Windows Desktop
4 | VisualStudioVersion = 12.0.21005.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TomatoTimerWPF", "TomatoTimerWPF\TomatoTimerWPF.csproj", "{C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Debug|x86 = Debug|x86
13 | Release|Any CPU = Release|Any CPU
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Debug|x64.ActiveCfg = Debug|x64
21 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Debug|x64.Build.0 = Debug|x64
22 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Debug|x86.ActiveCfg = Debug|x86
23 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Debug|x86.Build.0 = Debug|x86
24 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Release|x64.ActiveCfg = Release|x64
27 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Release|x64.Build.0 = Release|x64
28 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Release|x86.ActiveCfg = Release|x86
29 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}.Release|x86.Build.0 = Release|x86
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TomatoTimerWPF
2 |
3 | Pomodoro timer for windows 7/8(Desktop) showing countdown on taskbar by using OverlayIcon and ProgressBar of the TaskbarManager.
4 |
5 | | Work | Rest | Timeout |
6 | |:----------:|:-----------:|:------------:|
7 | |   |   |  |
8 |
9 |
10 | | Windows 7 | Windows 8 | Windows 10 |
11 | |:---------:|:---------:|:----------:|
12 | |  | | |
13 |
14 |
15 |
16 | ## Todo
17 | ```
18 | ```
19 |
20 | ## Buliding Prerequisites
21 | - [Microsoft Visual Studio](https://www.visualstudio.com/) (Community version is enough)
22 |
23 | ## Dependencies
24 | - [.NET Framework 4.5](https://www.microsoft.com/zh-tw/download/details.aspx?id=30653)
25 |
26 | ## Attribution
27 |
28 | All icons and sounds used in this project are made by android team and downloaded from [deviantart](http://palhaiz.deviantart.com/art/Android-4-1-Jelly-Bean-Icon-Set-311741892). Thanks for their hard work. :)
29 |
30 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("TomatoTimer")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("TomatoTimer")]
15 | [assembly: AssemblyCopyright("Copyright © 2014")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.*")]
55 | [assembly: AssemblyFileVersion("1.0.*")]
56 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Reflection;
9 |
10 | namespace TomatoTimerWPF
11 | {
12 | ///
13 | /// Interaction logic for App.xaml
14 | ///
15 | public partial class App : Application
16 | {
17 | //Custom main method
18 | [STAThread]
19 | public static void Main()
20 | {
21 | //EmbeddedAssembly.Load("TomatoTimerWPF.Microsoft.WindowsAPICodePack.dll", "Microsoft.WindowsAPICodePack.dll");
22 | //EmbeddedAssembly.Load("TomatoTimerWPF.Microsoft.WindowsAPICodePack.Shell.dll", "Microsoft.WindowsAPICodePack.Shell.dll");
23 |
24 | //AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
25 | //{
26 | // String resourceName = "TomatoTimerWPF.Microsoft.WindowsAPICodePack.Shell.dll";
27 | // using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
28 | // {
29 | // Byte[] assemblyData = new Byte[stream.Length];
30 | // stream.Read(assemblyData, 0, assemblyData.Length);
31 | // return System.Reflection.Assembly.Load(assemblyData);
32 | // }
33 | //};
34 |
35 | //AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
36 | //{
37 | // String resourceName = "TomatoTimerWPF.Microsoft.WindowsAPICodePack.dll";
38 | // using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
39 | // {
40 | // Byte[] assemblyData = new Byte[stream.Length];
41 | // stream.Read(assemblyData, 0, assemblyData.Length);
42 | // return System.Reflection.Assembly.Load(assemblyData);
43 | // }
44 | //};
45 |
46 | // Create new instance of application subclass
47 | App app = new App();
48 |
49 | // Code to register events and set properties that were
50 | // defined in XAML in the application definition
51 | app.InitializeComponent();
52 |
53 | // Start running the application
54 | app.Run();
55 |
56 | }
57 | }
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/TimerSettings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 30
7 |
8 |
9 | 35
10 |
11 |
12 | 5
13 |
14 |
15 | 15
16 |
17 |
18 | 15
19 |
20 |
21 | 20
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | True
31 |
32 |
33 | True
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | 0
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | False
58 |
59 |
60 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
54 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 30
19 |
20 |
21 | 35
22 |
23 |
24 | 5
25 |
26 |
27 | 15
28 |
29 |
30 | 15
31 |
32 |
33 | 20
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | True
43 |
44 |
45 | True
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | 0
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | False
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/EmbeddedAssembly.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.IO;
5 | using System.Reflection;
6 | using System.Security.Cryptography;
7 |
8 | ///
9 | /// A class for loading Embedded Assembly
10 | ///
11 | public class EmbeddedAssembly
12 | {
13 | static Dictionary dic = null;
14 |
15 | public static void Load(string embeddedResource, string fileName,bool saveToLocal = false)
16 | {
17 | if (dic == null)
18 | dic = new Dictionary();
19 |
20 | byte[] ba = null;
21 | Assembly asm = null;
22 | Assembly curAsm = Assembly.GetExecutingAssembly();
23 |
24 | using (Stream stm = curAsm.GetManifestResourceStream(embeddedResource))
25 | {
26 | // Either the file is not existed or it is not mark as embedded resource
27 | if (stm == null)
28 | throw new Exception(embeddedResource + " is not found in Embedded Resources.");
29 |
30 | // Get byte[] from the file from embedded resource
31 | ba = new byte[(int)stm.Length];
32 | stm.Read(ba, 0, (int)stm.Length);
33 | try
34 | {
35 | asm = Assembly.Load(ba);
36 |
37 | // Add the assembly/dll into dictionary
38 | dic.Add(asm.FullName, asm);
39 | return;
40 | }
41 | catch
42 | {
43 | // Purposely do nothing
44 | // Unmanaged dll or assembly cannot be loaded directly from byte[]
45 | // Let the process fall through for next part
46 | }
47 | }
48 |
49 | bool fileOk = false;
50 | string tempFile = "";
51 |
52 | using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
53 | {
54 | string fileHash = BitConverter.ToString(sha1.ComputeHash(ba)).Replace("-", string.Empty); ;
55 |
56 | tempFile = Path.GetTempPath() + fileName;
57 |
58 | if (File.Exists(tempFile))
59 | {
60 | byte[] bb = File.ReadAllBytes(tempFile);
61 | string fileHash2 = BitConverter.ToString(sha1.ComputeHash(bb)).Replace("-", string.Empty);
62 |
63 | if (fileHash == fileHash2)
64 | {
65 | fileOk = true;
66 | }
67 | else
68 | {
69 | fileOk = false;
70 | }
71 | }
72 | else
73 | {
74 | fileOk = false;
75 | }
76 | }
77 |
78 | if (!fileOk)
79 | {
80 | System.IO.File.WriteAllBytes(tempFile, ba);
81 | }
82 |
83 | asm = Assembly.LoadFile(tempFile);
84 |
85 | dic.Add(asm.FullName, asm);
86 | }
87 |
88 | public static Assembly Get(string assemblyFullName)
89 | {
90 | if (dic == null || dic.Count == 0)
91 | return null;
92 |
93 | if (dic.ContainsKey(assemblyFullName))
94 | return dic[assemblyFullName];
95 |
96 | return null;
97 | }
98 | }
99 |
100 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | # [Rr]elease/
13 | x64/
14 | build/
15 | bld/
16 | [Bb]in/
17 | [Oo]bj/
18 |
19 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
20 | !packages/*/build/
21 |
22 | # MSTest test Results
23 | [Tt]est[Rr]esult*/
24 | [Bb]uild[Ll]og.*
25 |
26 | #NUNIT
27 | *.VisualState.xml
28 | TestResult.xml
29 |
30 | *_i.c
31 | *_p.c
32 | *_i.h
33 | *.ilk
34 | *.meta
35 | *.obj
36 | *.pch
37 | *.pdb
38 | *.pgc
39 | *.pgd
40 | *.rsp
41 | *.sbr
42 | *.tlb
43 | *.tli
44 | *.tlh
45 | *.tmp
46 | *.tmp_proj
47 | *.log
48 | *.vspscc
49 | *.vssscc
50 | .builds
51 | *.pidb
52 | *.svclog
53 | *.scc
54 |
55 | # Chutzpah Test files
56 | _Chutzpah*
57 |
58 | # Visual C++ cache files
59 | ipch/
60 | *.aps
61 | *.ncb
62 | *.opensdf
63 | *.sdf
64 | *.cachefile
65 |
66 | # Visual Studio profiler
67 | *.psess
68 | *.vsp
69 | *.vspx
70 |
71 | # TFS 2012 Local Workspace
72 | $tf/
73 |
74 | # Guidance Automation Toolkit
75 | *.gpState
76 |
77 | # ReSharper is a .NET coding add-in
78 | _ReSharper*/
79 | *.[Rr]e[Ss]harper
80 | *.DotSettings.user
81 |
82 | # JustCode is a .NET coding addin-in
83 | .JustCode
84 |
85 | # TeamCity is a build add-in
86 | _TeamCity*
87 |
88 | # DotCover is a Code Coverage Tool
89 | *.dotCover
90 |
91 | # NCrunch
92 | *.ncrunch*
93 | _NCrunch_*
94 | .*crunch*.local.xml
95 |
96 | # MightyMoose
97 | *.mm.*
98 | AutoTest.Net/
99 |
100 | # Installshield output folder
101 | [Ee]xpress/
102 |
103 | # DocProject is a documentation generator add-in
104 | DocProject/buildhelp/
105 | DocProject/Help/*.HxT
106 | DocProject/Help/*.HxC
107 | DocProject/Help/*.hhc
108 | DocProject/Help/*.hhk
109 | DocProject/Help/*.hhp
110 | DocProject/Help/Html2
111 | DocProject/Help/html
112 |
113 | # Click-Once directory
114 | publish/
115 |
116 | # Publish Web Output
117 | *.Publish.xml
118 | *.azurePubxml
119 |
120 | # NuGet Packages Directory
121 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
122 | #packages/
123 | ## TODO: If the tool you use requires repositories.config, also uncomment the next line
124 | #!packages/repositories.config
125 |
126 | # Windows Azure Build Output
127 | csx/
128 | *.build.csdef
129 |
130 | # Windows Store app package directory
131 | AppPackages/
132 |
133 | # Others
134 | gif/
135 | sql/
136 | *.Cache
137 | ClientBin/
138 | [Ss]tyle[Cc]op.*
139 | ~$*
140 | *~
141 | *.dbmdl
142 | *.dbproj.schemaview
143 | *.[Pp]ublish.xml
144 | *.pfx
145 | *.publishsettings
146 |
147 | # RIA/Silverlight projects
148 | Generated_Code/
149 |
150 | # Backup & report files from converting an old project file to a newer
151 | # Visual Studio version. Backup files are not needed, because we have git ;-)
152 | _UpgradeReport_Files/
153 | Backup*/
154 | UpgradeLog*.XML
155 | UpgradeLog*.htm
156 |
157 | # SQL Server files
158 | App_Data/*.mdf
159 | App_Data/*.ldf
160 |
161 | # Business Intelligence projects
162 | *.rdl.data
163 | *.bim.layout
164 | *.bim_*.settings
165 |
166 | # Microsoft Fakes
167 | FakesAssemblies/
168 |
169 | # =========================
170 | # Windows detritus
171 | # =========================
172 |
173 | # Windows image file caches
174 | Thumbs.db
175 | ehthumbs.db
176 |
177 | # Folder config file
178 | Desktop.ini
179 |
180 | # Recycle Bin used on file shares
181 | $RECYCLE.BIN/
182 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/GifImage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 | using System.Windows.Media.Animation;
5 | using System.Windows.Media.Imaging;
6 |
7 | namespace TomatoTimerWPF
8 | {
9 | internal class GifImage : Image
10 | {
11 | public static readonly DependencyProperty FrameIndexProperty =
12 | DependencyProperty.Register(
13 | "FrameIndex",
14 | typeof(int),
15 | typeof(GifImage),
16 | new UIPropertyMetadata(0, FrameIndexChanged));
17 |
18 | public static readonly DependencyProperty AutoStartProperty =
19 | DependencyProperty.Register(
20 | "AutoStart",
21 | typeof(bool),
22 | typeof(GifImage),
23 | new UIPropertyMetadata(true, AutoStartChanged));
24 |
25 | public static readonly DependencyProperty GifSourceProperty =
26 | DependencyProperty.Register(
27 | "GifSource",
28 | typeof(string),
29 | typeof(GifImage),
30 | new UIPropertyMetadata(string.Empty, GifSourceChanged));
31 |
32 | public static readonly DependencyProperty DurationPerFrameProperty =
33 | DependencyProperty.Register(
34 | "DurationPerFrameMS",
35 | typeof(int),
36 | typeof(GifImage),
37 | new UIPropertyMetadata(100, null));
38 |
39 | private Int32Animation animation;
40 | private GifBitmapDecoder decoder;
41 | private bool isInitialized;
42 |
43 | static GifImage()
44 | {
45 | VisibilityProperty.OverrideMetadata(
46 | typeof(GifImage),
47 | new FrameworkPropertyMetadata(VisibilityChanged));
48 | }
49 |
50 | public int FrameIndex
51 | {
52 | get { return (int)GetValue(FrameIndexProperty); }
53 | set { SetValue(FrameIndexProperty, value); }
54 | }
55 |
56 | public bool AutoStart
57 | {
58 | get { return (bool)GetValue(AutoStartProperty); }
59 | set { SetValue(AutoStartProperty, value); }
60 | }
61 |
62 | public string GifSource
63 | {
64 | get { return (string)GetValue(GifSourceProperty); }
65 | set { SetValue(GifSourceProperty, value); }
66 | }
67 |
68 | public int DurationPerFrameMS
69 | {
70 | get { return (int)GetValue(DurationPerFrameProperty); }
71 | set { SetValue(DurationPerFrameProperty, value); }
72 | }
73 |
74 | private void Initialize()
75 | {
76 | decoder = new GifBitmapDecoder(
77 | new Uri("pack://application:,,," + GifSource),
78 | BitmapCreateOptions.PreservePixelFormat,
79 | BitmapCacheOption.Default);
80 | int frameCount = decoder.Frames.Count;
81 | animation = new Int32Animation(
82 | 0,
83 | decoder.Frames.Count - 1,
84 | new Duration(new TimeSpan(0, 0, 0, 0, frameCount * 1000)))
85 | {RepeatBehavior = RepeatBehavior.Forever};
86 | Source = decoder.Frames[0];
87 | isInitialized = true;
88 | if (AutoStart && Visibility == Visibility.Visible)
89 | {
90 | StartAnimation();
91 | }
92 | }
93 |
94 | private static void VisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
95 | {
96 | GifImage gifImage = sender as GifImage;
97 | if (gifImage == null)
98 | {
99 | return;
100 | }
101 | if ((Visibility)e.NewValue == Visibility.Visible)
102 | {
103 | gifImage.StartAnimation();
104 | }
105 | else
106 | {
107 | gifImage.StopAnimation();
108 | }
109 | }
110 |
111 | private static void FrameIndexChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
112 | {
113 | var gifImage = sender as GifImage;
114 | if (gifImage != null)
115 | {
116 | gifImage.Source = gifImage.decoder.Frames[(int)e.NewValue];
117 | }
118 | }
119 |
120 | private static void AutoStartChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
121 | {
122 | if ((bool)e.NewValue)
123 | ((GifImage)sender).StartAnimation();
124 | }
125 |
126 | private static void GifSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
127 | {
128 | ((GifImage)sender).Initialize();
129 | }
130 |
131 | public void StartAnimation()
132 | {
133 | if (!isInitialized)
134 | Initialize();
135 | BeginAnimation(FrameIndexProperty, animation);
136 | }
137 |
138 | public void StopAnimation()
139 | {
140 | BeginAnimation(FrameIndexProperty, null);
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18408
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace TomatoTimerWPF.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TomatoTimerWPF.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
65 | ///
66 | internal static System.Drawing.Icon _12_hardware_gamepad {
67 | get {
68 | object obj = ResourceManager.GetObject("_12_hardware_gamepad", resourceCulture);
69 | return ((System.Drawing.Icon)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
75 | ///
76 | internal static System.Drawing.Icon _4_collections_view_as_list {
77 | get {
78 | object obj = ResourceManager.GetObject("_4_collections_view_as_list", resourceCulture);
79 | return ((System.Drawing.Icon)(obj));
80 | }
81 | }
82 |
83 | ///
84 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
85 | ///
86 | internal static System.Drawing.Icon _9_av_pause {
87 | get {
88 | object obj = ResourceManager.GetObject("_9_av_pause", resourceCulture);
89 | return ((System.Drawing.Icon)(obj));
90 | }
91 | }
92 |
93 | ///
94 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
95 | ///
96 | internal static System.Drawing.Icon _9_av_play {
97 | get {
98 | object obj = ResourceManager.GetObject("_9_av_play", resourceCulture);
99 | return ((System.Drawing.Icon)(obj));
100 | }
101 | }
102 |
103 | ///
104 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
105 | ///
106 | internal static System.Drawing.Icon _9_av_replay {
107 | get {
108 | object obj = ResourceManager.GetObject("_9_av_replay", resourceCulture);
109 | return ((System.Drawing.Icon)(obj));
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
16 |
18 |
20 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
44 |
45 |
46 |
47 |
48 |
56 |
57 |
58 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Pages/Page_Buttons.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
42 |
44 |
45 |
46 |
47 |
48 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
62 |
63 |
66 |
69 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Pages/UIStyleResource.xaml:
--------------------------------------------------------------------------------
1 |
4 |
16 |
17 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
119 |
120 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resource\Android_JellyBean\12-hardware-gamepad.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\Resource\Android_JellyBean\4-collections-view-as-list.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | ..\Resource\Android_JellyBean\9-av-pause.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
131 | ..\Resource\Android_JellyBean\9-av-play.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
132 |
133 |
134 | ..\Resource\Android_JellyBean\9-av-replay.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
135 |
136 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/TimerSettings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace TomatoTimerWPF {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.1.0.0")]
16 | internal sealed partial class TimerSettings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static TimerSettings defaultInstance = ((TimerSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new TimerSettings())));
19 |
20 | public static TimerSettings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("30")]
29 | public int Work_Time {
30 | get {
31 | return ((int)(this["Work_Time"]));
32 | }
33 | set {
34 | this["Work_Time"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("35")]
41 | public int WorkTime_Uesr {
42 | get {
43 | return ((int)(this["WorkTime_Uesr"]));
44 | }
45 | set {
46 | this["WorkTime_Uesr"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("5")]
53 | public int Relax_Time {
54 | get {
55 | return ((int)(this["Relax_Time"]));
56 | }
57 | set {
58 | this["Relax_Time"] = value;
59 | }
60 | }
61 |
62 | [global::System.Configuration.UserScopedSettingAttribute()]
63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
64 | [global::System.Configuration.DefaultSettingValueAttribute("15")]
65 | public int RelaxTime_Uesr {
66 | get {
67 | return ((int)(this["RelaxTime_Uesr"]));
68 | }
69 | set {
70 | this["RelaxTime_Uesr"] = value;
71 | }
72 | }
73 |
74 | [global::System.Configuration.UserScopedSettingAttribute()]
75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
76 | [global::System.Configuration.DefaultSettingValueAttribute("15")]
77 | public int Relax_Time_Long {
78 | get {
79 | return ((int)(this["Relax_Time_Long"]));
80 | }
81 | set {
82 | this["Relax_Time_Long"] = value;
83 | }
84 | }
85 |
86 | [global::System.Configuration.UserScopedSettingAttribute()]
87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
88 | [global::System.Configuration.DefaultSettingValueAttribute("20")]
89 | public int Relax_Time_Long_User {
90 | get {
91 | return ((int)(this["Relax_Time_Long_User"]));
92 | }
93 | set {
94 | this["Relax_Time_Long_User"] = value;
95 | }
96 | }
97 |
98 | [global::System.Configuration.UserScopedSettingAttribute()]
99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
100 | [global::System.Configuration.DefaultSettingValueAttribute("")]
101 | public string GoogleCal_src {
102 | get {
103 | return ((string)(this["GoogleCal_src"]));
104 | }
105 | set {
106 | this["GoogleCal_src"] = value;
107 | }
108 | }
109 |
110 | [global::System.Configuration.UserScopedSettingAttribute()]
111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
112 | [global::System.Configuration.DefaultSettingValueAttribute("")]
113 | public string GoogleCal_text {
114 | get {
115 | return ((string)(this["GoogleCal_text"]));
116 | }
117 | set {
118 | this["GoogleCal_text"] = value;
119 | }
120 | }
121 |
122 | [global::System.Configuration.UserScopedSettingAttribute()]
123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
124 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
125 | public bool GoogleCal_EnableEvent {
126 | get {
127 | return ((bool)(this["GoogleCal_EnableEvent"]));
128 | }
129 | set {
130 | this["GoogleCal_EnableEvent"] = value;
131 | }
132 | }
133 |
134 | [global::System.Configuration.UserScopedSettingAttribute()]
135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
136 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
137 | public bool AlwaysOnTop {
138 | get {
139 | return ((bool)(this["AlwaysOnTop"]));
140 | }
141 | set {
142 | this["AlwaysOnTop"] = value;
143 | }
144 | }
145 |
146 | [global::System.Configuration.UserScopedSettingAttribute()]
147 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
148 | [global::System.Configuration.DefaultSettingValueAttribute("")]
149 | public string WindowRestoreBounds {
150 | get {
151 | return ((string)(this["WindowRestoreBounds"]));
152 | }
153 | set {
154 | this["WindowRestoreBounds"] = value;
155 | }
156 | }
157 |
158 | [global::System.Configuration.UserScopedSettingAttribute()]
159 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
160 | [global::System.Configuration.DefaultSettingValueAttribute("")]
161 | public string TimerRestoreDateTime {
162 | get {
163 | return ((string)(this["TimerRestoreDateTime"]));
164 | }
165 | set {
166 | this["TimerRestoreDateTime"] = value;
167 | }
168 | }
169 |
170 | [global::System.Configuration.UserScopedSettingAttribute()]
171 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
172 | [global::System.Configuration.DefaultSettingValueAttribute("0")]
173 | public int TimerRestoreMode {
174 | get {
175 | return ((int)(this["TimerRestoreMode"]));
176 | }
177 | set {
178 | this["TimerRestoreMode"] = value;
179 | }
180 | }
181 |
182 | [global::System.Configuration.UserScopedSettingAttribute()]
183 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
184 | [global::System.Configuration.DefaultSettingValueAttribute("")]
185 | public string SoundPathTimeOutRest {
186 | get {
187 | return ((string)(this["SoundPathTimeOutRest"]));
188 | }
189 | set {
190 | this["SoundPathTimeOutRest"] = value;
191 | }
192 | }
193 |
194 | [global::System.Configuration.UserScopedSettingAttribute()]
195 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
196 | [global::System.Configuration.DefaultSettingValueAttribute("")]
197 | public string SoundPathTimeOutWork {
198 | get {
199 | return ((string)(this["SoundPathTimeOutWork"]));
200 | }
201 | set {
202 | this["SoundPathTimeOutWork"] = value;
203 | }
204 | }
205 |
206 | [global::System.Configuration.UserScopedSettingAttribute()]
207 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
208 | [global::System.Configuration.DefaultSettingValueAttribute("")]
209 | public string SoundPathPause {
210 | get {
211 | return ((string)(this["SoundPathPause"]));
212 | }
213 | set {
214 | this["SoundPathPause"] = value;
215 | }
216 | }
217 |
218 | [global::System.Configuration.UserScopedSettingAttribute()]
219 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
220 | [global::System.Configuration.DefaultSettingValueAttribute("")]
221 | public string SoundPathResume {
222 | get {
223 | return ((string)(this["SoundPathResume"]));
224 | }
225 | set {
226 | this["SoundPathResume"] = value;
227 | }
228 | }
229 |
230 | [global::System.Configuration.UserScopedSettingAttribute()]
231 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
232 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
233 | public bool GoogleCal_CopyToClipboard {
234 | get {
235 | return ((bool)(this["GoogleCal_CopyToClipboard"]));
236 | }
237 | set {
238 | this["GoogleCal_CopyToClipboard"] = value;
239 | }
240 | }
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Pages/Page_Buttons.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | using System.Windows.Media.Animation;
17 | using System.Windows.Interop;
18 | using System.Runtime.InteropServices;
19 |
20 | namespace TomatoTimerWPF
21 | {
22 | ///
23 | /// Interaction logic for Page_Buttons.xaml
24 | ///
25 | public partial class Page_Buttons : UserControl
26 | {
27 |
28 | [StructLayout(LayoutKind.Sequential)]
29 | public struct RECT
30 | {
31 | public int Left;
32 | public int Top;
33 | public int Right;
34 | public int Bottom;
35 | }
36 |
37 | [DllImport("user32.dll")]
38 | [return: MarshalAs(UnmanagedType.Bool)]
39 | public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
40 |
41 | // Make sure RECT is actually OUR defined struct, not the windows rect.
42 | public static RECT GetWindowRectangle(Window window)
43 | {
44 | RECT rect;
45 | GetWindowRect((new WindowInteropHelper(window)).Handle, out rect);
46 |
47 | return rect;
48 | }
49 |
50 | private System.Windows.Point m_MousePosition;
51 | public DateTime m_MouseDownTime;
52 | public bool m_bIsMouseDown = false;
53 |
54 | private MainWindow m_window;
55 | public void SetMainWindow(MainWindow window)
56 | {
57 | m_window = window;
58 | }
59 |
60 | Storyboard m_sbAniOut;
61 | Storyboard m_sbAniIn;
62 |
63 | public Page_Buttons(MainWindow window)
64 | {
65 | InitializeComponent();
66 |
67 | m_window = window;
68 |
69 | m_MousePosition.X = m_MousePosition.Y = 0;
70 |
71 | spButtonStackPanel.Opacity = 0;
72 | btnGotoSetting.Opacity = 0;
73 |
74 | labelTime_small.Opacity = 0;
75 | grLabelGrid.Opacity = 1;
76 |
77 |
78 | m_sbAniOut = new Storyboard();
79 | DoubleAnimation daFadeOut = new DoubleAnimation();
80 | daFadeOut.Duration = 200.Milliseconds();
81 | daFadeOut.To = 0.0;
82 |
83 | m_sbAniOut.Children.Add(daFadeOut);
84 | Storyboard.SetTargetProperty(daFadeOut, new PropertyPath(UIElement.OpacityProperty));
85 |
86 | m_sbAniIn = new Storyboard();
87 | DoubleAnimation daFadeIn = new DoubleAnimation();
88 | daFadeIn.Duration = 200.Milliseconds();
89 | daFadeIn.From = 0.0;
90 | daFadeIn.To = 1.0;
91 |
92 | m_sbAniIn.Children.Add(daFadeIn);
93 | Storyboard.SetTargetProperty(daFadeIn, new PropertyPath(UIElement.OpacityProperty));
94 |
95 |
96 | Version win8version = new Version(6, 2, 9200, 0);
97 |
98 | if (Environment.OSVersion.Platform == PlatformID.Win32NT &&
99 | Environment.OSVersion.Version >= win8version)
100 | {
101 | labelTimeWhite.Visibility = Visibility.Visible;
102 | }
103 | else
104 | labelTimeWhite.Visibility = Visibility.Hidden;
105 |
106 | //labelTimeWhite.Visibility = Visibility.Visible;
107 |
108 |
109 | m_MouseDownTime = DateTime.Now;
110 | }
111 |
112 | #region ISwitchable Members
113 | //public void UtilizeState(object state)
114 | //{
115 | // throw new NotImplementedException();
116 | //}
117 |
118 | private void Button_GotoSettings_Click(object sender, System.Windows.RoutedEventArgs e)
119 | {
120 | //Switcher.Switch(new Page_Settings());
121 | m_window.SwitchToSettings();
122 | //m_window.SwitchToSoundSettings();
123 | }
124 | #endregion
125 |
126 | private void Button_Close_Click(object sender, System.Windows.RoutedEventArgs e)
127 | {
128 | m_window.SavePropertiesAndClose(true);
129 | }
130 |
131 | private void OnButtonMove_MouseDown_1(object sender, MouseButtonEventArgs e)
132 | {
133 | Control uiCur = (sender as Control);
134 | if (uiCur == null) return;
135 | m_MousePosition = e.GetPosition(uiCur);
136 | m_MouseDownTime = DateTime.Now;
137 | m_bIsMouseDown = true;
138 |
139 | if (m_window.WindowState == WindowState.Maximized)
140 | {
141 | double borderWidth;
142 | double borderHeight;
143 |
144 | //The real border size is 7 in my windows 7, but ResizeFrameVerticalBorderWidth is 4 ???
145 | //borderWidth = SystemParameters.ResizeFrameVerticalBorderWidth;
146 | //borderHeight = SystemParameters.ResizeFrameHorizontalBorderHeight;
147 |
148 | //use window api to get the real border size.
149 | var rectWindow = GetWindowRectangle(m_window);
150 | Point ptClient = m_window.PointToScreen(new Point(0, 0));
151 | borderWidth = ptClient.X - rectWindow.Left;
152 | borderHeight = ptClient.Y - rectWindow.Top;
153 |
154 | m_window.WindowState = WindowState.Normal;
155 |
156 | System.Drawing.Point pointMouse = System.Windows.Forms.Control.MousePosition;
157 | Point relativePoint = uiCur.TransformToAncestor(m_window)
158 | .Transform(m_MousePosition);
159 | m_window.Left = (double)pointMouse.X - relativePoint.X - borderWidth;
160 | m_window.Top = (double)pointMouse.Y - relativePoint.Y - borderHeight;
161 | }
162 | }
163 |
164 | private void OnButtonMove_MouseMove_1(object sender, MouseEventArgs e)
165 | {
166 |
167 | //MessageBox.Show("MM");
168 | //SystemParameters.MinimumHorizontalDragDistance
169 | Control uiCur = (sender as Control);
170 | if (uiCur == null) return;
171 | double minDragDis = Math.Min(Math.Min(uiCur.ActualWidth, uiCur.ActualHeight) * 0.25,15);
172 | var currentPoint = e.GetPosition(uiCur);
173 |
174 | if (e.LeftButton == MouseButtonState.Pressed
175 | &&
176 | //uiCur.IsMouseCaptured &&
177 | (Math.Abs(currentPoint.X - m_MousePosition.X) > minDragDis ||
178 | Math.Abs(currentPoint.Y - m_MousePosition.Y) > minDragDis))
179 | {
180 | // Prevent Click from firing
181 | uiCur.ReleaseMouseCapture();
182 | //if (m_window.ResizeMode != System.Windows.ResizeMode.NoResize)
183 | //{
184 | // m_window.ResizeMode = System.Windows.ResizeMode.NoResize;
185 | // m_window.UpdateLayout();
186 | //}
187 | m_bIsMouseDown = false;
188 |
189 | try
190 | {
191 | m_window.DragMove();
192 | }
193 | catch (System.InvalidOperationException)
194 | {
195 |
196 | }
197 | //Rect bounds = m_window.RestoreBounds;
198 | //Rect bounds = MainWindow.CheckBounds(m_window.RestoreBounds);
199 | //m_window.Top = bounds.Top;
200 | //m_window.Left = bounds.Left;
201 | //m_window.Width = bounds.Width;
202 | //m_window.Height = bounds.Height;
203 |
204 |
205 | }
206 |
207 |
208 |
209 | }
210 |
211 | private void Grid_MouseEnter_1(object sender, MouseEventArgs e)
212 | {
213 | //btnGotoSetting.Opacity = 1;
214 | //spWindowControlStackPanel.Opacity = 1;
215 | //spButtonStackPanel.Opacity = 1;
216 | //labelTime_small.Opacity = 1;
217 | //grLabelGrid.Opacity = 0;
218 | m_sbAniIn.Begin(btnGotoSetting);
219 | //m_sbAniIn.Begin(m_window.btnAlwaysOnTop);//m_sbAniIn.Begin(m_window.spWindowControlStackPanel);
220 | m_sbAniIn.Begin(spButtonStackPanel);
221 | m_sbAniIn.Begin(labelTime_small);
222 | m_sbAniOut.Begin(grLabelGrid);
223 | }
224 |
225 | private void Grid_MouseLeave_1(object sender, MouseEventArgs e)
226 | {
227 | m_sbAniOut.Begin(btnGotoSetting);
228 | //m_sbAniOut.Begin(m_window.btnAlwaysOnTop);// m_sbAniOut.Begin(m_window.spWindowControlStackPanel);
229 | m_sbAniOut.Begin(spButtonStackPanel);
230 | m_sbAniOut.Begin(labelTime_small);
231 | m_sbAniIn.Begin(grLabelGrid);
232 |
233 | //btnGotoSetting.Opacity = 0;
234 | //spWindowControlStackPanel.Opacity = 0;
235 | //spButtonStackPanel.Opacity = 0;
236 | //labelTime_small.Opacity = 0;
237 | //grLabelGrid.Opacity = 1;
238 | }
239 |
240 | private void Button_GotoWork_Click(object sender, System.Windows.RoutedEventArgs e)
241 | {
242 | //Switcher.GetBaseWindow().StartWork();
243 | m_window.StartWork();
244 | }
245 |
246 | private void Button_GotoRelax_Click(object sender, System.Windows.RoutedEventArgs e)
247 | {
248 | //Switcher.GetBaseWindow().StartRelax();
249 | m_window.StartRelax();
250 | m_bIsMouseDown = false;
251 | //TimeSpan downTime = DateTime.Now - m_MouseDownTime;
252 | //MessageBox.Show(downTime.ToString());
253 | }
254 |
255 | private void Button_Pause_Click(object sender, System.Windows.RoutedEventArgs e)
256 | {
257 |
258 | m_window.Pause();
259 | }
260 |
261 | private void Button_Resume_Click(object sender, System.Windows.RoutedEventArgs e)
262 | {
263 | m_window.Resume();
264 | }
265 |
266 | private void Button_Reset_Click(object sender, System.Windows.RoutedEventArgs e)
267 | {
268 | m_window.Reset();
269 | }
270 |
271 | private void Button_PreviewMouseDownTime(object sender, MouseButtonEventArgs e)
272 | {
273 | m_MouseDownTime = DateTime.Now;
274 | m_bIsMouseDown = true;
275 | }
276 |
277 | private void Button_MouseLeaveDownTime(object sender, MouseEventArgs e)
278 | {
279 | m_bIsMouseDown = false;
280 | //if (m_window.ResizeMode == System.Windows.ResizeMode.NoResize)
281 | //{
282 | // // restore resize grips
283 | // m_window.ResizeMode = System.Windows.ResizeMode.CanResize;
284 | // m_window.UpdateLayout();
285 | //}
286 | }
287 |
288 |
289 | public double GetLongMouseDownPercentage()
290 | {
291 | if (!m_bIsMouseDown) return 0;
292 | TimeSpan timeDown = DateTime.Now - m_MouseDownTime;
293 | double percentage = timeDown.TotalSeconds / 2.0 * 100;
294 | if (percentage > 100) percentage = 100;
295 | return percentage;
296 | }
297 |
298 | public bool GetIsMouseDown()
299 | {
300 | return m_bIsMouseDown;
301 | }
302 |
303 | public bool GetIsLongMouseDown()
304 | {
305 | return m_bIsMouseDown && !(DateTime.Now - m_MouseDownTime - 2.Seconds()).IsNegativeOrZero();
306 | }
307 |
308 |
309 | }
310 |
311 |
312 | }
313 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Pages/Page_Settings.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
134 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
146 |
147 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Pages/Page_Settings.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | using System.Text.RegularExpressions;
17 |
18 | namespace TomatoTimerWPF
19 | {
20 | ///
21 | /// Interaction logic for Page_Settings.xaml
22 | ///
23 | public partial class Page_Settings : UserControl
24 | {
25 | private bool m_bVersionMode;
26 | private MainWindow m_window;
27 | public void SetMainWindow(MainWindow window)
28 | {
29 | m_window = window;
30 | }
31 |
32 | public Page_Settings(MainWindow window)
33 | {
34 | InitializeComponent();
35 |
36 | m_bVersionMode = true;
37 | labelVersion_small.Content = "Version: " + System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
38 |
39 | m_window = window;
40 | SyncSettingsToUIValue();
41 | cbRelaxTimeComboBox.SelectionChanged += ComboBox_SelectionChanged;
42 | cbWorkTimeComboBox.SelectionChanged += ComboBox_SelectionChanged;
43 | cbLongRelaxTimeComboBox.SelectionChanged += ComboBox_SelectionChanged;
44 | }
45 |
46 | #region ISwitchable Members
47 | public void UtilizeState(object state)
48 | {
49 | throw new NotImplementedException();
50 | }
51 |
52 | private void Button_GotoButtons_Click(object sender, System.Windows.RoutedEventArgs e)
53 | {
54 | SyncUIValueToSettings();
55 | m_window.SwitchToButtons();
56 | //Switcher.Switch(new Page_Buttons());
57 |
58 | }
59 | #endregion
60 |
61 | private void SyncSettingsToUIValue()
62 | {
63 | TextBox tbox;
64 |
65 | tbox = cbWorkTimeComboBox.Items[2] as TextBox;
66 | if (tbox != null)
67 | tbox.Text = "" + TomatoTimerWPF.TimerSettings.Default.WorkTime_Uesr;
68 |
69 | tbox = cbRelaxTimeComboBox.Items[2] as TextBox;
70 | if (tbox != null)
71 | tbox.Text = "" + TomatoTimerWPF.TimerSettings.Default.RelaxTime_Uesr;
72 |
73 | tbox = cbLongRelaxTimeComboBox.Items[2] as TextBox;
74 | if (tbox != null)
75 | tbox.Text = "" + TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long_User;
76 |
77 |
78 | if (TomatoTimerWPF.TimerSettings.Default.Work_Time == 30)
79 | cbWorkTimeComboBox.SelectedIndex = 0;
80 | else if (TomatoTimerWPF.TimerSettings.Default.Work_Time == 25)
81 | cbWorkTimeComboBox.SelectedIndex = 1;
82 | else
83 | {
84 | cbWorkTimeComboBox.SelectedIndex = 2;
85 | tbox = cbWorkTimeComboBox.Items[2] as TextBox;
86 | if (tbox != null)
87 | {
88 | tbox.Text = "" + TomatoTimerWPF.TimerSettings.Default.Work_Time;
89 | }
90 | }
91 |
92 | if (TomatoTimerWPF.TimerSettings.Default.Relax_Time == 10)
93 | cbRelaxTimeComboBox.SelectedIndex = 0;
94 | else if (TomatoTimerWPF.TimerSettings.Default.Relax_Time == 5)
95 | cbRelaxTimeComboBox.SelectedIndex = 1;
96 | else
97 | {
98 | cbRelaxTimeComboBox.SelectedIndex = 2;
99 | tbox = cbRelaxTimeComboBox.Items[2] as TextBox;
100 | if (tbox != null)
101 | {
102 | tbox.Text = "" + TomatoTimerWPF.TimerSettings.Default.Relax_Time;
103 | }
104 | }
105 |
106 | if (TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long == 30)
107 | cbLongRelaxTimeComboBox.SelectedIndex = 0;
108 | else if (TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long == 15)
109 | cbLongRelaxTimeComboBox.SelectedIndex = 1;
110 | else
111 | {
112 | cbLongRelaxTimeComboBox.SelectedIndex = 2;
113 | tbox = cbLongRelaxTimeComboBox.Items[2] as TextBox;
114 | if (tbox != null)
115 | {
116 | tbox.Text = "" + TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long;
117 | }
118 | }
119 |
120 | tbGoogleCal_src.Text = TomatoTimerWPF.TimerSettings.Default.GoogleCal_src;
121 | tbGoogleCal_text.Text = TomatoTimerWPF.TimerSettings.Default.GoogleCal_text;
122 | cbEnableGCal.IsChecked = TomatoTimerWPF.TimerSettings.Default.GoogleCal_EnableEvent;
123 |
124 | if (cbEnableGCal.IsChecked == true)
125 | {
126 | spGoogleEventTitle.IsEnabled = true;
127 | spGoogleID.IsEnabled = true;
128 | menuTestGoogleCal.IsEnabled = true;
129 | }
130 | else
131 | {
132 | spGoogleEventTitle.IsEnabled = false;
133 | spGoogleID.IsEnabled = false;
134 | menuTestGoogleCal.IsEnabled = false;
135 | }
136 | }
137 |
138 | private void SyncUIValueToSettings()
139 | {
140 | TextBox tbox;
141 | if (cbRelaxTimeComboBox.SelectedIndex == 0)
142 | TomatoTimerWPF.TimerSettings.Default.Relax_Time = 10;
143 | else if (cbRelaxTimeComboBox.SelectedIndex == 1)
144 | TomatoTimerWPF.TimerSettings.Default.Relax_Time = 5;
145 | else
146 | {
147 | tbox = cbRelaxTimeComboBox.Items[2] as TextBox;
148 | if (tbox != null)
149 | {
150 | TomatoTimerWPF.TimerSettings.Default.Relax_Time = Int32.Parse(tbox.Text);
151 | }
152 | }
153 |
154 |
155 | if (cbLongRelaxTimeComboBox.SelectedIndex == 0)
156 | TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long = 30;
157 | else if (cbLongRelaxTimeComboBox.SelectedIndex == 1)
158 | TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long = 15;
159 | else
160 | {
161 | tbox = cbLongRelaxTimeComboBox.Items[2] as TextBox;
162 | if (tbox != null)
163 | {
164 | TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long = Int32.Parse(tbox.Text);
165 | }
166 | }
167 |
168 | if (cbWorkTimeComboBox.SelectedIndex == 0)
169 | TomatoTimerWPF.TimerSettings.Default.Work_Time = 30;
170 | else if (cbWorkTimeComboBox.SelectedIndex == 1)
171 | TomatoTimerWPF.TimerSettings.Default.Work_Time = 25;
172 | else
173 | {
174 | tbox = cbWorkTimeComboBox.Items[2] as TextBox;
175 | if (tbox != null)
176 | {
177 | TomatoTimerWPF.TimerSettings.Default.Work_Time = Int32.Parse(tbox.Text);
178 | }
179 | }
180 |
181 |
182 | tbox = cbWorkTimeComboBox.Items[2] as TextBox;
183 | if (tbox != null)
184 | TomatoTimerWPF.TimerSettings.Default.WorkTime_Uesr = Int32.Parse(tbox.Text);
185 |
186 | tbox = cbRelaxTimeComboBox.Items[2] as TextBox;
187 | if (tbox != null)
188 | TomatoTimerWPF.TimerSettings.Default.RelaxTime_Uesr = Int32.Parse(tbox.Text);
189 |
190 | tbox = cbLongRelaxTimeComboBox.Items[2] as TextBox;
191 | if (tbox != null)
192 | TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long_User = Int32.Parse(tbox.Text);
193 |
194 |
195 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_src = tbGoogleCal_src.Text;
196 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_text = tbGoogleCal_text.Text;
197 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_EnableEvent = (cbEnableGCal.IsChecked == true);
198 | }
199 |
200 | private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
201 | {
202 | SyncUIValueToSettings();
203 |
204 | }
205 |
206 | private void Button_Close_Click(object sender, System.Windows.RoutedEventArgs e)
207 | {
208 | //Switcher.Close();
209 | m_window.Close();
210 | }
211 |
212 | private void OnClick_Test_GoogleCalender(object sender, System.Windows.RoutedEventArgs e)
213 | {
214 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_src = tbGoogleCal_src.Text;
215 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_text = tbGoogleCal_text.Text;
216 | m_window.OpenGoogleCalender(DateTime.Now - TimeSpan.FromMinutes(TomatoTimerWPF.TimerSettings.Default.Work_Time), DateTime.Now);
217 | //Switcher.GetBaseWindow().OpenGoogleCalender(DateTime.Now - TimeSpan.FromMinutes(TomatoTimerWPF.TimerSettings.Default.Work_Time), DateTime.Now);
218 | }
219 |
220 | Regex NumEx = new Regex(@"^-?\d*\.?\d*$");
221 |
222 | private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
223 | {
224 | if (sender is TextBox)
225 | {
226 | string text = (sender as TextBox).Text + e.Text;
227 |
228 | e.Handled = !NumEx.IsMatch(text);
229 | }
230 | else
231 | throw new NotImplementedException("TextBox_PreviewTextInput Can only Handle TextBoxes");
232 | }
233 |
234 |
235 |
236 | private void UserControl_Loaded(object sender, RoutedEventArgs e)
237 | {
238 | SyncSettingsToUIValue();
239 | }
240 |
241 | private void myGif_MediaEnded(object sender, RoutedEventArgs e)
242 | {
243 | //myGif.Position = new TimeSpan(0, 0, 1);
244 | //myGif.Play();
245 | }
246 |
247 | private void CheckBox_Checked(object sender, RoutedEventArgs e)
248 | {
249 | if (sender == cbEnableGCal)
250 | {
251 | if (cbEnableGCal.IsChecked == true)
252 | {
253 | spGoogleEventTitle.IsEnabled = true;
254 | spGoogleID.IsEnabled = true;
255 | menuTestGoogleCal.IsEnabled = true;
256 | }
257 | else
258 | {
259 | spGoogleEventTitle.IsEnabled = false;
260 | spGoogleID.IsEnabled = false;
261 | menuTestGoogleCal.IsEnabled = false;
262 | }
263 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_EnableEvent = (cbEnableGCal.IsChecked == true);
264 | }//
265 | else if (sender == cbCopyLinkToClipBoard)
266 | {
267 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_CopyToClipboard = (cbCopyLinkToClipBoard.IsChecked == true);
268 | }
269 | }
270 |
271 | private void MenuItem_SubmenuOpened(object sender, RoutedEventArgs e)
272 | {
273 | gifHowToDemo.FrameIndex = 0;
274 | gifHowToDemo.StopAnimation();
275 | gifHowToDemo.StartAnimation();
276 | }
277 |
278 | private void cbComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
279 | {
280 | SyncUIValueToSettings();
281 | }
282 |
283 | private void menuClose_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
284 | {
285 | //MessageBox.Show("menuClose_MouseLeftButtonUp");
286 | m_window.SavePropertiesAndClose(true);
287 | }
288 |
289 | private void menuCloseDontSave_Click(object sender, RoutedEventArgs e)
290 | {
291 | //MessageBox.Show("menuCloseDontSave_Click");
292 | m_window.SavePropertiesAndClose(false);
293 | }
294 |
295 | private void menuCloseSave_Click(object sender, RoutedEventArgs e)
296 | {
297 | //MessageBox.Show("menuCloseSave_Click");
298 | m_window.SavePropertiesAndClose(true);
299 | }
300 |
301 | private void btnGotoSoundSettings_Click(object sender, RoutedEventArgs e)
302 | {
303 | m_window.SwitchFromSettingToSound();
304 | }
305 |
306 | private void labelVersion_small_MouseDown(object sender, MouseButtonEventArgs e)
307 | {
308 | m_bVersionMode = !m_bVersionMode;
309 | if (m_bVersionMode)
310 | labelVersion_small.Content = "Version: " + System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
311 | else
312 | {
313 | Version ver = System.Reflection.Assembly.GetEntryAssembly().GetName().Version;
314 | var date = new DateTime( 2000, 01, 01 ).AddDays( ver.Build ).AddSeconds( ver.Revision * 2 );
315 | labelVersion_small.Content = "Build date: " + date.ToString();
316 | }
317 |
318 | }
319 |
320 |
321 | private void btnGCal_Click(object sender, RoutedEventArgs e)
322 | {
323 | Button btnSelf = (sender as Button);
324 |
325 | btnSelf.ContextMenu.IsEnabled = true;
326 | btnSelf.ContextMenu.PlacementTarget = btnSelf;
327 | btnSelf.ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
328 | //btnSelf.ContextMenu.VerticalOffset = (btnSelf.ActualHeight);
329 | //btnSelf.ContextMenu.HorizontalOffset = (btnSelf.ContextMenu.ActualWidth / 2);
330 | btnSelf.ContextMenu.IsOpen = true;
331 |
332 | }
333 | }
334 | }
335 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/TomatoTimerWPF.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {C6D3FC89-0EC1-485B-AF8D-57DDFD4CB472}
8 | WinExe
9 | Properties
10 | TomatoTimerWPF
11 | TomatoTimerWPF
12 | v4.5
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 | false
17 | publish\
18 | true
19 | Disk
20 | false
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | true
28 | 1
29 | 1.0.0.%2a
30 | false
31 | true
32 | true
33 |
34 |
35 | AnyCPU
36 | true
37 | full
38 | false
39 | bin\Debug\
40 | DEBUG;TRACE
41 | prompt
42 | 4
43 |
44 |
45 | AnyCPU
46 | pdbonly
47 | true
48 | bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 | false
53 | false
54 |
55 |
56 | Resource\Android_JellyBean\10-device-access-alarms_big_wbg_wbloom.ico
57 |
58 |
59 |
60 | 912366DAAE9B56D48FC2B4767EFDC57385296A24
61 |
62 |
63 | TomatoTimerWPF_TemporaryKey.pfx
64 |
65 |
66 | false
67 |
68 |
69 | LocalIntranet
70 |
71 |
72 |
73 | true
74 |
75 |
76 | false
77 |
78 |
79 | true
80 | bin\x64\Debug\
81 | DEBUG;TRACE
82 | full
83 | x64
84 | prompt
85 | ManagedMinimumRules.ruleset
86 | true
87 |
88 |
89 | bin\x64\Release\
90 | TRACE
91 | true
92 | none
93 | x64
94 | false
95 | prompt
96 | ManagedMinimumRules.ruleset
97 | true
98 |
99 |
100 | true
101 | bin\x86\Debug\
102 | DEBUG;TRACE
103 | full
104 | x86
105 | prompt
106 | ManagedMinimumRules.ruleset
107 | true
108 |
109 |
110 | bin\x86\Release\
111 | TRACE
112 | true
113 | none
114 | x86
115 | false
116 | prompt
117 | ManagedMinimumRules.ruleset
118 | false
119 |
120 |
121 | TomatoTimerWPF.App
122 |
123 |
124 | true
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | 4.0
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | True
147 | True
148 | TimerSettings.settings
149 |
150 |
151 | MSBuild:Compile
152 | Designer
153 |
154 |
155 |
156 |
157 |
158 | Page_SoundSettings.xaml
159 |
160 |
161 | True
162 | True
163 | Resources.resx
164 |
165 |
166 |
167 | MSBuild:Compile
168 | Designer
169 |
170 |
171 | App.xaml
172 | Code
173 |
174 |
175 | MainWindow.xaml
176 | Code
177 |
178 |
179 | Designer
180 | MSBuild:Compile
181 |
182 |
183 | Designer
184 | MSBuild:Compile
185 |
186 |
187 | Designer
188 | MSBuild:Compile
189 |
190 |
191 | Designer
192 | MSBuild:Compile
193 |
194 |
195 |
196 |
197 | Page_Buttons.xaml
198 |
199 |
200 | Page_Settings.xaml
201 |
202 |
203 | Code
204 |
205 |
206 | True
207 | Settings.settings
208 | True
209 |
210 |
211 | ResXFileCodeGenerator
212 | Designer
213 | Resources.Designer.cs
214 |
215 |
216 |
217 | SettingsSingleFileGenerator
218 | Settings.Designer.cs
219 |
220 |
221 |
222 | SettingsSingleFileGenerator
223 | TimerSettings.Designer.cs
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 | False
272 | Microsoft .NET Framework 4.5 %28x86 and x64%29
273 | true
274 |
275 |
276 | False
277 | .NET Framework 3.5 SP1 Client Profile
278 | false
279 |
280 |
281 | False
282 | .NET Framework 3.5 SP1
283 | false
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
312 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Pages/Page_SoundSettings.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
39 |
40 |
41 |
42 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/Pages/Page_SoundSettings.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | //using WMPLib;
17 |
18 | namespace TomatoTimerWPF.Pages
19 | {
20 | using Res = Properties.Resources;
21 | ///
22 | /// Interaction logic for Page_SoundSettings.xaml
23 | ///
24 | public partial class Page_SoundSettings : UserControl
25 | {
26 | private MainWindow m_window;
27 | //private WindowsMediaPlayer m_wmplayer = null;
28 | //private System.Media.SoundPlayer[] m_ResourcePlayer;
29 |
30 | private MediaPlayer m_mediaPlayer = null;
31 |
32 | private Button[] m_aBtnPlay;
33 | private Button[] m_aBtnStop;
34 | private Button[] m_aBtnOpenFile;
35 | private Button[] m_aBtnMute;
36 |
37 | public enum SoundType : int
38 | {
39 | Resume = 0,
40 | Pause = 1,
41 | WorkDone = 2,
42 | RestTimeOut = 3
43 | }
44 |
45 | public enum SoundState : int
46 | {
47 | Resource = 0,
48 | Mute = 1,
49 | File = 2
50 | }
51 |
52 | private SoundState[] m_aSoundState;
53 |
54 |
55 | public Page_SoundSettings(MainWindow window)
56 | {
57 | InitializeComponent();
58 | m_window = window;
59 |
60 | m_aBtnPlay = new Button[4] { btnSoundResumePlay, btnSoundPausePlay, btnSoundWorkPlay, btnSoundRestPlay };
61 | m_aBtnStop = new Button[4] { btnSoundResumeStop, btnSoundPauseStop, btnSoundWorkStop, btnSoundRestStop };
62 | m_aBtnOpenFile = new Button[4] { btnSoundResumeOpenFile, btnSoundPauseOpenFile, btnSoundWorkOpenFile, btnSoundRestOpenFile };
63 | m_aBtnMute = new Button[4] { btnSoundResumeMute, btnSoundPauseMute, btnSoundWorkMute, btnSoundRestMute };
64 |
65 | m_aSoundState = new SoundState[4];
66 | //m_ResourcePlayer = new System.Media.SoundPlayer[4];
67 |
68 | for (int i = 0; i < 4; i++)
69 | {
70 | //m_ResourcePlayer[i] = null;
71 | m_aSoundState[i] = getSoundState(getSoundPathProperties((SoundType)i));
72 | SyncStateToPlayer((SoundType)i, m_aSoundState[i]);
73 | SyncStateToUI((SoundType)i, m_aSoundState[i]);
74 | }
75 | }
76 |
77 | private SoundState getSoundState(string path)
78 | {
79 | if (path.Length == 0)
80 | return SoundState.Mute;
81 | else
82 | {
83 | if (path == SoundState.Mute.ToString())
84 | return SoundState.Mute;
85 | if (path == SoundState.Resource.ToString())
86 | return SoundState.Mute;
87 |
88 | if (System.IO.File.Exists(path))
89 | {
90 | return SoundState.File;
91 | }
92 | else
93 | return SoundState.Mute;
94 | }
95 | }
96 |
97 | private void SyncStateToUI(SoundType type, SoundState state)
98 | {
99 | switch (state)
100 | {
101 | case SoundState.Resource:
102 | case SoundState.File:
103 | m_aBtnPlay[(int)type].Visibility = Visibility.Visible;
104 | m_aBtnStop[(int)type].Visibility = Visibility.Collapsed;
105 | m_aBtnOpenFile[(int)type].Visibility = Visibility.Visible;
106 | m_aBtnMute[(int)type].Visibility = Visibility.Visible;
107 | break;
108 | case SoundState.Mute:
109 | m_aBtnPlay[(int)type].Visibility = Visibility.Collapsed;
110 | m_aBtnStop[(int)type].Visibility = Visibility.Collapsed;
111 | m_aBtnOpenFile[(int)type].Visibility = Visibility.Visible;
112 | m_aBtnMute[(int)type].Visibility = Visibility.Collapsed;
113 | break;
114 | }
115 |
116 | }
117 |
118 | private void SyncStateToPlayer(SoundType type, SoundState state)
119 | {
120 | switch (state)
121 | {
122 | case SoundState.Resource:
123 | //if (m_ResourcePlayer[(int)type]==null)
124 | //{
125 | // switch (type)
126 | // {
127 | // case SoundType.Pause:
128 | // ;//m_ResourcePlayer[(int)type] = new System.Media.SoundPlayer(Res.Bellatrix_Pause);
129 | // break;
130 | // case SoundType.Resume:
131 | // ;//m_ResourcePlayer[(int)type] = new System.Media.SoundPlayer(Res.Pollux_Resume);
132 | // break;
133 | // case SoundType.WorkDone:
134 | // ;//m_ResourcePlayer[(int)type] = new System.Media.SoundPlayer(Res.CanisMajor_WorkDone);
135 | // break;
136 | // case SoundType.RestTimeOut:
137 | // ;//m_ResourcePlayer[(int)type] = new System.Media.SoundPlayer(Res.Fermium_RestTimeOut);
138 | // break;
139 | // }
140 | //}
141 | break;
142 |
143 | case SoundState.File:
144 | //if (m_wmplayer == null)
145 | //{
146 | // m_wmplayer = new WMPLib.WindowsMediaPlayer();
147 | // m_wmplayer.PlayStateChange +=
148 | // new WMPLib._WMPOCXEvents_PlayStateChangeEventHandler(Player_PlayStateChange);
149 | //}
150 | if (m_mediaPlayer == null)
151 | {
152 | m_mediaPlayer = new MediaPlayer();
153 | m_mediaPlayer.MediaEnded += MediaPlayer_MediaEnded;
154 | }
155 |
156 | break;
157 |
158 | }
159 |
160 | }
161 |
162 | private void MediaPlayer_MediaEnded(object sender, EventArgs e)
163 | {
164 | for (int i = 0; i < 4; i++)
165 | {
166 | SyncStateToUI((SoundType)i, m_aSoundState[i]);
167 | }
168 | }
169 |
170 | private string getSoundPathProperties(SoundType type)
171 | {
172 |
173 | switch (type)
174 | {
175 | case SoundType.Resume:
176 | return TomatoTimerWPF.TimerSettings.Default.SoundPathResume;
177 | case SoundType.Pause:
178 | return TomatoTimerWPF.TimerSettings.Default.SoundPathPause;
179 | case SoundType.WorkDone:
180 | return TomatoTimerWPF.TimerSettings.Default.SoundPathTimeOutWork;
181 | case SoundType.RestTimeOut:
182 | return TomatoTimerWPF.TimerSettings.Default.SoundPathTimeOutRest;
183 | default:
184 | return "";
185 | }
186 | }
187 |
188 | private void setSoundPathProperties(SoundType type,string stateString)
189 | {
190 | switch (type)
191 | {
192 | case SoundType.Resume:
193 | TomatoTimerWPF.TimerSettings.Default.SoundPathResume = stateString;
194 | break;
195 | case SoundType.Pause:
196 | TomatoTimerWPF.TimerSettings.Default.SoundPathPause = stateString;
197 | break;
198 | case SoundType.WorkDone:
199 | TomatoTimerWPF.TimerSettings.Default.SoundPathTimeOutWork = stateString;
200 | break;;
201 | case SoundType.RestTimeOut:
202 | TomatoTimerWPF.TimerSettings.Default.SoundPathTimeOutRest = stateString;
203 | break;
204 | }
205 | }
206 |
207 | //private void Player_PlayStateChange(int NewState)
208 | //{
209 | // if ((WMPLib.WMPPlayState)NewState == WMPLib.WMPPlayState.wmppsStopped ||
210 | // (WMPLib.WMPPlayState)NewState == WMPLib.WMPPlayState.wmppsMediaEnded)
211 | // {
212 | // for (int i = 0; i < 4; i++)
213 | // {
214 | // SyncStateToUI((SoundType)i, m_aSoundState[i]);
215 | // }
216 | // }
217 | // else if ((WMPLib.WMPPlayState)NewState == WMPLib.WMPPlayState.wmppsPlaying)
218 | // {
219 | // btnSoundPausePlay.Visibility = Visibility.Collapsed;
220 | // btnSoundResumePlay.Visibility = Visibility.Collapsed;
221 | // btnSoundWorkPlay.Visibility = Visibility.Collapsed;
222 | // btnSoundRestPlay.Visibility = Visibility.Collapsed;
223 |
224 | // btnSoundPauseStop.Visibility = Visibility.Visible;
225 | // btnSoundResumeStop.Visibility = Visibility.Visible;
226 | // btnSoundWorkStop.Visibility = Visibility.Visible;
227 | // btnSoundRestStop.Visibility = Visibility.Visible;
228 | // }
229 | //}
230 |
231 | public void playSound(SoundType type)
232 | {
233 | if ((int)type >= 4 || (int)type < 0) return;
234 |
235 | SyncStateToPlayer(type, m_aSoundState[(int)type]);
236 | switch (m_aSoundState[(int)type])
237 | {
238 | case SoundState.File:
239 | //m_wmplayer.URL = getSoundPathProperties(type);
240 | //m_wmplayer.controls.play();
241 | m_mediaPlayer.Open(new Uri(getSoundPathProperties(type)));
242 | m_mediaPlayer.Play();
243 |
244 | btnSoundPausePlay.Visibility = Visibility.Collapsed;
245 | btnSoundResumePlay.Visibility = Visibility.Collapsed;
246 | btnSoundWorkPlay.Visibility = Visibility.Collapsed;
247 | btnSoundRestPlay.Visibility = Visibility.Collapsed;
248 |
249 | btnSoundPauseStop.Visibility = Visibility.Visible;
250 | btnSoundResumeStop.Visibility = Visibility.Visible;
251 | btnSoundWorkStop.Visibility = Visibility.Visible;
252 | btnSoundRestStop.Visibility = Visibility.Visible;
253 |
254 | break;
255 | case SoundState.Resource:
256 | //m_ResourcePlayer[(int)type].Play();
257 | break;
258 | }
259 |
260 | }
261 |
262 | private void btnSound_Click(object sender, RoutedEventArgs e)
263 | {
264 | Button btnSelf = (sender as Button);
265 |
266 | btnSelf.ContextMenu.IsEnabled = true;
267 | btnSelf.ContextMenu.PlacementTarget = btnSelf;
268 | btnSelf.ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Center;
269 | btnSelf.ContextMenu.VerticalOffset = (btnSelf.ActualHeight);
270 | //btnSelf.ContextMenu.HorizontalOffset = (btnSelf.ContextMenu.ActualWidth / 2);
271 | btnSelf.ContextMenu.IsOpen = true;
272 |
273 | }
274 |
275 | private void btnGotoSetting_Click(object sender, RoutedEventArgs e)
276 | {
277 | //if (m_wmplayer != null && m_wmplayer.playState == WMPLib.WMPPlayState.wmppsPlaying)
278 | // m_wmplayer.controls.stop();
279 | if (m_mediaPlayer != null)
280 | m_mediaPlayer.Stop();
281 | m_window.SwitchFromSoundToSetting();
282 | }
283 |
284 | private void menuClose_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
285 | {
286 | //MessageBox.Show("menuClose_MouseLeftButtonUp");
287 | m_window.SavePropertiesAndClose(true);
288 | }
289 |
290 | private void menuCloseDontSave_Click(object sender, RoutedEventArgs e)
291 | {
292 | //MessageBox.Show("menuCloseDontSave_Click");
293 | m_window.SavePropertiesAndClose(false);
294 | }
295 |
296 | private void menuCloseSave_Click(object sender, RoutedEventArgs e)
297 | {
298 | //MessageBox.Show("menuCloseSave_Click");
299 | m_window.SavePropertiesAndClose(true);
300 | }
301 |
302 | private void btnSoundPlay_Click(object sender, RoutedEventArgs e)
303 | {
304 | Button btnSelf = sender as Button;
305 | SoundType type;
306 | for (int i=0;i<4;i++)
307 | {
308 | if (btnSelf == m_aBtnPlay[i])
309 | {
310 | type = (SoundType)i;
311 | playSound(type);
312 | return;
313 | }
314 | }
315 | }
316 |
317 | private void btnSoundStop_Click(object sender, RoutedEventArgs e)
318 | {
319 | //if (m_wmplayer == null) return;
320 | //m_wmplayer.controls.stop();
321 | if (m_mediaPlayer == null) return;
322 | m_mediaPlayer.Stop();
323 | for (int i = 0; i < 4; i++)
324 | {
325 | SyncStateToUI((SoundType)i, m_aSoundState[i]);
326 | }
327 |
328 | }
329 |
330 | private void btnSoundOpenFile_Click(object sender, RoutedEventArgs e)
331 | {
332 | Button btnSelf = sender as Button;
333 | SoundType type;
334 |
335 | System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();
336 |
337 | //dialog.Filter = "Sound files (*.wma;*.mp3;*.wav;*.ogg)|*.wma;*.mp3;*.wav;*.ogg";
338 | dialog.Filter = "Sound files (*.wma;*.mp3;*.wav)|*.wma;*.mp3;*.wav";
339 | //dialog.InitialDirectory = System.Windows.Forms.Application.StartupPath;
340 | dialog.Title = "Select a sound file";
341 |
342 | if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
343 | {
344 | for (int i = 0; i < 4; i++)
345 | {
346 | if (btnSelf == m_aBtnOpenFile[i])
347 | {
348 | type = (SoundType)i;
349 | m_aSoundState[i] = SoundState.File;
350 | SyncStateToUI(type, SoundState.File);
351 | setSoundPathProperties(type, dialog.FileName);
352 | playSound(type);
353 | return;
354 | }
355 | }
356 | }
357 | //else
358 | //{
359 | // for (int i = 0; i < 4; i++)
360 | // {
361 | // if (btnSelf == m_aBtnOpenFile[i])
362 | // {
363 | // type = (SoundType)i;
364 | // m_aSoundState[i] = SoundState.Mute;
365 | // SyncStateToUI(type, SoundState.Resource);
366 | // setSoundPathProperties(type, SoundState.Resource.ToString());
367 | // playSound(type);
368 | // return;
369 | // }
370 | // }
371 | //}
372 | }
373 |
374 | private void btnSoundMute_Click(object sender, RoutedEventArgs e)
375 | {
376 | if (m_mediaPlayer != null)
377 | m_mediaPlayer.Stop();
378 | Button btnSelf = sender as Button;
379 | SoundType type;
380 | for (int i = 0; i < 4; i++)
381 | {
382 | if (btnSelf == m_aBtnMute[i])
383 | {
384 | type = (SoundType)i;
385 | m_aSoundState[i] = SoundState.Mute;
386 | SyncStateToUI(type, SoundState.Mute);
387 | setSoundPathProperties(type, SoundState.Mute.ToString());
388 | return;
389 | }
390 | }
391 | }
392 |
393 | }
394 | }
395 |
--------------------------------------------------------------------------------
/TomatoTimerWPF/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | using System.Runtime.InteropServices;
17 | using System.Drawing;
18 | using System.Windows.Interop;
19 | using System.Windows.Media.Animation;
20 | using System.Configuration;
21 |
22 | using TomatoTimerWPF.Pages;
23 |
24 | namespace TomatoTimerWPF
25 | {
26 | using Res = Properties.Resources;
27 | //using Setting = Properties.Settings;
28 | ///
29 | /// Interaction logic for MainWindow.xaml
30 | ///
31 | public partial class MainWindow : Window
32 | {
33 |
34 | [DllImport("user32.dll")]
35 | static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi);
36 | //static extern uint SetClassLong(HandleRef hWnd, int nIndex, uint dwNewLong);
37 | //static extern uint GetClassLong(HandleRef hWnd, int nIndex, uint dwNewLong);
38 |
39 | [//Obsolete("This method will crash on 64-bit operating systems. Use SetClassLongPtr instead"),
40 | DllImport("user32.dll", SetLastError = true)]
41 | static extern uint SetClassLong(HandleRef hWnd, int nIndex, uint dwNewLong);
42 |
43 | private const Int32 GWL_STYLE = -16;
44 | private const Int32 WS_MAXIMIZEBOX = 0x00010000;
45 | private const Int32 WS_MINIMIZEBOX = 0x00020000;
46 |
47 | [DllImport("User32.dll", EntryPoint = "GetWindowLong")]
48 | private extern static Int32 GetWindowLongPtr(IntPtr hWnd, Int32 nIndex);
49 |
50 | [DllImport("User32.dll", EntryPoint = "SetWindowLong")]
51 | private extern static Int32 SetWindowLongPtr(IntPtr hWnd, Int32 nIndex, Int32 dwNewLong);
52 |
53 | [StructLayout(LayoutKind.Sequential)]
54 | public struct FLASHWINFO
55 | {
56 | public UInt32 cbSize;
57 | public IntPtr hwnd;
58 | public Int32 dwFlags;
59 | public UInt32 uCount;
60 | public Int32 dwTimeout;
61 | }
62 |
63 | [System.Runtime.InteropServices.DllImport("gdi32.dll")]
64 | public static extern bool DeleteObject(IntPtr hObject);
65 |
66 | enum TimerMode{
67 | MODE_WORK,
68 | MODE_RELAX,
69 | MODE_RELAX_LONG
70 | };
71 |
72 | private System.Windows.Forms.Timer m_timer;
73 | private bool m_bIsPause = false;
74 | private DateTime m_TimeDateStart = DateTime.Now;
75 | private DateTime m_TimeDatePauseStart;
76 | private TimeSpan m_TimeSpan;
77 | private TimeSpan m_TimeSpanPause;
78 | private TimerMode m_mode = TimerMode.MODE_WORK;
79 | private int m_OverlayIconLastMin;
80 | private bool m_bIsSupportTaskbarManager = false;
81 | private bool m_bIsOverTime = false;
82 |
83 | public IntPtr m_hwnd;
84 |
85 | private Page_Buttons m_pageButtons;
86 | private Page_Settings m_pageSettings;
87 | private Page_SoundSettings m_pageSoundSettings;
88 |
89 | Storyboard m_sbAniOut;
90 | Storyboard m_sbAniIn;
91 |
92 | ThicknessAnimation m_taSlideOut;
93 | ThicknessAnimation m_taSlideIn;
94 |
95 | private bool m_isNormalClosingEvent;
96 |
97 | public MainWindow()
98 | {
99 |
100 | InitializeComponent();
101 |
102 | //string path = System.Reflection.Assembly.GetExecutingAssembly().Location + ".config";
103 | //if (!System.IO.File.Exists(path))
104 | //{
105 | // //TomatoTimerWPF.TimerSettings.Default.Save();
106 | // Console.WriteLine("Save setting [" + path + "]");
107 | //}
108 | //else
109 | // Console.WriteLine("Exists![" + path + "]");
110 |
111 | m_OverlayIconLastMin = -99999;
112 | m_isNormalClosingEvent = false;
113 |
114 | //Initialize animations
115 | m_sbAniOut = new Storyboard();
116 | DoubleAnimation daFadeOut = new DoubleAnimation();
117 | daFadeOut.Duration = 200.Milliseconds();
118 | daFadeOut.To = 0.0;
119 |
120 | ThicknessAnimation taSlideOut = new ThicknessAnimation();
121 | taSlideOut.Duration = 200.Milliseconds();
122 | taSlideOut.To = new Thickness(0, this.Height, 0, 0);
123 | taSlideOut.From = new Thickness(0, 0, 0, 0);
124 |
125 | m_sbAniOut.Completed += Storyboard_Completed;
126 | m_sbAniOut.Children.Add(daFadeOut);
127 | m_sbAniOut.Children.Add(taSlideOut);
128 | Storyboard.SetTargetProperty(daFadeOut, new PropertyPath(UIElement.OpacityProperty));
129 | Storyboard.SetTargetProperty(taSlideOut, new PropertyPath(FrameworkElement.MarginProperty));
130 |
131 |
132 | m_sbAniIn = new Storyboard();
133 | DoubleAnimation daFadeIn = new DoubleAnimation();
134 | daFadeIn.Duration = 200.Milliseconds();
135 | daFadeIn.From = 0.0;
136 | daFadeIn.To = 1.0;
137 |
138 | ThicknessAnimation taSlideIn = new ThicknessAnimation();
139 | taSlideIn.Duration = 200.Milliseconds();
140 | taSlideIn.From = new Thickness(0, -this.Height, 0, 0);
141 | taSlideIn.To = new Thickness(0, 0, 0, 0);
142 |
143 | m_sbAniIn.Completed += Storyboard_Completed;
144 | m_sbAniIn.Children.Add(daFadeIn);
145 | m_sbAniIn.Children.Add(taSlideIn);
146 | Storyboard.SetTargetProperty(daFadeIn, new PropertyPath(UIElement.OpacityProperty));
147 | Storyboard.SetTargetProperty(taSlideIn, new PropertyPath(FrameworkElement.MarginProperty));
148 |
149 | m_taSlideOut = taSlideOut;
150 | m_taSlideIn = taSlideIn;
151 |
152 | try
153 | {
154 | Rect bounds = Rect.Parse(TomatoTimerWPF.TimerSettings.Default.WindowRestoreBounds);
155 | bounds = CheckBounds(bounds);
156 | this.Top = bounds.Top;
157 | this.Left = bounds.Left;
158 | this.Width = bounds.Width;
159 | this.Height = bounds.Height;
160 | }
161 | catch (Exception)
162 | {
163 | //MessageBox.Show(e.ToString());
164 | //MessageBox.Show("[" + TomatoTimerWPF.TimerSettings.Default.WindowRestoreBounds + "]");
165 | }
166 | }
167 |
168 | static public Rect CheckBounds(Rect bounds)
169 | {
170 | int iInsideLT, iInsideRB;
171 | iInsideLT = iInsideRB = -1;
172 | for (int s = 0; s < System.Windows.Forms.Screen.AllScreens.Length;s++ )
173 | {
174 | System.Windows.Forms.Screen screen = System.Windows.Forms.Screen.AllScreens[s];
175 | if (bounds.Left >= screen.Bounds.Left && bounds.Top >= screen.Bounds.Top &&
176 | bounds.Left < screen.Bounds.Right && bounds.Top < screen.Bounds.Bottom)
177 | {
178 | iInsideLT = s;
179 | }
180 |
181 | if (bounds.Right >= screen.Bounds.Left && bounds.Bottom >= screen.Bounds.Top &&
182 | bounds.Right < screen.Bounds.Right && bounds.Bottom < screen.Bounds.Bottom)
183 | {
184 | iInsideRB = s;
185 | }
186 | }
187 |
188 | //if (iInsideLT != -1 || iInsideRB != -1)
189 | {
190 | int recheckScreen = -1;
191 |
192 | if (iInsideLT == -1 && iInsideRB == -1)
193 | recheckScreen = 0;
194 | else if (iInsideLT == -1)
195 | recheckScreen = iInsideRB;
196 | else if (iInsideRB == -1)
197 | recheckScreen = iInsideLT;
198 |
199 | if (recheckScreen != -1)
200 | {
201 | System.Windows.Forms.Screen screen = System.Windows.Forms.Screen.AllScreens[recheckScreen];
202 |
203 | if (bounds.X < screen.Bounds.Left)
204 | bounds.X = screen.Bounds.Left;
205 | if (bounds.Y < screen.Bounds.Top)
206 | bounds.Y = screen.Bounds.Top;
207 | if (bounds.Width > screen.Bounds.Width)
208 | bounds.Width = screen.Bounds.Width;
209 | if (bounds.Height > screen.Bounds.Height)
210 | bounds.Height = screen.Bounds.Height;
211 |
212 | if (bounds.Right > screen.Bounds.Right)
213 | bounds.X -= bounds.Right - screen.Bounds.Right;
214 | if (bounds.Bottom > screen.Bounds.Bottom)
215 | bounds.Y -= bounds.Bottom - screen.Bounds.Bottom;
216 |
217 | }
218 | }
219 | return bounds;
220 | }
221 |
222 | private void Window_Loaded_1(object sender, RoutedEventArgs e)
223 | {
224 | m_hwnd = new WindowInteropHelper(this).Handle;
225 |
226 | Int32 windowStyle = GetWindowLongPtr(m_hwnd, GWL_STYLE);
227 | SetWindowLongPtr(m_hwnd, GWL_STYLE, windowStyle & ~WS_MAXIMIZEBOX);
228 |
229 | m_bIsSupportTaskbarManager = true;
230 | this.TaskbarItemInfo.ThumbnailClipMargin = new Thickness(0, 0, 0, 0);
231 |
232 | try
233 | {
234 | DateTime restoreStart = DateTime.Parse(TomatoTimerWPF.TimerSettings.Default.TimerRestoreDateTime);
235 | m_TimeDateStart = restoreStart;
236 | m_TimeDatePauseStart = restoreStart;
237 | m_mode = (TimerMode)TomatoTimerWPF.TimerSettings.Default.TimerRestoreMode;
238 | }
239 | catch(Exception)
240 | {
241 | m_TimeDateStart = DateTime.Now;
242 | m_TimeDatePauseStart = DateTime.Now;
243 | }
244 |
245 | m_pageButtons = new Page_Buttons(this);
246 | m_pageSettings = new Page_Settings(this);
247 | m_pageSoundSettings = new Page_SoundSettings(this);
248 |
249 | btnAlwaysOnTop.IsChecked = TomatoTimerWPF.TimerSettings.Default.AlwaysOnTop;
250 | if (btnAlwaysOnTop.IsChecked == true)
251 | this.ToggleAlwaysOnTop();
252 |
253 | spWindowControlStackPanel.Margin = new Thickness(0, -this.Height, 0, 0);
254 | m_sbAniOut.Begin(spWindowControlStackPanel);
255 |
256 | this.ucContent.Children.Add(m_pageButtons);
257 | UpdateUI();
258 |
259 | m_timer = new System.Windows.Forms.Timer();
260 | m_timer.Interval = 1000;
261 | m_timer.Tick += new EventHandler(Timer_Tick);
262 | m_timer.Start();
263 | }
264 |
265 | void Timer_Tick(object sender, EventArgs e)
266 | {
267 | UpdateUI();
268 | }
269 |
270 | public void SavePropertiesAndClose(bool isSaveTimerState)
271 | {
272 | if (isSaveTimerState && m_mode == TimerMode.MODE_WORK)
273 | {
274 | TomatoTimerWPF.TimerSettings.Default.TimerRestoreDateTime = m_TimeDateStart.ToString();
275 | TomatoTimerWPF.TimerSettings.Default.TimerRestoreMode = (int)m_mode;
276 | }
277 | else
278 | {
279 | TomatoTimerWPF.TimerSettings.Default.TimerRestoreDateTime = "";
280 | TomatoTimerWPF.TimerSettings.Default.TimerRestoreMode = (int)TimerMode.MODE_WORK;
281 | }
282 | TomatoTimerWPF.TimerSettings.Default.WindowRestoreBounds = this.RestoreBounds.ToString();
283 | TomatoTimerWPF.TimerSettings.Default.Save();
284 |
285 | m_isNormalClosingEvent = true;
286 | Close();
287 | }
288 |
289 | private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
290 | {
291 | if (!m_isNormalClosingEvent)
292 | {
293 | if (m_mode == TimerMode.MODE_WORK)
294 | {
295 | TomatoTimerWPF.TimerSettings.Default.TimerRestoreDateTime = m_TimeDateStart.ToString();
296 | TomatoTimerWPF.TimerSettings.Default.TimerRestoreMode = (int)m_mode;
297 | }
298 | else
299 | {
300 | TomatoTimerWPF.TimerSettings.Default.TimerRestoreDateTime = "";
301 | TomatoTimerWPF.TimerSettings.Default.TimerRestoreMode = (int)TimerMode.MODE_WORK;
302 | }
303 |
304 | TomatoTimerWPF.TimerSettings.Default.WindowRestoreBounds = this.RestoreBounds.ToString();
305 | TomatoTimerWPF.TimerSettings.Default.Save();
306 | }
307 | }
308 |
309 | public void UpdateUI()
310 | {
311 |
312 |
313 | TimeSpan pauseSpan = m_TimeSpanPause;
314 | if (m_bIsPause)
315 | pauseSpan += DateTime.Now - m_TimeDatePauseStart;
316 |
317 | TimeSpan timerSpan, modeSpan;
318 | if (m_mode == TimerMode.MODE_WORK)
319 | modeSpan = TimeSpan.FromMinutes(TomatoTimerWPF.TimerSettings.Default.Work_Time) + 800.Milliseconds();
320 | else if (m_mode == TimerMode.MODE_RELAX)
321 | modeSpan = TimeSpan.FromMinutes(TomatoTimerWPF.TimerSettings.Default.Relax_Time) + 800.Milliseconds();
322 | else if (m_mode == TimerMode.MODE_RELAX_LONG)
323 | modeSpan = TimeSpan.FromMinutes(TomatoTimerWPF.TimerSettings.Default.Relax_Time_Long) + 800.Milliseconds();
324 | else
325 | modeSpan = 1.Seconds();
326 |
327 | if (m_bIsPause)
328 | timerSpan = modeSpan - m_TimeSpan;
329 | else
330 | timerSpan = modeSpan - (DateTime.Now - m_TimeDateStart);
331 |
332 | if (!m_bIsOverTime && timerSpan.IsNegativeOrZero())
333 | {
334 | SetWindowFlash(true);
335 |
336 | if (m_mode == TimerMode.MODE_WORK)
337 | m_pageSoundSettings.playSound(Page_SoundSettings.SoundType.WorkDone);
338 | else
339 | m_pageSoundSettings.playSound(Page_SoundSettings.SoundType.RestTimeOut);
340 |
341 | }
342 |
343 | m_bIsOverTime = timerSpan.IsNegativeOrZero();
344 |
345 |
346 |
347 | double progressValue = 100.0 - ((timerSpan.TotalMilliseconds * 100.0 / modeSpan.TotalMilliseconds));
348 | if (progressValue < 0.0)
349 | progressValue = 0.0;
350 | else if (progressValue > 100.0)
351 | progressValue = 100.0;
352 |
353 |
354 | Page_Buttons pageButtons = m_pageButtons;//pageTransitionControl.CurrentPage as Page_Buttons;
355 | if (pageButtons != null)
356 | {
357 | if (m_mode == TimerMode.MODE_WORK)
358 | {
359 | pageButtons.btnWork.Visibility = false.ToVisibility();
360 | pageButtons.btnWork.IsEnabled = false;
361 |
362 | pageButtons.btnRelax.Visibility = true.ToVisibility();
363 | pageButtons.btnRelax.IsEnabled = true;
364 |
365 | if (m_bIsPause)
366 | {
367 | pageButtons.btnPause.Visibility = false.ToVisibility();
368 | pageButtons.btnPause.IsEnabled = false;
369 |
370 | pageButtons.btnPlay.Visibility = true.ToVisibility();
371 | pageButtons.btnPlay.IsEnabled = true;
372 | pageButtons.labelTime.Opacity = 0.5;
373 | }
374 | else
375 | {
376 |
377 | pageButtons.btnPause.Visibility = (!m_bIsPause).ToVisibility();
378 | pageButtons.btnPause.IsEnabled = (!m_bIsPause);
379 |
380 | pageButtons.btnPlay.Visibility = false.ToVisibility();
381 | pageButtons.btnPlay.IsEnabled = false;
382 | pageButtons.labelTime.Opacity = 1;
383 | }
384 | }
385 | else
386 | {
387 | pageButtons.btnWork.Visibility = true.ToVisibility();
388 | pageButtons.btnWork.IsEnabled = true;
389 |
390 | pageButtons.btnRelax.Visibility = false.ToVisibility();
391 | pageButtons.btnRelax.IsEnabled = false;
392 |
393 | pageButtons.btnPause.Visibility = false.ToVisibility();
394 | pageButtons.btnPause.IsEnabled = false;
395 |
396 | pageButtons.btnPlay.Visibility = false.ToVisibility();
397 | pageButtons.btnPlay.IsEnabled = false;
398 | pageButtons.labelTime.Opacity = 1;
399 | }
400 |
401 | String info, time;
402 | if (m_TimeDateStart.Day != DateTime.Now.Day || m_TimeDateStart.Month != DateTime.Now.Month)
403 | info = m_TimeDateStart.ToString("MM/dd H:mm");
404 | else
405 | info = "Start @ " + m_TimeDateStart.ToString("H:mm");
406 |
407 | if (!pauseSpan.IsNegativeOrZero())
408 | {
409 | if (pauseSpan.Hours != 0 || pauseSpan.Days != 0)
410 | info += "\r\nPause: {0}:{1:00}:{2:00}".ToFormat(Math.Abs(pauseSpan.Hours + pauseSpan.Days * 24), Math.Abs(pauseSpan.Minutes), Math.Abs(pauseSpan.Seconds));
411 | else
412 | info += "\r\nPause: {0}:{1:00}".ToFormat(Math.Abs(pauseSpan.Minutes), Math.Abs(pauseSpan.Seconds));
413 | }
414 |
415 | pageButtons.labelInfo.Content = info;
416 |
417 |
418 | TextBlock timeText = new TextBlock();
419 | if (m_mode == TimerMode.MODE_WORK)
420 | {
421 | time = "Work ";
422 | //timeText.Inlines.Add(new Bold(new Run("W")));
423 | timeText.Inlines.Add("Work ");
424 | }
425 | else if (m_mode == TimerMode.MODE_RELAX || m_mode == TimerMode.MODE_RELAX_LONG)
426 | {
427 | time = "Rest ";
428 | //timeText.Inlines.Add(new Bold(new Run("R")));
429 | timeText.Inlines.Add("Rest ");
430 | }
431 | else
432 | time = "";
433 |
434 |
435 | if (timerSpan.Hours != 0 || timerSpan.Days != 0)
436 | {
437 | if ((timerSpan.Seconds & 0x1) == 0)
438 | time += "{0}:{1:00} {2:00}".ToFormat(Math.Abs(timerSpan.Hours + timerSpan.Days * 24), Math.Abs(timerSpan.Minutes), Math.Abs(timerSpan.Seconds));
439 | else
440 | time += "{0}:{1:00}:{2:00}".ToFormat(Math.Abs(timerSpan.Hours + timerSpan.Days * 24), Math.Abs(timerSpan.Minutes), Math.Abs(timerSpan.Seconds));
441 |
442 | timeText.Inlines.Add("{0}:{1:00}".ToFormat(Math.Abs(timerSpan.Hours + timerSpan.Days * 24), Math.Abs(timerSpan.Minutes)));
443 | //Run minText = new Run("{0:00}".ToFormat(Math.Abs(timerSpan.Minutes)));
444 | //minText.FontFamily = new System.Windows.Media.FontFamily("/TomatoTimerWPF;component/Resource/#Roboto");
445 | //minText.FontWeight = FontWeights.Black;
446 | //timeText.Inlines.Add(new Bold(minText));
447 | timeText.Inlines.Add((timerSpan.Seconds & 0x1) == 0 ? ":" : " ");
448 | timeText.Inlines.Add("{0:00}".ToFormat(Math.Abs(timerSpan.Seconds)));
449 | }
450 | else
451 | {
452 | if ((timerSpan.Seconds & 0x1)==0)
453 | time += "{0} {1:00}".ToFormat(Math.Abs(timerSpan.Minutes), Math.Abs(timerSpan.Seconds));
454 | else
455 | time += "{0}:{1:00}".ToFormat(Math.Abs(timerSpan.Minutes), Math.Abs(timerSpan.Seconds));
456 |
457 | Run minText= new Run("{0}".ToFormat(Math.Abs(timerSpan.Minutes)));
458 | minText.FontFamily = new System.Windows.Media.FontFamily("/TomatoTimerWPF;component/Resource/#Roboto");
459 | minText.FontWeight = FontWeights.Black;
460 | timeText.Inlines.Add(new Bold(minText));
461 | timeText.Inlines.Add((timerSpan.Seconds & 0x1)==0?":":" ");
462 | timeText.Inlines.Add("{0:00}".ToFormat(Math.Abs(timerSpan.Seconds)));
463 | }
464 |
465 | if (pageButtons.labelTimeWhite.Visibility == Visibility.Visible)
466 | {
467 | pageButtons.labelTimeWhite.Content = time;
468 | pageButtons.labelTime.Content = time;
469 | }
470 | else
471 | {
472 | pageButtons.labelTime.Content = timeText;
473 | }
474 |
475 |
476 | if (pageButtons.GetIsMouseDown())
477 | {
478 | if (pageButtons.btnRelax.IsPressed)
479 | {
480 | progressValue = pageButtons.GetLongMouseDownPercentage();
481 | pageButtons.labelTime_small.Content = progressValue >= 100 ? "Long rest" : time;
482 | }
483 | else if (pageButtons.btnReset.IsPressed && m_mode == TimerMode.MODE_WORK)
484 | {
485 | progressValue = pageButtons.GetLongMouseDownPercentage();
486 | pageButtons.labelTime_small.Content = progressValue >= 100 ? "Skip GCal" : time;
487 | }
488 | else
489 | pageButtons.labelTime_small.Content = time;
490 | }
491 | else
492 | pageButtons.labelTime_small.Content = time;
493 |
494 |
495 |
496 | if (m_bIsPause)
497 | {
498 | pageButtons.pbarTimer.Foreground = System.Windows.Media.Brushes.Green;
499 | pageButtons.pbarTimer.IsIndeterminate = true;
500 | pageButtons.pbarTimer.Value = progressValue;
501 | pageButtons.labelTimeWhite.Opacity = 0;
502 | }
503 | else if (m_bIsOverTime)
504 | {
505 | pageButtons.pbarTimer.Foreground = System.Windows.Media.Brushes.Red;
506 | pageButtons.pbarTimer.IsIndeterminate = false;
507 | pageButtons.pbarTimer.Value = 100;
508 | pageButtons.labelTimeWhite.Opacity = 1;
509 | }
510 | else
511 | {
512 | if (progressValue > 80)
513 | {
514 | pageButtons.pbarTimer.Foreground = System.Windows.Media.Brushes.Yellow;
515 | pageButtons.labelTimeWhite.Opacity = 0;
516 | }
517 | else
518 | {
519 | pageButtons.pbarTimer.Foreground = System.Windows.Media.Brushes.Green;
520 | pageButtons.labelTimeWhite.Opacity = 1;
521 | }
522 | pageButtons.pbarTimer.IsIndeterminate = false;
523 | pageButtons.pbarTimer.Value = progressValue;
524 | }
525 |
526 |
527 | }
528 |
529 |
530 | int tMin = timerSpan.Hours * 24 + timerSpan.Minutes;
531 |
532 | if (m_bIsSupportTaskbarManager)
533 | {
534 |
535 | if (m_OverlayIconLastMin != (tMin == 0 ? timerSpan.Seconds : tMin) + (timerSpan.IsNegativeOrZero() ? 1 : 0) + (m_bIsPause ? 3 : 1))
536 | {
537 | Bitmap bmp = new Bitmap(16, 16);
538 |
539 |
540 | using (Graphics g = Graphics.FromImage(bmp))
541 | {
542 | g.FillRectangle(System.Drawing.Brushes.Black, 0, 0, 16, 16);
543 | if (m_bIsPause)
544 | g.FillRectangle(System.Drawing.Brushes.Gray, 1, 1, 14, 14);
545 | else if (timerSpan.IsNegativeOrZero())
546 | g.FillRectangle(System.Drawing.Brushes.DarkRed, 1, 1, 14, 14);
547 | else if (m_mode == TimerMode.MODE_WORK)
548 | g.FillRectangle(System.Drawing.Brushes.BlueViolet, 1, 1, 14, 14);
549 | else
550 | g.FillRectangle(System.Drawing.Brushes.MediumSeaGreen, 1, 1, 14, 14);
551 |
552 | if (timerSpan.Hours != 0 || timerSpan.Days != 0)
553 | {
554 | if (Math.Abs(timerSpan.Hours + timerSpan.Days * 24) <= 99)
555 | {
556 | g.DrawString("{0:00}".ToFormat(Math.Abs(timerSpan.Hours + timerSpan.Days * 24)), new Font("Arial", 6), new SolidBrush(System.Drawing.Color.White), 2, -1);
557 | g.DrawString("{0:00}".ToFormat(Math.Abs(timerSpan.Minutes)), new Font("Arial", 6), new SolidBrush(System.Drawing.Color.White), 2, 6);
558 | }
559 | else
560 | {
561 | g.DrawString("99", new Font("Impact", 6), new SolidBrush(System.Drawing.Color.White), 2, -1);
562 | g.DrawString("59", new Font("Impact", 6), new SolidBrush(System.Drawing.Color.White), 2, 6);
563 | }
564 | }
565 | else if (tMin == 0 && !timerSpan.IsNegativeOrZero() && !m_bIsPause)
566 | g.DrawString("{0:00}".ToFormat(Math.Abs(timerSpan.Seconds)), new Font("Courier New", 9), new SolidBrush(timerSpan.Seconds % 2 == 0 ? System.Drawing.Color.White : System.Drawing.Color.Black), -1, 0);
567 | else
568 | g.DrawString("{0:00}".ToFormat(Math.Abs(timerSpan.Minutes)), new Font("Courier New", 9), new SolidBrush(System.Drawing.Color.White), -1, 0);
569 |
570 | IntPtr hBitmap = bmp.GetHbitmap();
571 | this.TaskbarItemInfo.Overlay = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
572 | hBitmap,
573 | IntPtr.Zero,
574 | System.Windows.Int32Rect.Empty,
575 | BitmapSizeOptions.FromWidthAndHeight(bmp.Width, bmp.Height));
576 |
577 | DeleteObject(hBitmap);
578 | }
579 | m_OverlayIconLastMin = (tMin == 0 ? timerSpan.Seconds : tMin) + (timerSpan.IsNegativeOrZero() ? 1 : 0) + (m_bIsPause ? 3 : 1);
580 | }
581 |
582 |
583 | if (m_bIsPause)
584 | {
585 | this.TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Indeterminate;
586 | if (this.TaskbarItemInfo.ProgressValue != 1)
587 | this.TaskbarItemInfo.ProgressValue = 1;
588 | }
589 | else if (m_bIsOverTime)
590 | {
591 | if (m_mode == TimerMode.MODE_WORK)
592 | this.TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Paused;
593 | else
594 | this.TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Error;
595 | if (this.TaskbarItemInfo.ProgressValue != 1)
596 | this.TaskbarItemInfo.ProgressValue = 1;
597 | }
598 | else
599 | {
600 | if (progressValue > 80)
601 | this.TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Paused;
602 | else
603 | this.TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
604 | this.TaskbarItemInfo.ProgressValue = progressValue / 100;
605 | }
606 |
607 |
608 | if (m_mode == TimerMode.MODE_WORK)
609 | {
610 |
611 | ThumbButtonGoToWork.Visibility = Visibility.Collapsed;
612 | ThumbButtonTakeABreak.Visibility = Visibility.Visible;
613 | ThumbButtonPause.Visibility = !m_bIsPause ? Visibility.Visible : Visibility.Collapsed;
614 | ThumbButtonPlay.Visibility = m_bIsPause ? Visibility.Visible : Visibility.Collapsed;
615 |
616 | }
617 | else
618 | {
619 | ThumbButtonGoToWork.Visibility = Visibility.Visible;
620 | ThumbButtonTakeABreak.Visibility = Visibility.Collapsed;
621 | ThumbButtonPause.Visibility = Visibility.Collapsed;
622 | ThumbButtonPlay.Visibility = Visibility.Collapsed;
623 | }
624 | }
625 | }
626 |
627 | private int GetPercentageComplete(TimeSpan elapsed, TimeSpan total)
628 | {
629 | return (int)((elapsed.TotalMilliseconds * 100 / total.TotalMilliseconds));
630 | }
631 |
632 |
633 | public void StartWork()
634 | {
635 | if (m_bIsOverTime && m_mode == TimerMode.MODE_WORK &&
636 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_EnableEvent)
637 | OpenGoogleCalender(m_TimeDateStart, DateTime.Now);
638 |
639 | SetWindowFlash(false);
640 | m_TimeDateStart = DateTime.Now;
641 | m_TimeDatePauseStart = DateTime.Now;
642 | m_TimeSpanPause = TimeSpan.FromMinutes(0);
643 | m_TimeSpan = TimeSpan.FromMinutes(0);
644 | m_mode = TimerMode.MODE_WORK;
645 | m_bIsPause = false;
646 |
647 |
648 | //if (menuClose.Visibility == System.Windows.Visibility.Collapsed)
649 | //{
650 | // menuClose.Visibility = System.Windows.Visibility.Visible;
651 | // btnClose.Visibility = System.Windows.Visibility.Collapsed;
652 | //}
653 |
654 | UpdateUI();
655 |
656 | }
657 |
658 | public void StartRelax()
659 | {
660 | if (m_bIsOverTime && m_mode == TimerMode.MODE_WORK &&
661 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_EnableEvent)
662 | OpenGoogleCalender(m_TimeDateStart, DateTime.Now);
663 |
664 | SetWindowFlash(false);
665 | m_TimeDateStart = DateTime.Now;
666 | m_TimeDatePauseStart = DateTime.Now;
667 | m_TimeSpanPause = TimeSpan.FromMinutes(0);
668 | m_TimeSpan = TimeSpan.FromMinutes(0);
669 | m_mode = TimerMode.MODE_RELAX;
670 |
671 | if (m_pageButtons != null)
672 | {
673 | if (m_pageButtons.GetIsLongMouseDown())
674 | m_mode = TimerMode.MODE_RELAX_LONG;
675 | }
676 | m_bIsPause = false;
677 |
678 | //if (menuClose.Visibility == System.Windows.Visibility.Visible)
679 | //{
680 | // menuClose.Visibility = System.Windows.Visibility.Collapsed;
681 | // btnClose.Visibility = System.Windows.Visibility.Visible;
682 | //}
683 |
684 | UpdateUI();
685 | }
686 |
687 | public void Pause()
688 | {
689 | if (m_bIsPause) return;
690 | if (m_mode == TimerMode.MODE_RELAX_LONG || m_mode == TimerMode.MODE_RELAX)
691 | return;
692 |
693 | m_pageSoundSettings.playSound(Page_SoundSettings.SoundType.Pause);
694 | m_bIsPause = true;
695 | m_TimeSpan = DateTime.Now - m_TimeDateStart;
696 | m_TimeDatePauseStart = DateTime.Now;
697 | UpdateUI();
698 | }
699 |
700 | public void Resume()
701 | {
702 | TimeSpan pauseSpan;
703 | if (!m_bIsPause) return;
704 |
705 | m_pageSoundSettings.playSound(Page_SoundSettings.SoundType.Resume);
706 | m_bIsPause = false;
707 | pauseSpan = DateTime.Now - m_TimeDatePauseStart;
708 | m_TimeDateStart += pauseSpan;
709 | m_TimeSpanPause += pauseSpan;
710 |
711 | UpdateUI();
712 | }
713 |
714 | public void Reset()
715 | {
716 | if (m_bIsOverTime && m_mode == TimerMode.MODE_WORK && !m_pageButtons.GetIsLongMouseDown() &&
717 | TomatoTimerWPF.TimerSettings.Default.GoogleCal_EnableEvent)
718 | OpenGoogleCalender(m_TimeDateStart, DateTime.Now);
719 |
720 | SetWindowFlash(false);
721 | m_bIsPause = false;
722 | m_TimeDateStart = DateTime.Now;
723 | m_TimeDatePauseStart = DateTime.Now;
724 | m_TimeSpanPause = TimeSpan.FromMinutes(0);
725 | m_TimeSpan = TimeSpan.FromMinutes(0);
726 | UpdateUI();
727 |
728 |
729 | }
730 |
731 | private void SetWindowFlash(bool enable)
732 | {
733 | if (m_pageButtons.labelTimeWhite.Visibility == Visibility.Visible)
734 | return;
735 |
736 | FLASHWINFO fw = new FLASHWINFO();
737 |
738 | fw.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(FLASHWINFO)));
739 | fw.hwnd = m_hwnd;// new WindowInteropHelper(this).Handle;
740 | fw.dwFlags = enable ? 2 : 0;
741 | //fw.uCount = enable ? UInt32.MaxValue : 0;
742 | fw.uCount = enable ? (UInt32)(10*60) : 0;
743 |
744 | FlashWindowEx(ref fw);
745 | }
746 |
747 | public void OpenGoogleCalender(DateTime startTime, DateTime endTime)
748 | {
749 |
750 | String strTimeStart, strTimeEnd, gcalUrl;
751 | DateTime dateStartUTC, dateEndUTC;
752 |
753 | dateStartUTC = startTime.ToUniversalTime();
754 | dateEndUTC = endTime.ToUniversalTime();
755 | //dateEnd = DateTime.UtcNow;
756 |
757 | strTimeStart = String.Format("{0:yyyyMMdd}", dateStartUTC) + "T" + String.Format("{0:HHmmss}", dateStartUTC) + "Z";
758 | strTimeEnd = String.Format("{0:yyyyMMdd}", dateEndUTC) + "T" + String.Format("{0:HHmmss}", dateEndUTC) + "Z";
759 |
760 | //gcalUrl = "http://www.google.com/calendar/event?action=TEMPLATE";
761 | gcalUrl = "https://calendar.google.com/calendar/r/eventedit?action=TEMPLATE";
762 | if (TomatoTimerWPF.TimerSettings.Default.GoogleCal_text.Length != 0)
763 | {
764 | String textUrlEncode = System.Web.HttpUtility.UrlEncode(TomatoTimerWPF.TimerSettings.Default.GoogleCal_text);
765 | //MessageBox.Show("[" +TomatoTimerWPF.TimerSettings.Default.GoogleCal_text +"]->[" + textUrlEncode +"]");
766 | gcalUrl += "&text=" + textUrlEncode;
767 | }
768 | if (TomatoTimerWPF.TimerSettings.Default.GoogleCal_src.Length != 0)
769 | {
770 | if (TomatoTimerWPF.TimerSettings.Default.GoogleCal_src.IndexOf("@")!=-1)
771 | {
772 | gcalUrl += "&src=" + System.Web.HttpUtility.UrlEncode(TomatoTimerWPF.TimerSettings.Default.GoogleCal_src);
773 | }
774 | else
775 | gcalUrl += "&src=" + TomatoTimerWPF.TimerSettings.Default.GoogleCal_src;
776 | }
777 |
778 | gcalUrl += "&dates=" + strTimeStart + "/" + strTimeEnd;
779 | //MessageBox.Show(gcalUrl);
780 | if (TomatoTimerWPF.TimerSettings.Default.GoogleCal_CopyToClipboard)
781 | {
782 | System.Windows.Clipboard.SetText(gcalUrl);
783 | }
784 |
785 | System.Diagnostics.Process.Start(gcalUrl);
786 | }
787 |
788 |
789 | public void SwitchToButtons()
790 | {
791 | if (ucContent.Children.Count == 0)
792 | return;
793 | m_taSlideOut.To = new Thickness(0, this.Height, 0, 0);
794 | m_taSlideIn.From = new Thickness(0, -this.Height, 0, 0);
795 |
796 | pages.Push(m_pageButtons);
797 |
798 | FrameworkElement ucCurrent = ucContent.Children[0] as FrameworkElement;
799 | m_sbAniOut.Begin(ucCurrent);
800 |
801 |
802 | }
803 |
804 | Stack pages = new Stack();
805 |
806 | public void SwitchToSettings()
807 | {
808 | if (ucContent.Children.Count == 0)
809 | return;
810 |
811 | m_taSlideOut.To = new Thickness(0, -this.Height, 0, 0);
812 | m_taSlideIn.From = new Thickness(0, this.Height, 0, 0);
813 |
814 | pages.Push(m_pageSettings);
815 |
816 | FrameworkElement ucCurrent = ucContent.Children[0] as FrameworkElement;
817 | m_sbAniOut.Begin(ucCurrent);
818 |
819 | }
820 |
821 | public void SwitchFromSettingToSound()
822 | {
823 | if (ucContent.Children.Count == 0)
824 | return;
825 |
826 | m_taSlideOut.To = new Thickness(-this.Width, 0, 0, 0);
827 | m_taSlideIn.From = new Thickness(this.Width, 0, 0, 0);
828 |
829 | pages.Push(m_pageSoundSettings);
830 | FrameworkElement ucCurrent = ucContent.Children[0] as FrameworkElement;
831 | m_sbAniOut.Begin(ucCurrent);
832 |
833 | }
834 |
835 |
836 | public void SwitchFromSoundToSetting()
837 | {
838 | if (ucContent.Children.Count == 0)
839 | return;
840 |
841 | m_taSlideOut.To = new Thickness(this.Width, 0, 0, 0);
842 | m_taSlideIn.From = new Thickness(-this.Width, 0, 0, 0);
843 |
844 | pages.Push(m_pageSettings);
845 | UserControl ucCurrent = ucContent.Children[0] as UserControl;
846 | m_sbAniOut.Begin(ucCurrent);
847 |
848 | }
849 |
850 | private void Storyboard_Completed(object sender, EventArgs e)
851 | {
852 | if (pages.Count != 0)
853 | {
854 | UserControl page = pages.Pop();
855 |
856 | Page_Buttons pageButtons = page as Page_Buttons;
857 | if (pageButtons != null)
858 | {
859 | UpdateUI();
860 | btnAlwaysOnTop.Visibility = Visibility.Visible;
861 | }
862 | else
863 | btnAlwaysOnTop.Visibility = Visibility.Collapsed;
864 | ucContent.Children.Clear();
865 | ucContent.Children.Add(page);
866 |
867 | m_sbAniIn.Begin(page);
868 | }
869 | }
870 |
871 |
872 | private void btnAlwaysOnTop_Click(object sender, RoutedEventArgs e)
873 | {
874 | this.ToggleAlwaysOnTop();
875 | TomatoTimerWPF.TimerSettings.Default.AlwaysOnTop = this.Topmost;
876 | }
877 |
878 | private void ToggleAlwaysOnTop()
879 | {
880 | this.Topmost = btnAlwaysOnTop.IsChecked.HasValue && btnAlwaysOnTop.IsChecked.Value;
881 | }
882 |
883 |
884 | private void menuClose_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
885 | {
886 | //MessageBox.Show("menuClose_MouseLeftButtonUp");
887 | this.SavePropertiesAndClose(true);
888 | }
889 |
890 | private void menuCloseDontSave_Click(object sender, RoutedEventArgs e)
891 | {
892 | //MessageBox.Show("menuCloseDontSave_Click");
893 | this.SavePropertiesAndClose(false);
894 | }
895 |
896 | //private void menuCloseDontSave_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
897 | //{
898 | // MessageBox.Show("menuCloseDontSave_MouseLeftButtonUp");
899 | // m_window.SavePropertiesAndClose(false);
900 | //}
901 |
902 | //private void menuCloseDontSave_MouseEnter(object sender, MouseEventArgs e)
903 | //{
904 | // //menuClose.ReleaseMouseCapture();
905 | // //MessageBox.Show("menuCloseDontSave_MouseEnter");
906 | //}
907 |
908 | private void menuCloseSave_Click(object sender, RoutedEventArgs e)
909 | {
910 | //MessageBox.Show("menuCloseSave_Click");
911 | this.SavePropertiesAndClose(true);
912 | }
913 |
914 | private void Grid_MouseEnter(object sender, MouseEventArgs e)
915 | {
916 | m_timer.Interval = 50;
917 | m_taSlideIn.From = new Thickness(0, 0, 0, 0);
918 | m_sbAniIn.Begin(spWindowControlStackPanel);
919 |
920 | }
921 |
922 | private void Grid_MouseLeave(object sender, MouseEventArgs e)
923 | {
924 | m_timer.Interval = 1000;
925 | m_taSlideOut.To = new Thickness(0, 0, 0, 0);
926 | m_sbAniOut.Begin(spWindowControlStackPanel);
927 | }
928 |
929 | private void ThumbButtonPlay_Click(object sender, EventArgs e)
930 | {
931 | Resume();
932 | }
933 |
934 | private void ThumbButtonPause_Click(object sender, EventArgs e)
935 | {
936 | Pause();
937 | }
938 |
939 | private void ThumbButtonReset_Click(object sender, EventArgs e)
940 | {
941 | Reset();
942 | }
943 |
944 | private void ThumbButtonGoToWork_Click(object sender, EventArgs e)
945 | {
946 | StartWork();
947 | }
948 |
949 | private void ThumbButtonTakeABreak_Click(object sender, EventArgs e)
950 | {
951 | StartRelax();
952 | }
953 |
954 | private void Window_Activated(object sender, EventArgs e)
955 | {
956 | if (m_bIsOverTime && m_mode == TimerMode.MODE_WORK)
957 | SetWindowFlash(false);
958 | }
959 | }
960 | }
961 |
--------------------------------------------------------------------------------