Skip to content

Commit 861d178

Browse files
authored
Merge pull request #2306 from Nexus-Mods/load-order-styling
Load order styling part 2
2 parents fee4ee5 + baa2dd7 commit 861d178

File tree

7 files changed

+233
-65
lines changed

7 files changed

+233
-65
lines changed

src/NexusMods.App.UI/Pages/Sorting/LoadOrder/LoadOrderView.axaml

+107-58
Original file line numberDiff line numberDiff line change
@@ -7,57 +7,106 @@
77
xmlns:icons="clr-namespace:NexusMods.Icons;assembly=NexusMods.Icons"
88
xmlns:sorting="clr-namespace:NexusMods.App.UI.Pages.Sorting"
99
xmlns:alerts="clr-namespace:NexusMods.App.UI.Controls.Alerts"
10-
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
10+
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
1111
x:Class="NexusMods.App.UI.Pages.Sorting.LoadOrderView">
1212
<Design.DataContext>
1313
<sorting:LoadOrderDesignViewModel />
1414
</Design.DataContext>
1515

16-
<Grid RowDefinitions="Auto, *">
17-
<!-- <Border Background="Red"> -->
18-
<!-- <TextBlock Text="{Binding SortOrderName}"/> -->
19-
<!-- </Border> -->
20-
21-
<StackPanel Spacing="24"
22-
Grid.Row="0">
23-
<alerts:Alert
24-
Severity="Info"
25-
Title="Load Order for REDmod files in Cyberpunk 2077 - First Loaded Wins"
26-
Body="Some Cyberpunk 2077 mods use REDmod files to alter core gameplay elements. If two REDmod files modify the same part of the game, the one loaded first will take priority and overwrite changes from those loaded later.\n\nFor example, the 1st position overwrites the 2nd, the 2nd overwrites the 3rd, and so on."
27-
IsVisible="True"
28-
ShowDismiss="False" />
29-
30-
<TextBlock Grid.Row="1" Text="Last Loaded REDmod File Wins"
31-
Theme="{StaticResource HeadingXSSemiTheme}" />
32-
</StackPanel>
33-
34-
35-
<Grid Grid.Row="1" ColumnDefinitions="50, *" Margin="0,24,0,0">
36-
37-
<Grid RowDefinitions="24, 8, *, 8, 24" Margin="0,60,0,0">
38-
<icons:UnifiedIcon Grid.Row="0" Value="{x:Static icons:IconValues.Trophy}" />
39-
<Border Grid.Row="2" Width="5">
40-
<Border.Background>
41-
<LinearGradientBrush StartPoint="0%,0%" EndPoint="0%,100%">
42-
<GradientStop Color="#FFFFFFFF" Offset="0" />
43-
<GradientStop Color="#32FFFFFF" Offset="1" />
44-
</LinearGradientBrush>
45-
</Border.Background>
46-
</Border>
47-
<icons:UnifiedIcon Grid.Row="4" Value="{x:Static icons:IconValues.ArrowDown}" Foreground="#32FFFFFF" />
48-
</Grid>
49-
50-
<TreeDataGrid Grid.Column="1" x:Name="SortOrderTreeDataGrid"
51-
AutoDragDropRows="False"
52-
CanUserResizeColumns="True"
53-
CanUserSortColumns="False"
54-
ShowColumnHeaders="True"
55-
RowDrop="OnRowDrop">
16+
<controls:EmptyState x:Name="EmptyState"
17+
Header="{Binding EmptyStateMessageTitle}">
18+
19+
<controls:EmptyState.Subtitle>
20+
<TextBlock Text="{Binding EmptyStateMessageContents}" />
21+
</controls:EmptyState.Subtitle>
22+
23+
<Grid RowDefinitions="Auto, Auto, *">
24+
<Border Grid.Row="0" Classes="Toolbar">
25+
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
26+
<ComboBox SelectedIndex="0" Classes="Secondary">
27+
<ComboBox.ItemTemplate>
28+
<DataTemplate>
29+
<StackPanel Orientation="Horizontal">
30+
<icons:UnifiedIcon Value="{x:Static icons:IconValues.Sort}" Size="20" />
31+
<TextBlock Text="Ascending (1st top)" Theme="{StaticResource BodyMDNormalTheme}" />
32+
</StackPanel>
33+
</DataTemplate>
34+
</ComboBox.ItemTemplate>
35+
<ComboBoxItem>
36+
<StackPanel Orientation="Horizontal">
37+
<icons:UnifiedIcon Value="{x:Static icons:IconValues.SortAscending}" Size="20" />
38+
<TextBlock Text="Ascending (1st top)" Theme="{StaticResource BodyMDNormalTheme}" />
39+
</StackPanel>
40+
</ComboBoxItem>
41+
<ComboBoxItem>
42+
<StackPanel Orientation="Horizontal">
43+
<icons:UnifiedIcon Value="{x:Static icons:IconValues.SortDescending}" Size="20" />
44+
<TextBlock Text="Descending (1st bottom)" Theme="{StaticResource BodyMDNormalTheme}" />
45+
</StackPanel>
46+
</ComboBoxItem>
47+
</ComboBox>
48+
<CheckBox>
49+
<TextBlock Text="Hide Disabled Collections" Theme="{StaticResource BodyMDNormalTheme}" />
50+
</CheckBox>
51+
<Separator Width="1" Height="32" Background="{StaticResource StrokeTranslucentWeakBrush}" />
52+
<controls:StandardButton
53+
Size="Small"
54+
Text="Add to group" />
55+
<ComboBox SelectedIndex="0" Classes="Secondary">
56+
<ComboBox.ItemTemplate>
57+
<DataTemplate>
58+
<TextBlock Text="New group" Theme="{StaticResource BodyMDNormalTheme}" />
59+
</DataTemplate>
60+
</ComboBox.ItemTemplate>
61+
<ComboBoxItem Content="Item 1" />
62+
<ComboBoxItem Content="Item 2" />
63+
<ComboBoxItem Content="Item 3" />
64+
</ComboBox>
65+
</StackPanel>
66+
</Border>
67+
68+
<StackPanel Grid.Row="1" Spacing="24" Margin="24">
69+
<alerts:Alert
70+
Severity="Info"
71+
Title="Load Order for REDmod files in Cyberpunk 2077 - First Loaded Wins"
72+
Body="Some Cyberpunk 2077 mods use REDmod files to alter core gameplay elements. If two REDmod files modify the same part of the game, the one loaded first will take priority and overwrite changes from those loaded later.\n\nFor example, the 1st position overwrites the 2nd, the 2nd overwrites the 3rd, and so on."
73+
IsVisible="True"
74+
ShowDismiss="False" />
75+
76+
<TextBlock Text="Last Loaded REDmod File Wins"
77+
Theme="{StaticResource HeadingXSSemiTheme}" />
78+
</StackPanel>
5679

