Skip to content

Commit 0901b54

Browse files
committed
Chore: Refactor profile views into a reusable control
1 parent 5087342 commit 0901b54

52 files changed

Lines changed: 2369 additions & 16736 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using NETworkManager.Controls;
2+
using System.ComponentModel;
3+
using System.Windows.Input;
4+
5+
namespace NETworkManager.Profiles;
6+
7+
/// <summary>
8+
/// Interface for a view model that hosts the shared profile panel (search, tag filter, group list) next to a
9+
/// tool-specific view, extending <see cref="IProfileManager" /> with the additional members the reusable
10+
/// profile panel control binds to.
11+
/// </summary>
12+
public interface IProfileHostViewModel : IProfileManager
13+
{
14+
/// <summary>
15+
/// Gets or sets the selected profile.
16+
/// </summary>
17+
ProfileInfo SelectedProfile { get; set; }
18+
19+
/// <summary>
20+
/// Gets or sets the search text.
21+
/// </summary>
22+
string Search { get; set; }
23+
24+
/// <summary>
25+
/// Gets or sets a value indicating whether a search is in progress.
26+
/// </summary>
27+
bool IsSearching { get; set; }
28+
29+
/// <summary>
30+
/// Gets or sets a value indicating whether the profile filter popup is open.
31+
/// </summary>
32+
bool ProfileFilterIsOpen { get; set; }
33+
34+
/// <summary>
35+
/// Gets the view for the profile filter tags.
36+
/// </summary>
37+
ICollectionView ProfileFilterTagsView { get; }
38+
39+
/// <summary>
40+
/// Gets or sets a value indicating whether to match any profile filter tag.
41+
/// </summary>
42+
bool ProfileFilterTagsMatchAny { get; set; }
43+
44+
/// <summary>
45+
/// Gets or sets a value indicating whether to match all profile filter tags.
46+
/// </summary>
47+
bool ProfileFilterTagsMatchAll { get; set; }
48+
49+
/// <summary>
50+
/// Gets or sets a value indicating whether a profile filter is currently applied.
51+
/// </summary>
52+
bool IsProfileFilterSet { get; set; }
53+
54+
/// <summary>
55+
/// Gets the group expander state store for the profile list.
56+
/// </summary>
57+
GroupExpanderStateStore GroupExpanderStateStore { get; }
58+
59+
/// <summary>
60+
/// Gets the command to open the profile filter popup.
61+
/// </summary>
62+
ICommand OpenProfileFilterCommand { get; }
63+
64+
/// <summary>
65+
/// Gets the command to apply the profile filter.
66+
/// </summary>
67+
ICommand ApplyProfileFilterCommand { get; }
68+
69+
/// <summary>
70+
/// Gets the command to clear the profile filter.
71+
/// </summary>
72+
ICommand ClearProfileFilterCommand { get; }
73+
74+
/// <summary>
75+
/// Gets the command to expand all profile groups.
76+
/// </summary>
77+
ICommand ExpandAllProfileGroupsCommand { get; }
78+
79+
/// <summary>
80+
/// Gets the command to collapse all profile groups.
81+
/// </summary>
82+
ICommand CollapseAllProfileGroupsCommand { get; }
83+
}

