Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/Localization/Locals.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/Localization/Locals.en.resx
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,12 @@
<data name="MinimizeToTrayIconToolTip" xml:space="preserve">
<value>Show a tray icon when Log Viewer is minimized.</value>
</data>
<data name="StartMaximized" xml:space="preserve">
<value>Start in fullscreen mode:</value>
</data>
<data name="StartMaximizedToolTip" xml:space="preserve">
<value>When off, the application starts in a normal window instead of maximized.</value>
</data>
<data name="OnlyOneInstanceOfApp" xml:space="preserve">
<value>Only one application instance:</value>
</data>
Expand Down
6 changes: 6 additions & 0 deletions src/Localization/Locals.resx
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,12 @@
<data name="MinimizeToTrayIconToolTip" xml:space="preserve">
<value>Показывать иконку в трее при сворачивании приложения</value>
</data>
<data name="StartMaximized" xml:space="preserve">
<value>Запускать в полноэкранном режиме:</value>
</data>
<data name="StartMaximizedToolTip" xml:space="preserve">
<value>Если выключено, приложение запускается в обычном окне, а не развёрнутым на весь экран</value>
</data>
<data name="NoReceiversMessageBoxInfo" xml:space="preserve">
<value>Не добавлено ни одного сетевого приёмника.
Добавьте хотя бы один сетевой приёмник в настройках.</value>
Expand Down
7 changes: 7 additions & 0 deletions src/MVVM/Models/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ public sealed class Settings : ISerializable

public bool AutoStartInStartup { get; set; } = false;
public bool MinimizeToTray { get; set; } = false;

/// <summary>
/// Start the main window maximized. Missing value in old settings.xml keeps the default (true),
/// matching the behavior before this setting existed.
/// </summary>
public bool StartMaximized { get; set; } = true;
public bool OnlyOneAppInstance { get; set; } = false;
public bool IsEnabledMaxMessageBufferSize { get; set; } = false;
public int MaxMessageBufferSize { get; set; } = 1000000;
Expand Down Expand Up @@ -193,6 +199,7 @@ public void Load()
{
Instance.AutoStartInStartup = settings.AutoStartInStartup;
Instance.MinimizeToTray = settings.MinimizeToTray;
Instance.StartMaximized = settings.StartMaximized;
Instance.CurrentTheme = settings.CurrentTheme;
Instance.DataFormat = settings.DataFormat;
Instance.IgnoredIPs = settings.IgnoredIPs;
Expand Down
16 changes: 16 additions & 0 deletions src/MVVM/ViewModels/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class SettingsViewModel : BaseViewModel
private bool isConfigurationVisible = false;
private bool isAutoStartReadAtStartup = true;
private bool minimizeToTray = false;
private bool startMaximized = true;
private bool isEnableMaxMessageBufferSize = false;
private bool onlyOneAppInstance = true;
private Receiver selectedReceiver;
Expand Down Expand Up @@ -107,6 +108,19 @@ public bool MinimizeToTray
}


/// <summary>
/// Start the main window maximized.
/// </summary>
public bool StartMaximized
{
get => startMaximized;
set
{
startMaximized = value;
OnPropertyChanged();
}
}

/// <summary>
/// Honor the maximum message buffer size.
/// </summary>
Expand Down Expand Up @@ -566,6 +580,7 @@ public SettingsViewModel()
IgnoredIpAdresses = new ObservableCollection<IgnoredIPAddress>(Settings.Instance.IgnoredIPs);
IsAutoStartReadAtStartup = Settings.Instance.AutoStartInStartup;
MinimizeToTray = Settings.Instance.MinimizeToTray;
StartMaximized = Settings.Instance.StartMaximized;
OnlyOneAppInstance = Settings.Instance.OnlyOneAppInstance;
CheckForUpdatesOnStartup = Settings.Instance.CheckForUpdatesOnStartup;
SelectedDataFormat = Settings.Instance.DataFormat;
Expand Down Expand Up @@ -701,6 +716,7 @@ private void Save(object obj)

