├── Resources
├── 吊兰.png
├── 多肉.png
├── 绿箩.png
├── 青松.png
├── icon.ico
├── 仙人掌.png
├── 向日葵.png
└── iconfont.ttf
├── App.xaml.cs
├── HourMark.cs
├── README.md
├── AssemblyInfo.cs
├── BindingProxy.cs
├── Behaviors
├── GetTextFocusedBehavior.cs
├── DurationValidataRule.cs
├── ClickToChangeBgBehavior.cs
├── TimeInOrDeBehavior.cs
└── TimeButtonExtension.cs
├── Converters
├── RestTimesToStringConverter.cs
├── BoolToVisibilityReverseConverter.cs
├── BoolToVisibilityConverter.cs
└── RemainingTimeToStringConverter.cs
├── PomodoroTimer.sln
├── MainWindow.xaml.cs
├── PomodoroTimer.csproj
├── .gitattributes
├── .gitignore
├── WindowAccentCompositor.cs
├── MainWindowViewModel.cs
├── MainWindow.xaml
└── App.xaml
/Resources/吊兰.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hinadesu39/PomodoroTimer/HEAD/Resources/吊兰.png
--------------------------------------------------------------------------------
/Resources/多肉.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hinadesu39/PomodoroTimer/HEAD/Resources/多肉.png
--------------------------------------------------------------------------------
/Resources/绿箩.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hinadesu39/PomodoroTimer/HEAD/Resources/绿箩.png
--------------------------------------------------------------------------------
/Resources/青松.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hinadesu39/PomodoroTimer/HEAD/Resources/青松.png
--------------------------------------------------------------------------------
/Resources/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hinadesu39/PomodoroTimer/HEAD/Resources/icon.ico
--------------------------------------------------------------------------------
/Resources/仙人掌.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hinadesu39/PomodoroTimer/HEAD/Resources/仙人掌.png
--------------------------------------------------------------------------------
/Resources/向日葵.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hinadesu39/PomodoroTimer/HEAD/Resources/向日葵.png
--------------------------------------------------------------------------------
/Resources/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hinadesu39/PomodoroTimer/HEAD/Resources/iconfont.ttf
--------------------------------------------------------------------------------
/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Configuration;
2 | using System.Data;
3 | using System.Windows;
4 |
5 | namespace PomodoroTimer
6 | {
7 | ///
8 | /// Interaction logic for App.xaml
9 | ///
10 | public partial class App : Application
11 | {
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/HourMark.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Mvvm.ComponentModel;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows.Data;
8 | using System.Windows.Media;
9 |
10 | namespace PomodoroTimer
11 | {
12 | public partial class HourMark : ObservableObject
13 | {
14 | private LineGeometry data;
15 |
16 | public LineGeometry Data
17 | {
18 | get { return data; }
19 | set { data = value; }
20 | }
21 |
22 | [ObservableProperty]
23 | private bool isFill = false;
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PomodoroTimer
2 | ## 复刻win11原生专注工具
3 | 
4 | 
5 | 
6 | 
7 | 
8 |
--------------------------------------------------------------------------------
/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/BindingProxy.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 |
8 | namespace PomodoroTimer
9 | {
10 | public class BindingProxy : Freezable
11 | {
12 | public static readonly DependencyProperty ValueProperty =
13 | DependencyProperty.Register(
14 | nameof(Value),
15 | typeof(object),
16 | typeof(BindingProxy));
17 |
18 | public object Value
19 | {
20 | get => GetValue(ValueProperty);
21 | set => SetValue(ValueProperty, value);
22 | }
23 |
24 | protected override Freezable CreateInstanceCore()
25 | {
26 | return new BindingProxy();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Behaviors/GetTextFocusedBehavior.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Xaml.Behaviors;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Media;
10 |
11 | namespace PomodoroTimer.Behaviors
12 | {
13 | class GetTextFocusedBehavior : Behavior
14 | {
15 | protected override void OnAttached()
16 | {
17 | AssociatedObject.GotKeyboardFocus += SelectContents;
18 | }
19 | private void SelectContents(object sender, RoutedEventArgs e)
20 | {
21 | TextBox tb = (sender as TextBox);
22 | if (tb != null)
23 | {
24 | tb.SelectionBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#a94dc1"));
25 | tb.SelectAll();
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Converters/RestTimesToStringConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows.Data;
8 | using Windows.Web.Syndication;
9 |
10 | namespace PomodoroTimer.Converters
11 | {
12 | public class RestTimesToStringConverter : IValueConverter
13 | {
14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
15 | {
16 | int times;
17 | if(value != null && int.TryParse(value.ToString(),out times))
18 | {
19 | if(times == 0)
20 | {
21 | return "您将没有休息时间。";
22 | }
23 | else
24 | {
25 | return $"您将有{times}次休息时间。";
26 | }
27 | }
28 | return string.Empty;
29 | }
30 |
31 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
32 | {
33 | throw new NotImplementedException();
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Converters/BoolToVisibilityReverseConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Data;
9 |
10 | namespace PomodoroTimer.Converters
11 | {
12 | public class BoolToVisibilityReverseConverter : IValueConverter
13 | {
14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
15 | {
16 | bool isChecked;
17 | if (value != null && bool.TryParse(value.ToString(), out isChecked))
18 | {
19 | if (isChecked)
20 | {
21 | return Visibility.Collapsed;
22 | }
23 | else
24 | {
25 | return Visibility.Visible;
26 | }
27 | }
28 | return Visibility.Visible;
29 | }
30 |
31 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
32 | {
33 | throw new NotImplementedException();
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/PomodoroTimer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.9.34723.18
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PomodoroTimer", "PomodoroTimer.csproj", "{4671F198-386A-4CEB-9A0C-B0796000A4BB}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {4671F198-386A-4CEB-9A0C-B0796000A4BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {4671F198-386A-4CEB-9A0C-B0796000A4BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {4671F198-386A-4CEB-9A0C-B0796000A4BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {4671F198-386A-4CEB-9A0C-B0796000A4BB}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {810EDDEC-DB05-4D87-86B4-9CF1C597B3D7}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Converters/BoolToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Data;
9 |
10 | namespace PomodoroTimer.Converters
11 | {
12 | public class BoolToVisibilityConverter : IValueConverter
13 | {
14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
15 | {
16 | bool isChecked;
17 | if (value != null && bool.TryParse(value.ToString(), out isChecked))
18 | {
19 | if (isChecked)
20 | {
21 | return Visibility.Visible;
22 | }
23 | else
24 | {
25 | return Visibility.Collapsed;
26 | }
27 | }
28 | return Visibility.Collapsed;
29 | }
30 |
31 | public object ConvertBack(
32 | object value,
33 | Type targetType,
34 | object parameter,
35 | CultureInfo culture
36 | )
37 | {
38 | throw new NotImplementedException();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Behaviors/DurationValidataRule.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows.Controls;
8 |
9 | namespace PomodoroTimer.Behaviors
10 | {
11 | public class DurationValidataRule : ValidationRule
12 | {
13 | public int MaxDuration { get; set; } = 100;
14 | public int MinDuration { get; set; } = 0;
15 | public override ValidationResult Validate(object value, CultureInfo cultureInfo)
16 | {
17 | int currentDuration;
18 |
19 | if (int.TryParse(value.ToString(), out currentDuration))
20 | {
21 | if (currentDuration > MaxDuration)
22 | {
23 | return new ValidationResult(false, "DurationTooLong");
24 | }
25 | else if (currentDuration < MinDuration)
26 | {
27 | return new ValidationResult(false, "DurationTooShort");
28 | }
29 | return ValidationResult.ValidResult;
30 | }
31 | else
32 | {
33 | return new ValidationResult(false, "Duration Must be a int");
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Converters/RemainingTimeToStringConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows.Data;
8 |
9 | namespace PomodoroTimer.Converters
10 | {
11 | public class RemainingTimeToStringConverter : IValueConverter
12 | {
13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14 | {
15 | if (value != null)
16 | {
17 | var remainingTime = (TimeSpan)value;
18 | if (remainingTime == TimeSpan.FromMinutes(0))
19 | {
20 | return "完成";
21 | }
22 | else if(remainingTime < TimeSpan.FromMinutes(1))
23 | {
24 | return remainingTime.ToString("ss'秒'");
25 | }
26 | else
27 | {
28 | return remainingTime.ToString("mm'分'");
29 | }
30 | }
31 | return string.Empty;
32 | }
33 |
34 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
35 | {
36 | throw new NotImplementedException();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using System.Text;
3 | using System.Windows;
4 | using System.Windows.Controls;
5 | using System.Windows.Data;
6 | using System.Windows.Documents;
7 | using System.Windows.Input;
8 | using System.Windows.Media;
9 | using System.Windows.Media.Imaging;
10 | using System.Windows.Navigation;
11 | using System.Windows.Shapes;
12 |
13 | namespace PomodoroTimer
14 | {
15 | ///
16 | /// Interaction logic for MainWindow.xaml
17 | ///
18 | public partial class MainWindow : Window
19 | {
20 | public MainWindow()
21 | {
22 | InitializeComponent();
23 | Loaded += MainWindow_Loaded;
24 | TitleZone.MouseDown += (s, e) =>
25 | {
26 | if (e.LeftButton == MouseButtonState.Pressed)
27 | {
28 | this.DragMove();
29 | }
30 | };
31 | DragZone.MouseDown += (s, e) =>
32 | {
33 | if (e.LeftButton == MouseButtonState.Pressed)
34 | {
35 | this.DragMove();
36 | }
37 | };
38 | btn_Min.Click += (s, e) =>
39 | {
40 | this.WindowState = WindowState.Minimized;
41 | };
42 | }
43 | WindowAccentCompositor wac = null;
44 | private void MainWindow_Loaded(object sender, RoutedEventArgs e)
45 | {
46 | wac = new(this, false, (c) =>
47 | {
48 | //没有可用的模糊特效
49 | c.A = 255;
50 | Background = new SolidColorBrush(c);
51 | });
52 | //wac.Color = (bool)DarkModeCheck.IsChecked ? Color.FromArgb(180, 0, 0, 0) : Color.FromArgb(180, 255, 255, 255);
53 | wac.Color = Color.FromArgb(180, 0, 0, 0);
54 | wac.IsEnabled = true;
55 | }
56 |
57 |
58 | }
59 | }
--------------------------------------------------------------------------------
/Behaviors/ClickToChangeBgBehavior.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Xaml.Behaviors;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows;
11 | using System.Windows.Controls;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 |
15 | namespace PomodoroTimer.Behaviors
16 | {
17 | public class ClickToChangeBgBehavior : Behavior
18 | {
19 | private int bgIndex = 0;
20 | protected override void OnAttached()
21 | {
22 | AssociatedObject.Loaded += InitBg;
23 | AssociatedObject.MouseDown += ChangeBg;
24 | }
25 |
26 | private void InitBg(object sender, RoutedEventArgs e)
27 | {
28 | var bgList = AssociatedObject.Tag as ObservableCollection;
29 | if (bgList != null)
30 | {
31 | BitmapImage logo = new BitmapImage();
32 | logo.BeginInit();
33 | logo.UriSource = new Uri(bgList[bgIndex], UriKind.Relative);
34 | logo.EndInit();
35 | AssociatedObject.Source = logo;
36 | }
37 | }
38 |
39 | private void ChangeBg(object sender, System.Windows.Input.MouseButtonEventArgs e)
40 | {
41 | var bgList = AssociatedObject.Tag as ObservableCollection;
42 | if (bgList != null)
43 | {
44 | BitmapImage logo = new BitmapImage();
45 | logo.BeginInit();
46 | if (bgIndex == bgList.Count - 1)
47 | {
48 | bgIndex = 0;
49 | }
50 | else
51 | {
52 | bgIndex++;
53 | }
54 | logo.UriSource = new Uri(bgList[bgIndex], UriKind.Relative);
55 | logo.EndInit();
56 | AssociatedObject.Source = logo;
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/PomodoroTimer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net8.0-windows10.0.17763.0
6 | enable
7 | enable
8 | true
9 | Resources\icon.ico
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | PreserveNewest
35 |
36 |
37 | PreserveNewest
38 |
39 |
40 | PreserveNewest
41 |
42 |
43 | PreserveNewest
44 |
45 |
46 | PreserveNewest
47 |
48 |
49 | PreserveNewest
50 |
51 |
52 | PreserveNewest
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/Behaviors/TimeInOrDeBehavior.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Xaml.Behaviors;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 |
10 | namespace PomodoroTimer.Behaviors
11 | {
12 | class TimeInOrDeBehavior : Behavior