57-
<TreeDataGrid.Resources>
80+
<Grid Grid.Row="2" ColumnDefinitions="32, *" Margin="24,0,24,24">
5881

59-
<DataTemplate x:Key="LoadOrderItemIndexColumnTemplate"
60-
DataType="sorting:ILoadOrderItemModel">
82+
<!-- left column (trophy bar) -->
83+
<DockPanel x:Name="TrophyBarPanel" HorizontalAlignment="Left">
84+
<icons:UnifiedIcon x:Name="TrophyIcon" Margin="0,8,0,8" DockPanel.Dock="Top"
85+
Value="{x:Static icons:IconValues.Trophy}" Size="20" />
86+
87+
<Grid RowDefinitions="Auto, *, Auto" HorizontalAlignment="Center">
88+
<icons:UnifiedIcon x:Name="ArrowUpIcon" Grid.Row="0"
89+
Value="{x:Static icons:IconValues.ArrowUpThick}"
90+
Size="20" />
91+
<Border Grid.Row="1" x:Name="TrophyGradientBorder" Width="3" Margin="0,4" />
92+
<icons:UnifiedIcon x:Name="ArrowDownIcon" Grid.Row="2"
93+
Value="{x:Static icons:IconValues.ArrowDownThick}"
94+
Size="20" />
95+
</Grid>
96+
</DockPanel>
97+
98+
<!-- right column (tree data grid) -->
99+
<TreeDataGrid Grid.Column="1" x:Name="SortOrderTreeDataGrid"
100+
AutoDragDropRows="False"
101+
CanUserResizeColumns="True"
102+
CanUserSortColumns="False"
103+
ShowColumnHeaders="True"
104+
RowDrop="OnRowDrop">
105+
106+
<TreeDataGrid.Resources>
107+
108+
<DataTemplate x:Key="LoadOrderItemIndexColumnTemplate"
109+
DataType="sorting:ILoadOrderItemModel">
61110

