Skip to content

Commit 5b52d1b

Browse files
committed
Fix artifact compatibility - use v4
1 parent 6f51fbe commit 5b52d1b

8 files changed

Lines changed: 124 additions & 5 deletions

File tree

Bloxstrap/Extensions/BootstrapperIconEx.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ static class BootstrapperIconEx
88
{
99
private static readonly ConcurrentDictionary<BootstrapperIcon, ImageSource> ImageSourceCache = new();
1010

11+
public static void ClearCache(BootstrapperIcon icon)
12+
{
13+
ImageSourceCache.TryRemove(icon, out _);
14+
}
15+
1116
public static ImageSource GetImageSource(this BootstrapperIcon icon)
1217
{
1318
return ImageSourceCache.GetOrAdd(icon, key =>

Bloxstrap/Extensions/RobloxIconEx.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ static class RobloxIconEx
88
{
99
private static readonly ConcurrentDictionary<RobloxIcon, ImageSource> ImageSourceCache = new();
1010

11+
public static void ClearCache(RobloxIcon icon)
12+
{
13+
ImageSourceCache.TryRemove(icon, out _);
14+
}
15+
1116
public static ImageSource GetImageSource(this RobloxIcon icon)
1217
{
1318
return ImageSourceCache.GetOrAdd(icon, key =>
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
using System.Windows.Media;
1+
using System.ComponentModel;
2+
using System.Windows.Media;
23

34
namespace Bloxstrap.Models
45
{
5-
public class BootstrapperIconEntry
6+
public class BootstrapperIconEntry : INotifyPropertyChanged
67
{
8+
public event PropertyChangedEventHandler? PropertyChanged;
9+
710
public BootstrapperIcon IconType { get; set; }
811
public ImageSource ImageSource => IconType.GetImageSource();
12+
13+
public void RefreshImageSource() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ImageSource)));
914
}
1015
}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
using System.Windows.Media;
1+
using System.ComponentModel;
2+
using System.Windows.Media;
23

34
namespace Bloxstrap.Models
45
{
5-
public class RobloxIconEntry
6+
public class RobloxIconEntry : INotifyPropertyChanged
67
{
8+
public event PropertyChangedEventHandler? PropertyChanged;
9+
710
public RobloxIcon IconType { get; set; }
811
public ImageSource ImageSource => IconType.GetImageSource();
12+
13+
public void RefreshImageSource() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ImageSource)));
914
}
1015
}