Source/NETworkManager.Profiles/NETworkManager.Profiles.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
</ItemGroup>
2727
<ItemGroup>
28+
<ProjectReference Include="..\NETworkManager.Controls\NETworkManager.Controls.csproj" />
2829
<ProjectReference Include="..\NETworkManager.Models\NETworkManager.Models.csproj" />
2930
<ProjectReference Include="..\NETworkManager.Settings\NETworkManager.Settings.csproj" />
3031
<ProjectReference Include="..\NETworkManager.Utilities\NETworkManager.Utilities.csproj" />
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System;
2+
using System.Windows;
3+
using NETworkManager.Utilities;
4+
5+
namespace NETworkManager.Settings;
6+
7+
/// <summary>
8+
/// Shared expanded/width state of the profile panel, used by every tool that hosts a profile list. Because all
9+
/// tools observe the same <see cref="Current" /> instance, resizing or collapsing the profile panel in one tool
10+
/// is reflected in every other tool automatically through data binding - no manual synchronization needed.
11+
/// </summary>
12+
/// <remarks>
13+
/// <see cref="Current" /> reads <see cref="SettingsManager.Current" /> the first time it is accessed. This is
14+
/// only safe once <see cref="SettingsManager.Load" /> has completed (done early in App.xaml.cs, before the main
15+
/// window - and therefore any tool view - is created). Do not reference <see cref="Current" /> from eagerly
16+
/// loaded resources (e.g. App.xaml or globally merged style dictionaries).
17+
/// </remarks>
18+
public sealed class ProfileViewState : PropertyChangedBase
19+
{
20+
public static ProfileViewState Current { get; }
21+
22+
static ProfileViewState()
23+
{
24+
Current = new ProfileViewState();
25+
}
26+
27+
private readonly bool _isLoading;
28+
private bool _canProfileWidthChange = true;
29+
private double _tempProfileWidth;
30+
31+
private ProfileViewState()
32+
{
33+
_isLoading = true;
34+
35+
// Must be set before ExpandProfileView below, since assigning it can synchronously trigger
36+
// ResizeProfile(false), which reads _tempProfileWidth.
37+
_tempProfileWidth = SettingsManager.Current.Profile_Width;
38+
39+
ExpandProfileView = SettingsManager.Current.Profile_ExpandView;
40+
41+
ProfileWidth = ExpandProfileView
42+
? new GridLength(SettingsManager.Current.Profile_Width)
43+
: new GridLength(GlobalStaticConfiguration.Profile_WidthCollapsed);
44+
45+
_isLoading = false;
46+
}
47+
48+
/// <summary>
49+
/// Gets or sets a value indicating whether the profile panel is expanded, shared across all tools.
50+
/// </summary>
51+
public bool ExpandProfileView
52+
{
53+
get;
54+
set
55+
{
56+
if (value == field)
57+
return;
58+
59+
if (!_isLoading)
60+
SettingsManager.Current.Profile_ExpandView = value;
61+
62+
field = value;
63+
64+
if (_canProfileWidthChange)
65+
ResizeProfile(false);
66+
67+
OnPropertyChanged();
68+
}
69+
}
70+
71+
/// <summary>
72+
/// Gets or sets the width of the profile panel, shared across all tools.
73+
/// </summary>
74+
public GridLength ProfileWidth
75+
{
76+
get;
77+
set
78+
{
79+
if (value == field)
80+
return;
81+
82+
if (!_isLoading && Math.Abs(value.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) >
83+
GlobalStaticConfiguration.FloatPointFix) // Do not save the size when collapsed
84+
SettingsManager.Current.Profile_Width = value.Value;
85+
86+
field = value;
87+
88+
if (_canProfileWidthChange)
89+
ResizeProfile(true);
90+
91+
OnPropertyChanged();
92+
}
93+
}
94+
95+
private void ResizeProfile(bool dueToChangedSize)
96+
{
97+
_canProfileWidthChange = false;
98+
99+
if (dueToChangedSize)
100+
{
101+
ExpandProfileView = Math.Abs(ProfileWidth.Value - GlobalStaticConfiguration.Profile_WidthCollapsed) >
102+
GlobalStaticConfiguration.FloatPointFix;
103+
}
104+
else
105+
{
106+
if (ExpandProfileView)
107+
{
108+
ProfileWidth =
109+
Math.Abs(_tempProfileWidth - GlobalStaticConfiguration.Profile_WidthCollapsed) <
110+
GlobalStaticConfiguration.FloatPointFix
111+
? new GridLength(GlobalStaticConfiguration.Profile_DefaultWidthExpanded)
112+
: new GridLength(_tempProfileWidth);
113+
}
114+
else
115+
{
116+
_tempProfileWidth = ProfileWidth.Value;
117+
ProfileWidth = new GridLength(GlobalStaticConfiguration.Profile_WidthCollapsed);
118+
}
119+
}
120+
121+
_canProfileWidthChange = true;
122+
}
123+
}

0 commit comments

Comments
 (0)