62111
<StackPanel Orientation="Horizontal" Spacing="12">
63112
<controls:StandardButton x:Name="UpButton"
@@ -89,24 +138,24 @@
89138
Fill="None" />
90139
<Border
91140
Background="{StaticResource SurfaceTranslucentMidBrush}"
92-
Width="1"
93-
Height="42"/>
141+
Width="1"
142+
Height="42" />
94143
</StackPanel>
95-
</DataTemplate>
144+
</DataTemplate>
96145

97-
<DataTemplate x:Key="LoadOrderItemNameColumnTemplate"
98-
DataType="sorting:ILoadOrderItemModel">
99-
<StackPanel Orientation="Horizontal">
100-
<TextBlock x:Name="ItemName"
101-
Text="{CompiledBinding DisplayName}" />
102-
</StackPanel>
103-
</DataTemplate>
146+
<DataTemplate x:Key="LoadOrderItemNameColumnTemplate"
147+
DataType="sorting:ILoadOrderItemModel">
148+
<StackPanel Orientation="Horizontal">
149+
<TextBlock x:Name="ItemName"
150+
Text="{CompiledBinding DisplayName}" />
151+
</StackPanel>
152+
</DataTemplate>
104153

105-
</TreeDataGrid.Resources>
154+
</TreeDataGrid.Resources>
106155

107-
</TreeDataGrid>
156+
</TreeDataGrid>
157+
</Grid>
108158
</Grid>
109-
110-
</Grid>
159+
</controls:EmptyState>
111160

112161
</reactiveUi:ReactiveUserControl>

src/NexusMods.App.UI/Pages/Sorting/LoadOrder/LoadOrderView.axaml.cs

+27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
using System.ComponentModel;
12
using System.Reactive.Disposables;
23
using Avalonia.Controls;
34
using Avalonia.ReactiveUI;
45
using NexusMods.App.UI.Controls;
6+
using NexusMods.App.UI.Helpers;
57
using ReactiveUI;
68

79
namespace NexusMods.App.UI.Pages.Sorting;
@@ -25,6 +27,31 @@ public LoadOrderView()
2527
view => view.SortOrderTreeDataGrid.Source
2628
)
2729
.DisposeWith(disposables);
30+
31+
this.WhenAnyValue(view => view.ViewModel!.SortDirectionCurrent)
32+
.Subscribe(sortCurrentDirection =>
33+
{
34+
var isAscending = sortCurrentDirection == ListSortDirection.Ascending;
35+
ArrowUpIcon.IsVisible = !isAscending;
36+
ArrowDownIcon.IsVisible = isAscending;
37+
}
38+
)
39+
.DisposeWith(disposables);
40+
41+
this.WhenAnyValue(view => view.ViewModel!.IsWinnerTop)
42+
.Subscribe(isWinnerTop =>
43+
{
44+
DockPanel.SetDock(TrophyIcon, isWinnerTop ? Dock.Top : Dock.Bottom);
45+
TrophyBarPanel.Classes.Add(isWinnerTop ? "IsWinnerTop" : "IsWinnerBottom");
46+
}
47+
)
48+
.DisposeWith(disposables);
49+
50+
// empty state
51+
this.OneWayBind(ViewModel,
52+
vm => vm.Adapter.IsSourceEmpty.Value,
53+
view => view.EmptyState.IsActive)
54+
.DisposeWith(disposables);
2855
}
2956
);
3057
}

src/NexusMods.Icons/IconValues.cs

+16-1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ public static class IconValues
117117
// https://pictogrammers.com/library/mdi/icon/view-carousel/
118118
public static readonly IconValue ViewCarousel = new ProjektankerIcon("mdi-view-carousel");
119119