Bloxstrap/UI/Elements/Settings/Pages/AppearancePage.xaml.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,24 @@ public partial class AppearancePage
1111
{
1212
public AppearancePage()
1313
{
14-
DataContext = new AppearanceViewModel(this);
14+
var viewModel = new AppearanceViewModel(this);
15+
16+
// Subscribe ke event untuk update icon di title bar
17+
viewModel.IconChangedEvent += (sender, e) => UpdateMainWindowIcon();
18+
19+
DataContext = viewModel;
1520
InitializeComponent();
1621
}
1722

23+
private void UpdateMainWindowIcon()
24+
{
25+
var mainWindow = System.Windows.Window.GetWindow(this) as MainWindow;
26+
if (mainWindow != null)
27+
{
28+
mainWindow.RootTitleBar.Icon = App.Settings.Prop.BootstrapperIcon.GetImageSource();
29+
}
30+
}
31+
1832
public void CustomThemeSelection(object sender, SelectionChangedEventArgs e)
1933
{
2034
AppearanceViewModel viewModel = (AppearanceViewModel)DataContext;

Bloxstrap/UI/Elements/Settings/Pages/ModsPage.xaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@
103103
<StackPanel>
104104
<ui:Button Icon="Image16" Content="{x:Static resources:Strings.Menu_Mods_Misc_CustomBackground_Choose}" Command="{Binding ManageCustomBackgroundCommand}" Visibility="{Binding ChooseCustomBackgroundVisibility, Mode=OneWay}" />
105105
<ui:Button Icon="Delete16" Content="{x:Static resources:Strings.Menu_Mods_Misc_CustomBackground_Remove}" Appearance="Danger" Command="{Binding ManageCustomBackgroundCommand}" Visibility="{Binding DeleteCustomBackgroundVisibility, Mode=OneWay}" />
106+
<Border Margin="0,8,0,0" BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}" BorderThickness="1" CornerRadius="4" Visibility="{Binding BackgroundPreviewVisibility, Mode=OneWay}">
107+
<Image Source="{Binding BackgroundPreview, Mode=OneWay}" MaxHeight="200" Stretch="Uniform" />
108+
</Border>
106109
</StackPanel>
107110
</controls:OptionControl>
108111

@@ -112,6 +115,9 @@
112115
<StackPanel>
113116
<ui:Button Icon="Image16" Content="{x:Static resources:Strings.Menu_Mods_Misc_CustomLoadingScreen_Choose}" Command="{Binding ManageCustomLoadingScreenCommand}" Visibility="{Binding ChooseCustomLoadingScreenVisibility, Mode=OneWay}" />
114117
<ui:Button Icon="Delete16" Content="{x:Static resources:Strings.Menu_Mods_Misc_CustomLoadingScreen_Remove}" Appearance="Danger" Command="{Binding ManageCustomLoadingScreenCommand}" Visibility="{Binding DeleteCustomLoadingScreenVisibility, Mode=OneWay}" />
118+
<Border Margin="0,8,0,0" BorderBrush="{DynamicResource ControlStrokeColorDefaultBrush}" BorderThickness="1" CornerRadius="4" Visibility="{Binding LoadingScreenPreviewVisibility, Mode=OneWay}">
119+
<Image Source="{Binding LoadingScreenPreview, Mode=OneWay}" MaxHeight="200" Stretch="Uniform" />
120+
</Border>
115121
</StackPanel>
116122
</controls:OptionControl>
117123
</StackPanel>

Bloxstrap/UI/ViewModels/Settings/AppearanceViewModel.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public class AppearanceViewModel : NotifyPropertyChangedViewModel, INavigationAw
1717
{
1818
private readonly Page _page;
1919

20+
public event EventHandler? IconChangedEvent;
21+
2022
public ICommand PreviewBootstrapperCommand => new RelayCommand(PreviewBootstrapper);
2123
public ICommand BrowseCustomIconLocationCommand => new RelayCommand(BrowseCustomIconLocation);
2224
public ICommand BrowseCustomRobloxIconLocationCommand => new RelayCommand(BrowseCustomRobloxIconLocation);
@@ -152,6 +154,16 @@ public string CustomRobloxIconLocation
152154

153155
App.Settings.Prop.RobloxIconCustomLocation = value;
154156

157+
// Clear cache dan refresh ImageSource
158+
RobloxIconEx.ClearCache(RobloxIcon.IconCustom);
159+
160+
// Refresh semua icon entries
161+
foreach (var entry in RobloxIcons)
162+
{
163+
if (entry.IconType == RobloxIcon.IconCustom)
164+
entry.RefreshImageSource();
165+
}
166+
155167
OnPropertyChanged(nameof(RobloxIcon));
156168
OnPropertyChanged(nameof(RobloxIcons));
157169
}
@@ -186,8 +198,21 @@ public string CustomIconLocation
186198

187199
App.Settings.Prop.BootstrapperIconCustomLocation = value;
188200

201+
// Clear cache dan refresh ImageSource
202+
BootstrapperIconEx.ClearCache(BootstrapperIcon.IconCustom);
203+
204+
// Refresh semua icon entries
205+
foreach (var entry in Icons)
206+
{
207+
if (entry.IconType == BootstrapperIcon.IconCustom)
208+
entry.RefreshImageSource();
209+
}
210+
189211
OnPropertyChanged(nameof(Icon));
190212
OnPropertyChanged(nameof(Icons));
213+
214+
// Notify icon changed untuk update title bar
215+
IconChangedEvent?.Invoke(this, EventArgs.Empty);
191216
}
192217
}
193218

