Skip to content
Draft
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
109 changes: 70 additions & 39 deletions src/View/Window/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@
Foreground="{DynamicResource SecondaryForeground}"
Icon="/WinMemoryCleaner;component/Resources/Images/win-memory-cleaner.ico"
MouseDown="OnWindowMouseDown"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
Height="700"
MinHeight="440"
MinWidth="680"
ResizeMode="CanResizeWithGrip"
SizeToContent="Manual"
Width="960"
SnapsToDevicePixels="True"
Title="{x:Static local:Constants+App.Title}"
Topmost="{Binding AlwaysOnTop}"
Expand All @@ -27,9 +31,15 @@
BorderThickness="1"
CornerRadius="8"
IsEnabled="{Binding IsBusy, Converter={StaticResource InverseBooleanConverter}, FallbackValue=True}">
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Header -->
<Grid Margin="10, 10, 0, 0">
<Grid Grid.Row="0"
Margin="10, 10, 0, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
Expand Down Expand Up @@ -193,23 +203,31 @@
</StackPanel>
</Grid>
<!-- Content -->
<Grid Margin="10, 0, 10, 0"
Visibility="{Binding CompactMode, Converter={StaticResource InverseBooleanToVisibilityConverter}, FallbackValue={x:Static Visibility.Visible}}"
x:Name="ContentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer x:Name="BodyScrollViewer"
Grid.Row="1"
HorizontalScrollBarVisibility="Disabled"
Margin="10, 0, 10, 0"
VerticalScrollBarVisibility="Auto"
Visibility="{Binding CompactMode, Converter={StaticResource InverseBooleanToVisibilityConverter}, FallbackValue={x:Static Visibility.Visible}}">
<!-- A finite viewport keeps the process list bounded while the body can scroll. -->
<Grid x:Name="ContentGrid"
Height="{Binding ViewportHeight, ElementName=BodyScrollViewer}"
MinHeight="320">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Settings -->
<GroupBox Grid.Column="0"
Grid.Row="0"
Header="{Binding Path=(local:Localizer.String).Settings}"
Margin="0, 5, 5, 0">
<ScrollViewer Grid.Column="0"
Grid.Row="0"
Margin="0, 5, 5, 0"
VerticalScrollBarVisibility="Auto">
<StackPanel>
<GroupBox Header="{Binding Path=(local:Localizer.String).Settings}"
Margin="0">
<StackPanel VerticalAlignment="Center">
<StackPanel Orientation="Horizontal"
Margin="0, 0, 0, 6"
Expand Down Expand Up @@ -255,10 +273,8 @@
</StackPanel>
</GroupBox>
<!-- Memory Areas -->
<GroupBox Grid.Column="0"
Grid.Row="1"
Header="{Binding Path=(local:Localizer.String).MemoryAreas}"
Margin="0, 5, 5, 0">
<GroupBox Header="{Binding Path=(local:Localizer.String).MemoryAreas}"
Margin="0, 5, 0, 0">
<ItemsControl ItemsSource="{Binding MemoryAreaItems}"
VerticalAlignment="Center">
<ItemsControl.ItemTemplate>
Expand All @@ -273,10 +289,8 @@
</ItemsControl>
</GroupBox>
<!-- Optimization Hotkey -->
<GroupBox Grid.Column="0"
Grid.Row="2"
Header="{Binding Path=(local:Localizer.String).OptimizationHotkey}"
Margin="0, 5, 5, 0"
<GroupBox Header="{Binding Path=(local:Localizer.String).OptimizationHotkey}"
Margin="0, 5, 0, 0"
Visibility="{Binding Computer.OperatingSystem.HasHotkeyManager, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue={x:Static Visibility.Collapsed}}">
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center">
Expand Down Expand Up @@ -309,19 +323,15 @@
VerticalAlignment="Center"
Visibility="{Binding IsOptimizationKeyValid, Converter={StaticResource InverseBooleanToVisibilityConverter}, FallbackValue={x:Static Visibility.Collapsed}}" />
</StackPanel>
</GroupBox>
</GroupBox>
</StackPanel>
</ScrollViewer>
<!-- Tray Icon | Process Exclusion List | Auto Optimization -->
<Grid Grid.Column="1"
Grid.Row="0"
Grid.RowSpan="3"
VerticalAlignment="Stretch">
<Grid.MaxHeight>
<MultiBinding Converter="{StaticResource SumNumericConverter}">
<Binding ElementName="ContentGrid" Path="ActualHeight" />
</MultiBinding>
</Grid.MaxHeight>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
Expand Down Expand Up @@ -615,17 +625,29 @@
</GroupBox>
</Grid>
</Grid>
</ScrollViewer>
<!-- Footer -->
<Grid Margin="10, 0, 10, 10">
<Grid Grid.Row="2"
Margin="10, 0, 10, 10"
FlowDirection="LeftToRight">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Memory Stats -->
<Grid Grid.Column="0"
Grid.RowSpan="3"
FlowDirection="{Binding Path=(local:Localizer.Language).Direction}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Memory Stats -->
<GroupBox Grid.Column="0"
Grid.Row="0"
Header="{Binding PhysicalMemoryHeader}"
Expand Down Expand Up @@ -927,7 +949,16 @@
VerticalAlignment="Center" />
</StackPanel>
</Grid>
</Grid>
<ResizeGrip x:Name="WindowResizeGrip"
FlowDirection="LeftToRight"
Grid.Column="1"
Grid.Row="2"
Height="16"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="16" />
</Grid>
</StackPanel>
</Grid>
</Border>
</local:View>
117 changes: 112 additions & 5 deletions src/View/Window/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Windows;
Expand All @@ -15,6 +16,15 @@ namespace WinMemoryCleaner
/// <seealso cref="System.Windows.Markup.IComponentConnector" />
public partial class MainWindow : View
{
private const double ExpandedHeight = 700;
private const double ExpandedMinHeight = 440;
private const double ExpandedMinWidth = 680;
private const double ExpandedWidth = 960;

private bool? _compactModeApplied;
private bool _expandedLayoutApplied;
private double _lastExpandedHeight = ExpandedHeight;
private double _lastExpandedWidth = ExpandedWidth;
private readonly MainViewModel _viewModel;

/// <summary>
Expand All @@ -28,11 +38,9 @@ public MainWindow()

InitializeComponent();

// Set initial focus once on load
Loaded += (s, e) =>
{
SetFocusTo(Optimize);
};
// Set initial focus and layout once on load
Loaded += OnMainWindowLoaded;
Closed += OnMainWindowClosed;

IsVisibleChanged += OnWindowVisibleChanged;

Expand All @@ -42,6 +50,7 @@ public MainWindow()
{
_viewModel.OnAddProcessToExclusionListCommandCompleted += OnAddProcessToExclusionListCommandCompleted;
_viewModel.OnLanguageChangeCompleted += Refresh;
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
_viewModel.OnNavigateUriCommandCompleted += OnNavigateUriCommandCompleted;
_viewModel.OnOptimizeCommandCompleted += OnOptimizeCommandCompleted;
_viewModel.OnRemoveProcessFromExclusionListCommandCompleted += () => SetFocusTo(ProcessExclusionList);
Expand Down Expand Up @@ -69,6 +78,65 @@ public MainWindow()
FontSizeSlider.AddHandler(PreviewMouseLeftButtonDownEvent, sliderPreviewMouseLeftButtonDownEvent, true);
}

/// <summary>
/// Applies the requested compact or expanded window layout.
/// </summary>
/// <param name="compactMode">If set to <c>true</c>, applies compact mode.</param>
private void ApplyCompactMode(bool compactMode)
{
if (_compactModeApplied.HasValue && _compactModeApplied.Value == compactMode)
return;

if (compactMode)
{
if (_expandedLayoutApplied)
{
CacheExpandedSize();

if (WindowState == WindowState.Maximized)
WindowState = WindowState.Normal;
}

MinHeight = 0;
MinWidth = 0;
ResizeMode = ResizeMode.NoResize;
SizeToContent = SizeToContent.WidthAndHeight;
WindowResizeGrip.Visibility = Visibility.Collapsed;
}
else
{
SizeToContent = SizeToContent.Manual;
ResizeMode = ResizeMode.CanResizeWithGrip;
MinHeight = ExpandedMinHeight;
MinWidth = ExpandedMinWidth;
Width = _lastExpandedWidth;
Height = _lastExpandedHeight;
WindowResizeGrip.Visibility = Visibility.Visible;
_expandedLayoutApplied = true;
}

_compactModeApplied = compactMode;
}

/// <summary>
/// Caches a usable expanded window size for the current session.
/// </summary>
private void CacheExpandedSize()
{
if (WindowState == WindowState.Minimized)
return;

var bounds = WindowState == WindowState.Maximized
? RestoreBounds
: new Rect(0, 0, ActualWidth, ActualHeight);

if (bounds.Width <= 0 || bounds.Height <= 0)
return;

_lastExpandedWidth = bounds.Width;
_lastExpandedHeight = bounds.Height;
}

/// <summary>
/// Closes the window to the notification area.
/// </summary>
Expand Down Expand Up @@ -186,8 +254,14 @@ private void OnMinimizeButtonClick(object sender, RoutedEventArgs e)
/// <inheritdoc/>
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (e == null)
throw new ArgumentNullException("e");

base.OnMouseLeftButtonDown(e);

if (e.Handled || e.OriginalSource is ResizeGrip || e.Source is ResizeGrip)
return;

DragMove();
}

Expand Down Expand Up @@ -295,6 +369,39 @@ private void OnWindowMouseDown(object sender, MouseButtonEventArgs e)
SetFocusTo(Optimize);
}

/// <summary>
/// Called when the window is closed.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void OnMainWindowClosed(object sender, EventArgs e)
{
if (_viewModel != null)
_viewModel.PropertyChanged -= OnViewModelPropertyChanged;
}

/// <summary>
/// Called when the window is loaded.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
private void OnMainWindowLoaded(object sender, RoutedEventArgs e)
{
SetFocusTo(Optimize);
ApplyCompactMode(_viewModel != null && _viewModel.CompactMode);
}

/// <summary>
/// Called when the view model changes.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "CompactMode")
ApplyCompactMode(_viewModel.CompactMode);
}

/// <summary>
/// Called when the window visibility changes.
/// </summary>
Expand Down
Loading