Settings.Instance.MinimizeToTray = MinimizeToTray;
Settings.Instance.AutoStartInStartup = IsAutoStartReadAtStartup;
Settings.Instance.StartMaximized = StartMaximized;
Settings.Instance.IsShowSourceColumn = IsShowSourceColumn;
Settings.Instance.IsShowThreadColumn = IsShowThreadColumn;
Settings.Instance.IsShowTaskbarProgress = IsShowTaskbarProgress;
Expand Down
2 changes: 1 addition & 1 deletion src/MVVM/Views/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
xmlns:viewModels="clr-namespace:LogViewer.MVVM.ViewModels"
xmlns:localization="clr-namespace:LogViewer.Localization"
mc:Ignorable="d"
Title="Log Viewer" Height="1080" Width="1920" WindowState="Maximized" Loaded="MainWindow_OnLoaded"
Title="Log Viewer" Height="1080" Width="1920" WindowStartupLocation="CenterScreen" Loaded="MainWindow_OnLoaded"
AllowDrop="True" DragOver="Window_OnDragOver" Drop="Window_OnDrop">
<Window.DataContext>
<viewModels:LogViewModel/>
Expand Down
39 changes: 38 additions & 1 deletion src/MVVM/Views/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ public partial class MainWindow : Window, IDisposable
public MainWindow()
{
InitializeComponent();
if (!Settings.Instance.StartMaximized)
{
WindowStartupLocation = WindowStartupLocation.Manual;
CenterNormalWindow(Screen.FromPoint(System.Windows.Forms.Cursor.Position));
}
WindowState = Settings.Instance.StartMaximized ? WindowState.Maximized : WindowState.Normal;
UpdateAutoScrollChrome();
logsViewKeeper = new ListViewViewKeeper(LogsListView, () => AutoScrollEnabled);
TranslationSource.Instance.LanguageChanged += (_, __) => UpdateAutoScrollChrome();
Expand Down Expand Up @@ -99,6 +105,9 @@ private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
/// </summary>
protected override void OnStateChanged(EventArgs e)
{
if (WindowState == WindowState.Normal && IsLoaded)
CenterNormalWindow();

if (WindowState == WindowState.Minimized && Settings.Instance.MinimizeToTray)
{
if (trayIcon == null)
Expand Down Expand Up @@ -128,6 +137,34 @@ protected override void OnStateChanged(EventArgs e)
base.OnStateChanged(e);
}

private void CenterNormalWindow(Screen screen = null)
{
var workArea = GetWorkArea(screen ?? Screen.FromHandle(new WindowInteropHelper(this).Handle));

Width = Math.Min(Width, workArea.Width);
Height = Math.Min(Height, workArea.Height);
Left = workArea.Left + (workArea.Width - Width) / 2;
Top = workArea.Top + (workArea.Height - Height) / 2;
}

private Rect GetWorkArea(Screen screen)
{
var source = PresentationSource.FromVisual(this);
// Screen coordinates are physical pixels; WPF window bounds use device-independent units.
var transform = source?.CompositionTarget?.TransformFromDevice;
if (!transform.HasValue)
{
// Before HWND creation, use the system DPI used by this WPF application.
using (var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
transform = new System.Windows.Media.Matrix(96.0 / graphics.DpiX, 0, 0, 96.0 / graphics.DpiY, 0, 0);
}

var workArea = screen.WorkingArea;
var topLeft = transform.Value.Transform(new Point(workArea.Left, workArea.Top));
var bottomRight = transform.Value.Transform(new Point(workArea.Right, workArea.Bottom));
return new Rect(topLeft, bottomRight);
}

private void TrayIconContextMenuClick(object sender, ToolStripItemClickedEventArgs e)
{
switch (e.ClickedItem.Text)
Expand Down Expand Up @@ -555,4 +592,4 @@ public void Dispose()
trayIcon?.Dispose();
}
}
}
}
Loading