Bloxstrap/UI/ViewModels/Settings/ModsViewModel.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System.Windows;
22
using System.Windows.Input;
3+
using System.Windows.Media;
4+
using System.Windows.Media.Imaging;
35

46
using Microsoft.Win32;
57

@@ -16,6 +18,34 @@ namespace Bloxstrap.UI.ViewModels.Settings
1618
{
1719
public class ModsViewModel : NotifyPropertyChangedViewModel
1820
{
21+
private ImageSource? _backgroundPreview;
22+
private ImageSource? _loadingScreenPreview;
23+
24+
public ImageSource? BackgroundPreview
25+
{
26+
get => _backgroundPreview;
27+
set
28+
{
29+
_backgroundPreview = value;
30+
OnPropertyChanged(nameof(BackgroundPreview));
31+
OnPropertyChanged(nameof(BackgroundPreviewVisibility));
32+
}
33+
}
34+
35+
public ImageSource? LoadingScreenPreview
36+
{
37+
get => _loadingScreenPreview;
38+
set
39+
{
40+
_loadingScreenPreview = value;
41+
OnPropertyChanged(nameof(LoadingScreenPreview));
42+
OnPropertyChanged(nameof(LoadingScreenPreviewVisibility));
43+
}
44+
}
45+
46+
public Visibility BackgroundPreviewVisibility => BackgroundPreview != null ? Visibility.Visible : Visibility.Collapsed;
47+
public Visibility LoadingScreenPreviewVisibility => LoadingScreenPreview != null ? Visibility.Visible : Visibility.Collapsed;
48+
1949
private void OpenModsFolder() => Process.Start("explorer.exe", Paths.Modifications);
2050

2151
private readonly Dictionary<string, byte[]> FontHeaders = new()
@@ -70,6 +100,7 @@ private void ManageCustomBackground()
70100
if (!String.IsNullOrEmpty(BackgroundTask.NewState))
71101
{
72102
BackgroundTask.NewState = "";
103+
BackgroundPreview = null;
73104
}
74105
else
75106
{
@@ -85,6 +116,17 @@ private void ManageCustomBackground()
85116
{
86117
using var img = System.Drawing.Image.FromFile(dialog.FileName);
87118
BackgroundTask.NewState = dialog.FileName;
119+
120+
// Load preview image
121+
var bitmap = new BitmapImage();
122+
bitmap.BeginInit();
123+
bitmap.UriSource = new Uri(dialog.FileName);
124+
bitmap.CacheOption = BitmapCacheOption.OnLoad;
125+
bitmap.DecodePixelWidth = 400; // Resize untuk preview
126+
bitmap.EndInit();
127+
bitmap.Freeze();
128+
129+
BackgroundPreview = bitmap;
88130
}
89131
catch
90132
{
@@ -102,6 +144,7 @@ private void ManageCustomLoadingScreen()
102144
if (!String.IsNullOrEmpty(LoadingScreenTask.NewState))
103145
{
104146
LoadingScreenTask.NewState = "";
147+
LoadingScreenPreview = null;
105148
}
106149
else
107150
{
@@ -117,6 +160,17 @@ private void ManageCustomLoadingScreen()
117160
{
118161
using var img = System.Drawing.Image.FromFile(dialog.FileName);
119162
LoadingScreenTask.NewState = dialog.FileName;
163+
164+
// Load preview image
165+
var bitmap = new BitmapImage();
166+
bitmap.BeginInit();
167+
bitmap.UriSource = new Uri(dialog.FileName);
168+
bitmap.CacheOption = BitmapCacheOption.OnLoad;
169+
bitmap.DecodePixelWidth = 400; // Resize untuk preview
170+
bitmap.EndInit();
171+
bitmap.Freeze();
172+
173+
LoadingScreenPreview = bitmap;
120174
}
121175
catch
122176
{

0 commit comments

Comments
 (0)