-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
1,053 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.9.34701.34 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VdLabel", "VdLabel\VdLabel.csproj", "{550F365E-5537-4DEC-B4F4-9B3E4D904C05}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{550F365E-5537-4DEC-B4F4-9B3E4D904C05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{550F365E-5537-4DEC-B4F4-9B3E4D904C05}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{550F365E-5537-4DEC-B4F4-9B3E4D904C05}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{550F365E-5537-4DEC-B4F4-9B3E4D904C05}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {4FF2BCDC-3065-48AF-82B4-4682B342CCBF} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Application | ||
x:Class="VdLabel.App" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" | ||
ShutdownMode="OnMainWindowClose"> | ||
<Application.Resources> | ||
<ResourceDictionary> | ||
<ResourceDictionary.MergedDictionaries> | ||
<ui:ThemesDictionary Theme="Dark" /> | ||
<ui:ControlsDictionary /> | ||
<ResourceDictionary Source="pack://application:,,,/ColorPicker;component/Styles/DefaultColorPickerStyle.xaml" /> | ||
<ResourceDictionary Source="Themes/DefaultStyles.xaml" /> | ||
</ResourceDictionary.MergedDictionaries> | ||
</ResourceDictionary> | ||
</Application.Resources> | ||
</Application> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System.Windows; | ||
|
||
namespace VdLabel; | ||
|
||
/// <summary> | ||
/// Interaction logic for App.xaml | ||
/// </summary> | ||
public partial class App : Application | ||
{ | ||
public App() | ||
{ | ||
InitializeComponent(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System.Windows; | ||
|
||
[assembly: ThemeInfo( | ||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located | ||
//(used if a resource is not found in the page, | ||
// or application resource dictionaries) | ||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located | ||
//(used if a resource is not found in the page, | ||
// app, or any theme specific resource dictionaries) | ||
)] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using System.Drawing; | ||
|
||
namespace VdLabel; | ||
|
||
class Config | ||
{ | ||
public OverlayPosition Position { get; set; } = OverlayPosition.TopLeft; | ||
public double FontSize { get; set; } = 48; | ||
public Color Foreground { get; set; } = Color.WhiteSmoke; | ||
public Color Background { get; set; } = Color.FromArgb(0x0d1117); | ||
public double Duration { get; set; } = 2.5; | ||
public List<DesktopConfig> DesktopConfigs { get; init; } = []; | ||
} | ||
|
||
enum OverlayPosition | ||
{ | ||
Center, | ||
TopLeft, | ||
} | ||
|
||
record DesktopConfig | ||
{ | ||
public Guid Id { get; set; } | ||
public bool IsVisibleName { get; set; } = true; | ||
public string? Name { get; set; } | ||
public string? ImagePath { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using System.Drawing; | ||
using System.IO; | ||
using System.Text.Encodings.Web; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace VdLabel; | ||
|
||
interface IConfigStore | ||
{ | ||
event EventHandler? Saved; | ||
|
||
ValueTask<Config> Load(); | ||
ValueTask Save(Config? config = null); | ||
} | ||
|
||
class ConfigStore : IConfigStore | ||
{ | ||
private readonly string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "VdLabel", "config.json"); | ||
private static readonly JsonSerializerOptions options = new() | ||
{ | ||
Converters = { new ColorJsonConverter() }, | ||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, | ||
}; | ||
private Config? config; | ||
|
||
public event EventHandler? Saved; | ||
|
||
public ValueTask<Config> Load() | ||
{ | ||
if (File.Exists(this.path)) | ||
{ | ||
using var fs = File.OpenRead(this.path); | ||
this.config = JsonSerializer.Deserialize<Config>(fs, options); | ||
} | ||
return new(this.config ??= new Config() | ||
{ | ||
DesktopConfigs = { new() { Id = Guid.Empty } } | ||
}); | ||
} | ||
|
||
public ValueTask Save(Config? config = null) | ||
{ | ||
if (config is not null) | ||
{ | ||
this.config = config; | ||
} | ||
Directory.CreateDirectory(Path.GetDirectoryName(this.path)!); | ||
using (var fs = File.Create(this.path)) | ||
{ | ||
JsonSerializer.Serialize(fs, this.config, options); | ||
} | ||
this.Saved?.Invoke(this, EventArgs.Empty); | ||
return default; | ||
} | ||
|
||
private class ColorJsonConverter : JsonConverter<Color> | ||
{ | ||
public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | ||
=> ColorTranslator.FromHtml(reader.GetString()!); | ||
public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options) | ||
=> writer.WriteStringValue(ColorTranslator.ToHtml(value)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
using CommunityToolkit.Mvvm.ComponentModel; | ||
using CommunityToolkit.Mvvm.Input; | ||
using Microsoft.Win32; | ||
using System.Collections.ObjectModel; | ||
using System.Reflection; | ||
using Wpf.Ui; | ||
using Wpf.Ui.Extensions; | ||
|
||
namespace VdLabel; | ||
|
||
partial class MainViewModel : ObservableObject | ||
{ | ||
private readonly IConfigStore configStore; | ||
private readonly IContentDialogService dialogService; | ||
[ObservableProperty] | ||
private bool isBusy; | ||
|
||
[ObservableProperty] | ||
private Config? config; | ||
|
||
[ObservableProperty] | ||
private DesktopConfigViewModel? selectedDesktopConfig; | ||
|
||
[ObservableProperty] | ||
private bool isStartup; | ||
|
||
public ObservableCollection<DesktopConfigViewModel> DesktopConfigs { get; } = []; | ||
|
||
public IReadOnlyList<OverlayPosition> Positions { get; } = Enum.GetValues<OverlayPosition>(); | ||
|
||
public MainViewModel(IConfigStore configStore, IContentDialogService dialogService) | ||
{ | ||
this.configStore = configStore; | ||
this.dialogService = dialogService; | ||
this.isStartup = GetIsStartup(); | ||
Load(); | ||
} | ||
|
||
private async void Load() | ||
{ | ||
this.IsBusy = true; | ||
try | ||
{ | ||
this.Config = await this.configStore.Load(); | ||
this.DesktopConfigs.Clear(); | ||
foreach (var desktopConfig in this.Config.DesktopConfigs) | ||
{ | ||
this.DesktopConfigs.Add(new DesktopConfigViewModel(desktopConfig)); | ||
} | ||
this.SelectedDesktopConfig = this.DesktopConfigs.FirstOrDefault(); | ||
} | ||
finally | ||
{ | ||
this.IsBusy = false; | ||
} | ||
} | ||
|
||
[RelayCommand] | ||
public async Task Save() | ||
{ | ||
this.IsBusy = true; | ||
try | ||
{ | ||
this.Config!.DesktopConfigs.Clear(); | ||
foreach (var desktopConfig in this.DesktopConfigs) | ||
{ | ||
this.Config.DesktopConfigs.Add(desktopConfig.DesktopConfig); | ||
} | ||
await this.configStore.Save(this.Config); | ||
} | ||
finally | ||
{ | ||
this.IsBusy = false; | ||
} | ||
} | ||
|
||
partial void OnIsStartupChanged(bool value) | ||
{ | ||
var exe = Assembly.GetExecutingAssembly(); | ||
using var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true) ?? throw new InvalidOperationException(); | ||
var name = exe.GetName().Name ?? throw new InvalidOperationException(); | ||
var path = Environment.ProcessPath ?? throw new InvalidOperationException(); | ||
if (value) | ||
{ | ||
key.SetValue(name, exe.Location); | ||
this.dialogService.ShowAlertAsync("自動起動", $"{name}を自動起動に登録しました。", "OK"); | ||
} | ||
else | ||
{ | ||
key.DeleteValue(name, false); | ||
this.dialogService.ShowAlertAsync("自動起動", $"{name}の自動起動を解除しました。", "OK"); | ||
} | ||
} | ||
|
||
private static bool GetIsStartup() | ||
{ | ||
var exe = Assembly.GetExecutingAssembly(); | ||
using var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", false); | ||
string? name = exe.GetName().Name; | ||
return key?.GetValue(name) is { }; | ||
} | ||
} | ||
|
||
partial class DesktopConfigViewModel(DesktopConfig desktopConfig) : ObservableObject | ||
{ | ||
public DesktopConfig DesktopConfig { get; } = desktopConfig; | ||
|
||
public Guid Id => this.DesktopConfig.Id; | ||
|
||
public bool IsDefault => this.DesktopConfig.Id == Guid.Empty; | ||
|
||
public string Title => this.IsDefault ? "デフォルト設定" : this.DesktopConfig.Name ?? this.DesktopConfig.Id.ToString(); | ||
|
||
public bool IsVisibleName | ||
{ | ||
get => this.DesktopConfig.IsVisibleName; | ||
set => SetProperty(this.DesktopConfig.IsVisibleName, value, this.DesktopConfig, (c, v) => c.IsVisibleName = v); | ||
} | ||
|
||
public string? Name | ||
{ | ||
get => this.DesktopConfig.Name; | ||
set | ||
{ | ||
if (SetProperty(this.DesktopConfig.Name, value, this.DesktopConfig, (c, v) => c.Name = v)) | ||
{ | ||
OnPropertyChanged(nameof(Title)); | ||
} | ||
} | ||
} | ||
|
||
public string? ImagePath | ||
{ | ||
get => this.DesktopConfig.ImagePath; | ||
set | ||
{ | ||
if (SetProperty(this.DesktopConfig.ImagePath, value, this.DesktopConfig, (c, v) => c.ImagePath = v)) | ||
{ | ||
OnPropertyChanged(nameof(IsVisibleImage)); | ||
} | ||
} | ||
} | ||
|
||
public bool IsVisibleImage => this.ImagePath is not null; | ||
|
||
[RelayCommand] | ||
public void PickImage() | ||
{ | ||
var openFileDialog = new OpenFileDialog() | ||
{ | ||
DefaultDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), | ||
AddToRecent = true, | ||
CheckFileExists = true, | ||
ForcePreviewPane = true, | ||
Filter = "Image files (*.bmp;*.jpg;*.jpeg;*.png)|*.bmp;*.jpg;*.jpeg;*.png|All files (*.*)|*.*" | ||
}; | ||
|
||
if (openFileDialog.ShowDialog() != true) | ||
{ | ||
return; | ||
} | ||
|
||
this.ImagePath = openFileDialog.FileName; | ||
} | ||
} |
Oops, something went wrong.