Compare commits

...
5 Commits
16 changed files with 423 additions and 31 deletions
@@ -6,6 +6,10 @@ namespace Daybreak.Configuration
{
public sealed class ApplicationConfiguration
{
[JsonProperty("SetGuildwarsWindowSizeOnLaunch")]
public bool SetGuildwarsWindowSizeOnLaunch { get; set; }
[JsonProperty("DesiredGuildwarsScreen")]
public int DesiredGuildwarsScreen { get; set; }
[JsonProperty("BrowsersEnabled")]
public bool BrowsersEnabled { get; set; } = true;
[JsonProperty("ToolboxPath")]
@@ -9,6 +9,7 @@ using Daybreak.Services.Logging;
using Daybreak.Services.Mutex;
using Daybreak.Services.Privilege;
using Daybreak.Services.Runtime;
using Daybreak.Services.Screens;
using Daybreak.Services.Screenshots;
using Daybreak.Services.Updater;
using Daybreak.Services.ViewManagement;
@@ -39,6 +40,7 @@ namespace Daybreak.Configuration
serviceProducer.RegisterSingleton<IBuildTemplateManager, BuildTemplateManager>();
serviceProducer.RegisterSingleton<IIconRetriever, IconRetriever>();
serviceProducer.RegisterSingleton<IPrivilegeManager, PrivilegeManager>();
serviceProducer.RegisterSingleton<IScreenManager, ScreenManager>();
}
public static void RegisterLifetimeServices(IApplicationLifetimeProducer applicationLifetimeProducer)
{
@@ -63,6 +65,7 @@ namespace Daybreak.Configuration
viewProducer.RegisterView<BuildTemplateView>();
viewProducer.RegisterView<BuildsListView>();
viewProducer.RegisterView<RequestElevationView>();
viewProducer.RegisterView<ScreenChoiceView>();
}
}
}
@@ -0,0 +1,17 @@
<UserControl x:Class="Daybreak.Controls.Templates.ScreenTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Controls.Templates"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Rectangle Stroke="{Binding ElementName=_this, Path=Highlight, Mode=OneWay}" StrokeThickness="15"></Rectangle>
<TextBlock FontSize="168" VerticalAlignment="Center" HorizontalAlignment="Center"
Text="{Binding ElementName=_this, Path=ScreenId, Mode=OneWay}"
Foreground="{Binding ElementName=_this, Path=Highlight, Mode=OneWay}"></TextBlock>
<Rectangle Fill="Transparent" MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"></Rectangle>
</Grid>
</UserControl>
@@ -0,0 +1,73 @@
using Daybreak.Models;
using System;
using System.Extensions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
using System.Windows.Media;
namespace Daybreak.Controls.Templates
{
/// <summary>
/// Interaction logic for ScreenTemplate.xaml
/// </summary>
public partial class ScreenTemplate : UserControl
{
public static readonly DependencyProperty ScreenIdProperty =
DependencyPropertyExtensions.Register<ScreenTemplate, string>(nameof(ScreenId));
public static readonly DependencyProperty HighlightProperty =
DependencyPropertyExtensions.Register<ScreenTemplate, Brush>(nameof(Highlight));
public event EventHandler<Screen> Clicked;
public string ScreenId
{
get => this.GetTypedValue<string>(ScreenIdProperty);
set => this.SetValue(ScreenIdProperty, value);
}
public Brush Highlight
{
get => this.GetTypedValue<Brush>(HighlightProperty);
set => this.SetValue(HighlightProperty, value);
}
public ScreenTemplate()
{
this.InitializeComponent();
this.DataContextChanged += ScreenTemplate_DataContextChanged;
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == ForegroundProperty)
{
this.Highlight = e.NewValue.As<Brush>();
}
}
private void ScreenTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is Screen screen)
{
this.ScreenId = screen.Id.ToString();
}
}
private void Rectangle_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Highlight = Brushes.LightSteelBlue;
}
private void Rectangle_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Highlight = this.Foreground;
}
private void Rectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
this.Clicked?.Invoke(this, this.DataContext.As<Screen>());
}
}
}
+1 -1
View File
@@ -9,7 +9,7 @@
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
<LangVersion>preview</LangVersion>
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
<Version>0.8.1</Version>
<Version>0.8.4</Version>
</PropertyGroup>
<ItemGroup>
+10
View File
@@ -0,0 +1,10 @@
using System.Windows;
namespace Daybreak.Models
{
public sealed class Screen
{
public int Id { get; set; }
public Rect Size { get; set; }
}
}
@@ -23,6 +23,7 @@ namespace Daybreak.Services.ApplicationLauncher
{
public class ApplicationLauncher : IApplicationLauncher
{
private const int MaxRetries = 10;
private const string TexModProcessName = "TexMod";
private const string UModProcessName = "uMod";
private const string ToolboxProcessName = "GWToolbox";
@@ -53,30 +54,31 @@ namespace Daybreak.Services.ApplicationLauncher
this.privilegeManager = privilegeManager.ThrowIfNull(nameof(privilegeManager));
}
public async Task LaunchGuildwars()
public async Task<bool> LaunchGuildwars()
{
var configuration = this.configurationManager.GetConfiguration();
var auth = await this.credentialManager.GetDefaultCredentials().ConfigureAwait(false);
auth.Do(
onSome: (credentials) =>
return await auth.Switch(
onSome: async (credentials) =>
{
if (configuration.ExperimentalFeatures.MultiLaunchSupport is true)
{
if (this.privilegeManager.AdminPrivileges is false)
{
this.privilegeManager.RequestAdminPrivileges<MainView>("You need administrator rights in order to start using multi-launch");
return;
return false;
}
ClearGwLocks();
}
LaunchGuildwarsProcess(credentials.Username, credentials.Password, credentials.CharacterName);
return await LaunchGuildwarsProcess(credentials.Username, credentials.Password, credentials.CharacterName);
},
onNone: () =>
{
throw new CredentialsNotFoundException($"No credentials available");
});
})
.ExtractValue();
}
public Task LaunchGuildwarsToolbox()
@@ -142,7 +144,7 @@ namespace Daybreak.Services.ApplicationLauncher
Application.Current.Shutdown();
}
private void LaunchGuildwarsProcess(string email, Models.SecureString password, string character)
private async Task<bool> LaunchGuildwarsProcess(string email, Models.SecureString password, string character)
{
var executable = this.configurationManager.GetConfiguration().GuildwarsPaths.Where(path => path.Default).FirstOrDefault();
if (executable is null)
@@ -184,6 +186,38 @@ namespace Daybreak.Services.ApplicationLauncher
{
throw new InvalidOperationException($"Unable to launch {executable}");
}
var retries = 0;
while (true)
{
await Task.Delay(100);
retries++;
var gwProcess = Process.GetProcessesByName("gw").FirstOrDefault();
if (gwProcess is null && retries < MaxRetries)
{
continue;
}
else if (gwProcess is null && retries >= MaxRetries)
{
throw new InvalidOperationException("Newly launched gw process not detected");
}
if (gwProcess.MainWindowHandle == IntPtr.Zero)
{
continue;
}
int titleLength = NativeMethods.GetWindowTextLength(gwProcess.MainWindowHandle);
var titleBuffer = new StringBuilder(titleLength);
var readCount = NativeMethods.GetWindowText(gwProcess.MainWindowHandle, titleBuffer, titleLength + 1);
var title = titleBuffer.ToString();
if (title != "Guild Wars")
{
continue;
}
return true;
}
}
private bool GuildwarsProcessDetected()
@@ -7,7 +7,7 @@ namespace Daybreak.Services.ApplicationLauncher
bool IsGuildwarsRunning { get; }
bool IsToolboxRunning { get; }
bool IsTexmodRunning { get; }
Task LaunchGuildwars();
Task<bool> LaunchGuildwars();
Task LaunchGuildwarsToolbox();
Task LaunchTexmod();
void RestartDaybreakAsAdmin();
@@ -0,0 +1,11 @@
using Daybreak.Models;
using System.Collections.Generic;
namespace Daybreak.Services.Screens
{
public interface IScreenManager
{
IEnumerable<Screen> Screens { get; }
void MoveGuildwarsToScreen(Screen screen);
}
}
@@ -0,0 +1,39 @@
using Daybreak.Models;
using Daybreak.Services.Logging;
using Daybreak.Utils;
using Pepa.Wpf.Utilities;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Extensions;
using System.Linq;
namespace Daybreak.Services.Screens
{
public sealed class ScreenManager : IScreenManager
{
private readonly ILogger logger;
public IEnumerable<Screen> Screens { get; } = WpfScreenHelper.Screen.AllScreens
.Select((screen, index) => new Screen { Id = index, Size = screen.Bounds });
public ScreenManager(
ILogger logger)
{
this.logger = logger.ThrowIfNull(nameof(logger));
}
public void MoveGuildwarsToScreen(Screen screen)
{
this.logger.LogInformation($"Attempting to move guildwars to screen {screen.Id}");
var hwnd = GetMainWindowHandle();
NativeMethods.SetWindowPos(hwnd, NativeMethods.HWND_TOP, screen.Size.Left.ToInt(), screen.Size.Top.ToInt(), screen.Size.Width.ToInt(), screen.Size.Height.ToInt(), NativeMethods.SWP_SHOWWINDOW);
}
private static IntPtr GetMainWindowHandle()
{
var process = Process.GetProcessesByName("gw").FirstOrDefault();
return process is not null ? process.MainWindowHandle : throw new InvalidOperationException("Could not find guildwars process");
}
}
}
+12
View File
@@ -7,6 +7,10 @@ namespace Pepa.Wpf.Utilities
{
static class NativeMethods
{
public static uint SWP_SHOWWINDOW = 0x0040;
public static IntPtr HWND_TOPMOST = new(-1);
public static IntPtr HWND_TOP = IntPtr.Zero;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SystemHandleInformation
{
@@ -105,5 +109,13 @@ namespace Pepa.Wpf.Utilities
public static extern NtStatus NtQuerySystemInformation(SystemInformationClass SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, out int ReturnLength);
[DllImport("kernel32.dll")]
public static extern bool QueryFullProcessImageName(IntPtr hProcess, uint dwFlags, StringBuilder lpExeName, ref uint lpdwSize);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hwnd, IntPtr insertAfter, int x, int y, int cx, int cy, uint flags);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hwnd, int cmd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
}
}
+23 -2
View File
@@ -2,9 +2,11 @@
using Daybreak.Models.Builds;
using Daybreak.Services.ApplicationLauncher;
using Daybreak.Services.Configuration;
using Daybreak.Services.Screens;
using Daybreak.Services.ViewManagement;
using System;
using System.Extensions;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
@@ -40,6 +42,7 @@ namespace Daybreak.Views
private readonly IApplicationLauncher applicationDetector;
private readonly IViewManager viewManager;
private readonly IConfigurationManager configurationManager;
private readonly IScreenManager screenManager;
private readonly CancellationTokenSource cancellationTokenSource = new();
private bool leftBrowserMaximized = false;
@@ -94,8 +97,10 @@ namespace Daybreak.Views
public MainView(
IApplicationLauncher applicationDetector,
IViewManager viewManager,
IConfigurationManager configurationManager)
IConfigurationManager configurationManager,
IScreenManager screenManager)
{
this.screenManager = screenManager.ThrowIfNull(nameof(screenManager));
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
this.applicationDetector = applicationDetector.ThrowIfNull(nameof(applicationDetector));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
@@ -145,7 +150,23 @@ namespace Daybreak.Views
{
try
{
await this.applicationDetector.LaunchGuildwars();
if (await this.applicationDetector.LaunchGuildwars() is false)
{
return;
}
if (this.configurationManager.GetConfiguration().SetGuildwarsWindowSizeOnLaunch)
{
var id = this.configurationManager.GetConfiguration().DesiredGuildwarsScreen;
var desiredScreen = this.screenManager.Screens.Skip(id).FirstOrDefault();
if (desiredScreen is null)
{
throw new InvalidOperationException($"Unable to set guildwars on desired screen. No screen with id {id}");
}
await Task.Delay(1000);
this.screenManager.MoveGuildwarsToScreen(desiredScreen);
}
if (this.configurationManager.GetConfiguration().ToolboxAutoLaunch is true)
{
var delay = this.configurationManager.GetConfiguration().ExperimentalFeatures.ToolboxAutoLaunchDelay;
+28
View File
@@ -0,0 +1,28 @@
<UserControl x:Class="Daybreak.Views.ScreenChoiceView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Views"
xmlns:controls="clr-namespace:Daybreak.Controls"
mc:Ignorable="d"
x:Name="_this"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="#A0202020">
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<controls:BackButton Foreground="White" Height="30" Width="30" Grid.Column="0" HorizontalAlignment="Left" Margin="5"
Clicked="BackButton_Clicked"></controls:BackButton>
<TextBlock Text="Choose screen" FontSize="18" Foreground="White" HorizontalAlignment="Center"></TextBlock>
<controls:OpaqueButton Text="Test" Foreground="White" HighlightOpacity="0.3" Highlight="White" FontSize="18" Width="80"
HorizontalAlignment="Right" Margin="0, 0, 50, 0" Clicked="OpaqueButton_Clicked"
IsEnabled="{Binding ElementName=_this, Path=CanTest, Mode=OneWay}"></controls:OpaqueButton>
<controls:SaveButton Foreground="White" Height="30" Width="30" Grid.Column="1" HorizontalAlignment="Right" Margin="5"
Clicked="SaveButton_Clicked"></controls:SaveButton>
<Viewbox Grid.Row="1">
<Grid x:Name="ScreenContainer"></Grid>
</Viewbox>
</Grid>
</UserControl>
+108
View File
@@ -0,0 +1,108 @@
using Daybreak.Controls.Templates;
using Daybreak.Models;
using Daybreak.Services.ApplicationLauncher;
using Daybreak.Services.Configuration;
using Daybreak.Services.Screens;
using Daybreak.Services.ViewManagement;
using System;
using System.Extensions;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Extensions;
using System.Windows.Media;
namespace Daybreak.Views
{
/// <summary>
/// Interaction logic for ScreenChoiceView.xaml
/// </summary>
public partial class ScreenChoiceView : UserControl
{
public static readonly DependencyProperty CanTestProperty =
DependencyPropertyExtensions.Register<ScreenChoiceView, bool>(nameof(CanTest));
private readonly IScreenManager screenManager;
private readonly IViewManager viewManager;
private readonly IConfigurationManager configurationManager;
private readonly IApplicationLauncher applicationLauncher;
private int selectedId;
public bool CanTest
{
get => this.GetTypedValue<bool>(CanTestProperty);
set => this.SetValue(CanTestProperty, value);
}
public ScreenChoiceView(
IViewManager viewManager,
IScreenManager screenManager,
IConfigurationManager configurationManager,
IApplicationLauncher applicationLauncher)
{
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
this.screenManager = screenManager.ThrowIfNull(nameof(screenManager));
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
this.applicationLauncher = applicationLauncher.ThrowIfNull(nameof(applicationLauncher));
this.InitializeComponent();
this.selectedId = configurationManager.GetConfiguration().DesiredGuildwarsScreen;
this.CanTest = applicationLauncher.IsGuildwarsRunning;
this.SetupView();
}
private void SetupView()
{
foreach(var screen in this.screenManager.Screens)
{
var screenTemplate = new ScreenTemplate
{
DataContext = screen,
Margin = new System.Windows.Thickness(screen.Size.Left, screen.Size.Top, 0, 0),
Width = screen.Size.Width,
Height = screen.Size.Height,
VerticalAlignment = System.Windows.VerticalAlignment.Top,
HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
Foreground = screen.Id == this.selectedId ? Brushes.LightGreen : Brushes.White
};
screenTemplate.Clicked += ScreenTemplate_Clicked;
this.ScreenContainer.Children.Add(screenTemplate);
}
}
private void ScreenTemplate_Clicked(object sender, Screen e)
{
this.SelectScreen(e);
}
private void SelectScreen(Screen screen)
{
this.selectedId = screen.Id;
foreach(var template in this.ScreenContainer.Children.OfType<ScreenTemplate>())
{
template.Foreground = template.DataContext.As<Screen>().Id == this.selectedId ? Brushes.LightGreen : Brushes.White;
}
}
private void BackButton_Clicked(object sender, EventArgs e)
{
this.viewManager.ShowView<SettingsView>();
}
private void SaveButton_Clicked(object sender, EventArgs e)
{
this.configurationManager.GetConfiguration().DesiredGuildwarsScreen = this.selectedId;
this.viewManager.ShowView<SettingsCategoryView>();
}
private void OpaqueButton_Clicked(object sender, EventArgs e)
{
var screen = this.screenManager.Screens.Skip(this.selectedId).FirstOrDefault();
if (screen is null)
{
throw new InvalidOperationException($"Unable to test placement. No screen with id {this.selectedId}");
}
this.screenManager.MoveGuildwarsToScreen(screen);
}
}
}
+24 -13
View File
@@ -81,19 +81,21 @@
<controls:SaveButton Foreground="White" Height="30" Width="30" Grid.Column="1" HorizontalAlignment="Right" Margin="5"
Clicked="SaveButton_Clicked"></controls:SaveButton>
<StackPanel Orientation="Vertical" Grid.Row="1">
<TextBlock Text="Texmod path" FontSize="22" Foreground="White"></TextBlock>
<TextBlock Text="GWToolbox path: " FontSize="22" Foreground="White"></TextBlock>
<TextBlock Text="GWToolbox auto-launch: " FontSize="22" Foreground="White"></TextBlock>
<TextBlock Text="Browsers enabled: " FontSize="22" Foreground="White"/>
<TextBlock Text="Browsers address bar readonly: " FontSize="22" Foreground="White"/>
<TextBlock Text="Left browser homepage: " FontSize="22" Foreground="White"></TextBlock>
<TextBlock Text="Right browser homepage: " FontSize="22" Foreground="White"></TextBlock>
<TextBlock Text="Texmod path" FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="GWToolbox path: " FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="GWToolbox auto-launch: " FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="Browsers enabled: " FontSize="22" Foreground="White" Height="30"/>
<TextBlock Text="Browsers address bar readonly: " FontSize="22" Foreground="White" Height="30"/>
<TextBlock Text="Left browser homepage: " FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="Right browser homepage: " FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="Auto-place on desired screen: " FontSize="22" Foreground="White" Height="30"></TextBlock>
<TextBlock Text="Desired screen id: " FontSize="22" Foreground="White" Height="30"></TextBlock>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="1">
<Grid>
<TextBox HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
FontSize="22" Margin="0, 0, 30, 0" Background="Transparent" Foreground="White"
Text="{Binding ElementName=_this, Path=TexmodPath, Mode=TwoWay}"></TextBox>
Text="{Binding ElementName=_this, Path=TexmodPath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<controls:FilePickerGlyph Height="30" Width="30" HorizontalAlignment="Right"
Foreground="White" BorderBrush="Gray" BorderThickness="0"
Clicked="TexmodFilePickerGlyph_Clicked"></controls:FilePickerGlyph>
@@ -101,7 +103,7 @@
<Grid>
<TextBox HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
FontSize="22" Margin="0, 0, 30, 0" Background="Transparent" Foreground="White"
Text="{Binding ElementName=_this, Path=ToolboxPath, Mode=TwoWay}"></TextBox>
Text="{Binding ElementName=_this, Path=ToolboxPath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<controls:FilePickerGlyph Height="30" Width="30" HorizontalAlignment="Right"
Foreground="White" BorderBrush="Gray" BorderThickness="0"
Clicked="ToolboxFilePickerGlyph_Clicked"></controls:FilePickerGlyph>
@@ -114,12 +116,21 @@
FontSize="22" Foreground="White" IsChecked="{Binding ElementName=_this, Path=AddressBarReadonly, Mode=TwoWay}"></ToggleButton>
<TextBox HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
FontSize="22" Background="Transparent" Foreground="White"
Text="{Binding ElementName=_this, Path=LeftBrowserUrl, Mode=TwoWay}"
TextChanged="LeftBrowserUrl_TextChanged"></TextBox>
Text="{Binding ElementName=_this, Path=LeftBrowserUrl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<TextBox HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
FontSize="22" Background="Transparent" Foreground="White"
Text="{Binding ElementName=_this, Path=RightBrowserUrl, Mode=TwoWay}"
TextChanged="RightBrowserUrl_TextChanged"></TextBox>
Text="{Binding ElementName=_this, Path=RightBrowserUrl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<ToggleButton HorizontalAlignment="Center" HorizontalContentAlignment="Stretch" Style="{StaticResource AnimatedSwitch}" Height="30" Width="40"
FontSize="22" Foreground="White" IsChecked="{Binding ElementName=_this, Path=AutoPlaceOnScreen, Mode=TwoWay}"></ToggleButton>
<Grid>
<TextBox HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
FontSize="22" Background="Transparent" Foreground="White"
Text="{Binding ElementName=_this, Path=DesiredScreen, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
PreviewTextInput="TextBox_AllowOnlyNumbers" Margin="0, 0, 30, 0"></TextBox>
<controls:FilePickerGlyph Height="30" Width="30" HorizontalAlignment="Right"
Foreground="White" BorderBrush="Gray" BorderThickness="0"
Clicked="ScreenPickerGlyph_Clicked"></controls:FilePickerGlyph>
</Grid>
</StackPanel>
</Grid>
</UserControl>
+28 -7
View File
@@ -28,6 +28,10 @@ namespace Daybreak.Views
DependencyPropertyExtensions.Register<SettingsView, string>(nameof(RightBrowserUrl));
public static readonly DependencyProperty ToolboxAutoLaunchProperty =
DependencyPropertyExtensions.Register<SettingsView, bool>(nameof(ToolboxAutoLaunch));
public static readonly DependencyProperty AutoPlaceOnScreenProperty =
DependencyPropertyExtensions.Register<SettingsView, bool>(nameof(AutoPlaceOnScreen));
public static readonly DependencyProperty DesiredScreenProperty =
DependencyPropertyExtensions.Register<SettingsView, string>(nameof(DesiredScreen));
private readonly IConfigurationManager configurationManager;
private readonly IViewManager viewManager;
@@ -67,6 +71,16 @@ namespace Daybreak.Views
get => this.GetTypedValue<bool>(BrowsersEnabledProperty);
set => this.SetValue(BrowsersEnabledProperty, value);
}
public bool AutoPlaceOnScreen
{
get => this.GetTypedValue<bool>(AutoPlaceOnScreenProperty);
set => this.SetValue(AutoPlaceOnScreenProperty, value);
}
public string DesiredScreen
{
get => this.GetTypedValue<string>(DesiredScreenProperty);
set => this.SetValue(DesiredScreenProperty, value);
}
public SettingsView(
IConfigurationManager configurationManager,
@@ -88,6 +102,8 @@ namespace Daybreak.Views
this.ToolboxAutoLaunch = config.ToolboxAutoLaunch;
this.TexmodPath = config.TexmodPath;
this.BrowsersEnabled = config.BrowsersEnabled;
this.AutoPlaceOnScreen = config.SetGuildwarsWindowSizeOnLaunch;
this.DesiredScreen = config.DesiredGuildwarsScreen.ToString();
}
private void SaveButton_Clicked(object sender, EventArgs e)
@@ -100,6 +116,8 @@ namespace Daybreak.Views
currentConfig.ToolboxAutoLaunch = this.ToolboxAutoLaunch;
currentConfig.TexmodPath = this.TexmodPath;
currentConfig.BrowsersEnabled = this.BrowsersEnabled;
currentConfig.SetGuildwarsWindowSizeOnLaunch = this.AutoPlaceOnScreen;
currentConfig.DesiredGuildwarsScreen = int.Parse(this.DesiredScreen);
this.configurationManager.SaveConfiguration(currentConfig);
this.viewManager.ShowView<SettingsCategoryView>();
}
@@ -134,19 +152,22 @@ namespace Daybreak.Views
}
}
private void ScreenPickerGlyph_Clicked(object sender, EventArgs e)
{
this.viewManager.ShowView<ScreenChoiceView>();
}
private void BackButton_Clicked(object sender, EventArgs e)
{
this.viewManager.ShowView<SettingsCategoryView>();
}
private void LeftBrowserUrl_TextChanged(object sender, TextChangedEventArgs e)
private void TextBox_AllowOnlyNumbers(object sender, System.Windows.Input.TextCompositionEventArgs e)
{
this.LeftBrowserUrl = sender.As<TextBox>().Text;
}
private void RightBrowserUrl_TextChanged(object sender, TextChangedEventArgs e)
{
this.RightBrowserUrl = sender.As<TextBox>().Text;
if (int.TryParse(e.Text, out _) is false)
{
e.Handled = true;
}
}
}
}