120+
// https://pictogrammers.com/library/mdi/icon/sort/
121+
public static readonly IconValue Sort = new ProjektankerIcon("mdi-sort");
122+
123+
// https://pictogrammers.com/library/mdi/icon/sort-ascending/
124+
public static readonly IconValue SortAscending = new ProjektankerIcon("mdi-sort-ascending");
125+
126+
// https://pictogrammers.com/library/mdi/icon/sort-descending/
127+
public static readonly IconValue SortDescending = new ProjektankerIcon("mdi-sort-descending");
128+
120129
#endregion
121130

122131
#region Alert
@@ -289,7 +298,13 @@ public static class IconValues
289298

290299
// https://pictogrammers.com/library/mdi/icon/menu-up/
291300
public static readonly IconValue ArrowDropUp = new ProjektankerIcon("mdi-menu-up");
292-
301+
302+
// https://pictogrammers.com/library/mdi/icon/arrow-up-thick/
303+
public static readonly IconValue ArrowUpThick = new ProjektankerIcon("mdi-arrow-up-thick");
304+
305+
// https://pictogrammers.com/library/mdi/icon/arrow-down-thick"/
306+
public static readonly IconValue ArrowDownThick = new ProjektankerIcon("mdi-arrow-down-thick");
307+
293308
// https://pictogrammers.com/library/mdi/icon/chevron-left/
294309
public static readonly IconValue ChevronLeft = new ProjektankerIcon("mdi-chevron-left");
295310

src/Themes/NexusMods.Themes.NexusFluentDark/Styles/Controls/Border/Toolbar.xaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
<Setter Property="HorizontalAlignment" Value="Stretch" />
102102
<Setter Property="Height" Value="52" />
103103
<Setter Property="Background" Value="{StaticResource SurfaceLow}" />
104-
<Setter Property="BorderThickness" Value="0, 0, 0, 1" />
104+
<Setter Property="BorderThickness" Value="0, 1, 0, 1" />
105105
<Setter Property="BorderBrush" Value="{StaticResource StrokeTranslucentWeakBrush}" />
106106
</Style>
107107

src/Themes/NexusMods.Themes.NexusFluentDark/Styles/Controls/Icons/IconsStyles.axaml

+21
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@
104104
<icons:UnifiedIcon Classes="Database"/>
105105
<icons:UnifiedIcon Classes="Size"/>
106106
<icons:UnifiedIcon Classes="Info"/>
107+
<icons:UnifiedIcon Classes="Trophy"/>
108+
<icons:UnifiedIcon Classes="ArrowUpThick"/>
109+
<icons:UnifiedIcon Classes="ArrowDownThick"/>
110+
<icons:UnifiedIcon Classes="Sort"/>
111+
<icons:UnifiedIcon Classes="SortAscending"/>
112+
<icons:UnifiedIcon Classes="SortDescending"/>
107113
</WrapPanel>
108114
</Design.PreviewWith>
109115

@@ -521,4 +527,19 @@
521527
<Style Selector="icons|UnifiedIcon.Trophy">
522528
<Setter Property="Value" Value="{x:Static icons:IconValues.Trophy}"/>
523529
</Style>
530+
<Style Selector="icons|UnifiedIcon.ArrowUpThick">
531+
<Setter Property="Value" Value="{x:Static icons:IconValues.ArrowUpThick}"/>
532+
</Style>
533+
<Style Selector="icons|UnifiedIcon.ArrowDownThick">
534+
<Setter Property="Value" Value="{x:Static icons:IconValues.ArrowDownThick}"/>
535+
</Style>
536+
<Style Selector="icons|UnifiedIcon.Sort">
537+
<Setter Property="Value" Value="{x:Static icons:IconValues.Sort}"/>
538+
</Style>
539+
<Style Selector="icons|UnifiedIcon.SortAscending">
540+
<Setter Property="Value" Value="{x:Static icons:IconValues.SortAscending}"/>
541+
</Style>
542+
<Style Selector="icons|UnifiedIcon.SortDescending">
543+
<Setter Property="Value" Value="{x:Static icons:IconValues.SortDescending}"/>
544+
</Style>
524545
</Styles>

src/Themes/NexusMods.Themes.NexusFluentDark/Styles/Controls/TabControl/TabControlStyles.axaml

+8-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@
6161
</Design.PreviewWith>
6262

6363
<Style Selector="TabControl">
64+
6465
<!-- <Setter Property="ClipToBounds" Value="False" /> -->
6566
<Setter Property="Margin" Value="0" />
66-
<Setter Property="Padding" Value="8" />
67+
<Setter Property="Padding" Value="0" />
6768
<Setter Property="CornerRadius" Value="0" />
6869
<Setter Property="Background" Value="{StaticResource SurfaceLowBrush}" />
6970
<!-- <Setter Property="HorizontalAlignment" Value="Stretch" /> -->
@@ -150,11 +151,15 @@
150151

151152
<Style Selector="^.Subtabs">
152153

154+
<!-- content padding -->
155+
<Setter Property="Padding" Value="0,0" />
156+
157+
<!-- header padding -->
153158
<Style Selector="^ ItemsPresenter#PART_ItemsPresenter">
154-
<Setter Property="Margin" Value="8,8,8,0" />
159+
<Setter Property="Margin" Value="24,8" />
155160
</Style>
156161

157-
162+
158163
<Style Selector="^ TabItem">
159164
<Setter Property="Padding" Value="12,0" />
160165
<Setter Property="BorderThickness" Value="1" />

src/Themes/NexusMods.Themes.NexusFluentDark/Styles/Controls/TreeDataGrid/SortOrderStyles.axaml

+53-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,62 @@
11
<Styles xmlns="https://github.com/avaloniaui"
2-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:icons="clr-namespace:NexusMods.Icons;assembly=NexusMods.Icons"
4+
xmlns:sorting="clr-namespace:NexusMods.App.UI.Pages.Sorting;assembly=NexusMods.App.UI">
35
<Design.PreviewWith>
4-
<Border Padding="16">
6+
<Border Padding="0">
57
<TreeDataGrid x:Name="SortOrderTreeDataGrid" Width="400" Height="200" />
68
</Border>
79
</Design.PreviewWith>
810

11+
12+
<Style Selector="sorting|LoadOrderView">
13+
14+
<Style Selector="^ DockPanel#TrophyBarPanel">
15+
16+
<Style Selector="^.IsWinnerTop">
17+
<Style Selector="^ Border#TrophyGradientBorder">
18+
<Setter Property="Background">
19+
<LinearGradientBrush StartPoint="0%,0%" EndPoint="0%,100%">
20+
<GradientStop Color="#FFFFFFFF" Offset="0" />
21+
<GradientStop Color="#32FFFFFF" Offset="1" />
22+
</LinearGradientBrush>
23+
</Setter>
24+
</Style>
25+
<Style Selector="^ icons|UnifiedIcon#ArrowUpIcon">
26+
<Setter Property="Foreground" Value="#FFFFFFFF" />
27+
</Style>
28+
<Style Selector="^ icons|UnifiedIcon#ArrowDownIcon">
29+
<Setter Property="Foreground" Value="#32FFFFFF" />
30+
</Style>
31+
</Style>
32+
33+
<Style Selector="^.IsWinnerBottom">
34+
<Style Selector="^ Border#TrophyGradientBorder">
35+
<Setter Property="Background">
36+
<LinearGradientBrush StartPoint="0%,0%" EndPoint="0%,100%">
37+
<GradientStop Color="#32FFFFFF" Offset="0" />
38+
<GradientStop Color="#FFFFFFFF" Offset="1" />
39+
</LinearGradientBrush>
40+
</Setter>
41+
</Style>
42+
<Style Selector="^ icons|UnifiedIcon#ArrowUpIcon">
43+
<Setter Property="Foreground" Value="#32FFFFFF" />
44+
</Style>
45+
<Style Selector="^ icons|UnifiedIcon#ArrowDownIcon">
46+
<Setter Property="Foreground" Value="#FFFFFFFF" />
47+
</Style>
48+
</Style>
49+
50+
<Style Selector="^.SortAsc">
51+
<Setter Property="Background" Value="Transparent" />
52+
</Style>
53+
54+
<Style Selector="^.SortDesc">
55+
<Setter Property="Background" Value="Transparent" />
56+
</Style>
57+
</Style>
58+
</Style>
59+
960
<Style Selector="TreeDataGrid#SortOrderTreeDataGrid">
1061

1162
<Setter Property="Background" Value="{x:Null}" />

0 commit comments

Comments
 (0)