Skip to content

Commit 242c4d5

Browse files
committed
Import/Export gradients
1 parent c08f8f3 commit 242c4d5

7 files changed

Lines changed: 160 additions & 23 deletions

File tree

Bloxstrap/App.xaml.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public partial class App : Application
5656

5757
public static bool IsProductionBuild => IsActionBuild && BuildMetadata.CommitRef.StartsWith("tag", StringComparison.Ordinal);
5858

59-
public static bool IsStudioVisible => !String.IsNullOrEmpty(App.RobloxState.Prop.Studio.VersionGuid);
59+
public static bool IsStudioVisible => !String.IsNullOrEmpty(RobloxState.Prop.Studio.VersionGuid);
6060

6161
public static readonly MD5 MD5Provider = MD5.Create();
6262

@@ -209,7 +209,7 @@ private static void ApplyBackdropToAllWindows(WindowsBackdrops backdropType)
209209

210210
public void ApplyCustomFontToWindow(Window window)
211211
{
212-
var fontPath = App.Settings.Prop.CustomFontPath;
212+
var fontPath = Settings.Prop.CustomFontPath;
213213
if (string.IsNullOrWhiteSpace(fontPath) || !File.Exists(fontPath))
214214
return;
215215

@@ -459,7 +459,7 @@ protected override void OnStartup(StartupEventArgs e)
459459
Terminate();
460460
}
461461

462-
Task.Run(App.RemoteData.LoadData); // ok
462+
Task.Run(RemoteData.LoadData); // ok
463463

464464
Settings.Load();
465465
State.Load();
@@ -470,10 +470,10 @@ protected override void OnStartup(StartupEventArgs e)
470470
// to fix error System.IO.IOException: No se encuentra el recurso 'ui/style/.xaml'.
471471
// when i put in installer dosent work
472472
// if i try to fix in wpfuiwindow also dosent work
473-
if (App.Settings.Prop.Theme > Enums.Theme.Custom)
473+
if (Settings.Prop.Theme > Enums.Theme.Custom)
474474
{
475-
App.Settings.Prop.Theme = Enums.Theme.Dark;
476-
App.Settings.Save();
475+
Settings.Prop.Theme = Enums.Theme.Dark;
476+
Settings.Save();
477477
}
478478

479479
if (Settings.Prop.AllowCookieAccess)

Bloxstrap/Models/Persistable/Settings.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
using System.Collections.ObjectModel;
2-
using System.Windows;
32

43
namespace Bloxstrap.Models.Persistable
54
{
65
public class Settings
76
{
8-
// uh
7+
// Fishstrap feature to use private channel.
98
public bool AllowCookieAccess { get; set; } = false;
109

1110
// Integration Page

Bloxstrap/UI/Elements/Settings/MainWindow.xaml.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ public void ApplyNavigationReorder()
169169
.ToList();
170170

171171
App.Settings.Prop.NavigationOrder = order;
172-
App.State.Save();
173172
}
174173

175174
private void ReorderNavigationItemsFromSettings()
@@ -254,7 +253,6 @@ public void ResetNavigationToDefault()
254253
RebuildNavigationItems();
255254

256255
App.Settings.Prop.NavigationOrder.Clear();
257-
App.State.Save();
258256
}
259257

260258
public int MoveNavigationItem(NavigationItem item, int direction)

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,29 +48,38 @@
4848
<ColumnDefinition Width="Auto"/>
4949
<ColumnDefinition Width="*"/>
5050
<ColumnDefinition Width="Auto"/>
51-
<ColumnDefinition Width="140"/>
52-
<ColumnDefinition Width="80"/>
51+
<ColumnDefinition Width="110"/>
52+
<ColumnDefinition Width="110"/>
5353
<ColumnDefinition Width="100"/>
5454
</Grid.ColumnDefinitions>
5555

5656
<TextBlock Text="Offset:" VerticalAlignment="Center" Margin="4,0,4,0" Grid.Column="0"/>
5757
<Slider Minimum="0" Maximum="1" Value="{Binding Offset, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" PreviewMouseLeftButtonUp="OnGradientSliderReleased" TickFrequency="0.01" IsSnapToTickEnabled="True" AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="2" Margin="4,8,4,8" Grid.Column="1"/>
5858
<TextBlock Text="{Binding Offset, StringFormat=F2}" VerticalAlignment="Center" Margin="8,0,8,0" Width="30" Grid.Column="2"/>
59-
<TextBox Text="{Binding Color, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="130" Margin="0,0,8,0" VerticalAlignment="Center" TextChanged="OnGradientColorHexChanged" Grid.Column="3" MinWidth="100"/>
60-
<Button Content="Color" Width="75" Margin="0,0,4,0" Tag="{Binding}" Click="OnChangeGradientColor_Click" Grid.Column="4"/>
61-
<Button Content="Remove" Width="95" Margin="0,0,4,0" Tag="{Binding}" Click="OnRemoveGradientStop_Click" Grid.Column="5"/>
59+
<TextBox Text="{Binding Color, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch" Margin="0,0,8,0" VerticalAlignment="Center" TextChanged="OnGradientColorHexChanged" Grid.Column="3" MinWidth="100"/>
60+
<Button Content="Color Picker" Margin="0,0,4,0" Tag="{Binding}" HorizontalAlignment="Stretch" Click="OnChangeGradientColor_Click" Grid.Column="4"/>
61+
<Button Content="Remove" Margin="0,0,0,0" Tag="{Binding}" HorizontalAlignment="Stretch" Click="OnRemoveGradientStop_Click" Grid.Column="5"/>
6262
</Grid>
6363
</DataTemplate>
6464
</ItemsControl.ItemTemplate>
6565
</ItemsControl>
66-
<StackPanel>
67-
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,0,0">
66+
<Grid Margin="0,12,0,0">
67+
<Grid.ColumnDefinitions>
68+
<ColumnDefinition Width="Auto" />
69+
<ColumnDefinition Width="*" />
70+
<ColumnDefinition Width="Auto" />
71+
</Grid.ColumnDefinitions>
72+
<StackPanel Orientation="Horizontal" Grid.Column="0">
73+
<Button Content="Export Gradient" Click="OnExportGradient_Click" Margin="4"/>
74+
<Button Content="Import Gradient" Click="OnImportGradient_Click" Margin="4"/>
75+
</StackPanel>
76+
<StackPanel Orientation="Horizontal" Grid.Column="2">
6877
<TextBlock Text="Gradient Angle:" VerticalAlignment="Center" Margin="0,0,4,0"/>
6978
<TextBox Text="{Binding GradientAngle, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Width="50" Margin="4"/>
7079
<Button Content="Reset to Default" Click="OnResetGradient_Click" Margin="4" />
7180
<Button Content="Add Gradient Color" Click="OnAddGradientStop_Click" Margin="4"/>
7281
</StackPanel>
73-
</StackPanel>
82+
</Grid>
7483
</StackPanel>
7584
</ui:CardExpander>
7685

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

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,144 @@ private void OnResetGradient_Click(object sender, RoutedEventArgs e)
134134
if (DataContext is not AppearanceViewModel vm) return;
135135

136136
vm.ResetGradientStops();
137+
vm.GradientAngle = 0;
137138
UpdateGradientTheme();
138139
}
139140

141+
private void OnExportGradient_Click(object sender, RoutedEventArgs e)
142+
{
143+
if (DataContext is not AppearanceViewModel vm) return;
144+
145+
var saveDialog = new SaveFileDialog
146+
{
147+
Filter = "JSON Files (*.json)|*.json|Text Files (*.txt)|*.txt",
148+
DefaultExt = ".json",
149+
FileName = "Froststrap Gradient Background"
150+
};
151+
152+
if (saveDialog.ShowDialog() == true)
153+
{
154+
try
155+
{
156+
var gradientData = new
157+
{
158+
GradientStops = vm.GradientStops.Select(gs => new { gs.Offset, gs.Color }).ToList(),
159+
GradientAngle = vm.GradientAngle,
160+
Version = App.Version
161+
};
162+
163+
string json = JsonSerializer.Serialize(gradientData, new JsonSerializerOptions
164+
{
165+
WriteIndented = true
166+
});
167+
168+
File.WriteAllText(saveDialog.FileName, json);
169+
170+
Frontend.ShowMessageBox(
171+
"Gradient exported successfully!",
172+
MessageBoxImage.Information,
173+
MessageBoxButton.OK
174+
);
175+
}
176+
catch (Exception ex)
177+
{
178+
Frontend.ShowMessageBox(
179+
$"Failed to export gradient: {ex.Message}",
180+
MessageBoxImage.Error,
181+
MessageBoxButton.OK
182+
);
183+
}
184+
}
185+
}
186+
187+
private void OnImportGradient_Click(object sender, RoutedEventArgs e)
188+
{
189+
if (DataContext is not AppearanceViewModel vm) return;
190+
191+
var openDialog = new OpenFileDialog
192+
{
193+
Filter = "JSON Files (*.json)|*.json|Text Files (*.txt)|*.txt",
194+
Multiselect = false
195+
};
196+
197+
if (openDialog.ShowDialog() == true)
198+
{
199+
try
200+
{
201+
string json = File.ReadAllText(openDialog.FileName);
202+
using var document = JsonDocument.Parse(json);
203+
var root = document.RootElement;
204+
205+
if (!root.TryGetProperty("GradientStops", out var stopsElement) ||
206+
stopsElement.GetArrayLength() == 0)
207+
{
208+
throw new InvalidDataException("Invalid gradient file format.");
209+
}
210+
211+
var gradientStops = new List<GradientStops>();
212+
foreach (var stopElement in stopsElement.EnumerateArray())
213+
{
214+
if (stopElement.TryGetProperty("Offset", out var offsetElement) &&
215+
stopElement.TryGetProperty("Color", out var colorElement) &&
216+
offsetElement.ValueKind == JsonValueKind.Number &&
217+
colorElement.ValueKind == JsonValueKind.String)
218+
{
219+
var offset = offsetElement.GetDouble();
220+
var color = colorElement.GetString()!;
221+
222+
if (offset < 0 || offset > 1 || !IsValidHexColor(color))
223+
{
224+
throw new InvalidDataException("Invalid gradient stop data.");
225+
}
226+
227+
gradientStops.Add(new GradientStops { Offset = offset, Color = color });
228+
}
229+
else
230+
{
231+
throw new InvalidDataException("Invalid gradient stop format.");
232+
}
233+
}
234+
235+
double gradientAngle = vm.GradientAngle;
236+
if (root.TryGetProperty("GradientAngle", out var angleElement) &&
237+
angleElement.ValueKind == JsonValueKind.Number)
238+
{
239+
var angle = angleElement.GetDouble();
240+
if (angle >= 0 && angle <= 360)
241+
{
242+
gradientAngle = angle;
243+
}
244+
}
245+
246+
vm.GradientStops.Clear();
247+
foreach (var stop in gradientStops)
248+
{
249+
vm.GradientStops.Add(stop);
250+
}
251+
252+
vm.GradientAngle = gradientAngle;
253+
App.Settings.Prop.CustomGradientStops = vm.GradientStops.ToList();
254+
App.Settings.Prop.GradientAngle = gradientAngle;
255+
256+
UpdateGradientTheme();
257+
258+
Frontend.ShowMessageBox(
259+
"Gradient imported successfully!",
260+
MessageBoxImage.Information,
261+
MessageBoxButton.OK
262+
);
263+
}
264+
catch (Exception ex)
265+
{
266+
Frontend.ShowMessageBox(
267+
$"Failed to import gradient: {ex.Message}",
268+
MessageBoxImage.Error,
269+
MessageBoxButton.OK
270+
);
271+
}
272+
}
273+
}
274+
140275
private static bool IsValidHexColor(string color) => !string.IsNullOrWhiteSpace(color) && color.StartsWith("#") && color.Length >= 7;
141276

142277
private void MoveUp_Click(object sender, RoutedEventArgs e)

Bloxstrap/UI/ViewModels/Settings/AppearanceViewModel.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ private void ManageCustomFont(string action)
6565
{
6666
if (action == "Choose")
6767
{
68-
var dialog = new Microsoft.Win32.OpenFileDialog
68+
var dialog = new OpenFileDialog
6969
{
7070
Filter = "Font files (*.ttf;*.otf)|*.ttf;*.otf|All files (*.*)|*.*"
7171
};
@@ -80,7 +80,6 @@ private void ManageCustomFont(string action)
8080
{
8181
FontManager.ApplyFontGlobally(fontFamily);
8282
App.Settings.Prop.CustomFontPath = fontPath;
83-
App.Settings.Save();
8483

8584
UpdateFontVisibility();
8685

Bloxstrap/UI/ViewModels/Settings/BehaviourViewModel.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ public void AddProcessExclusion(string processName)
128128
if (!UserExcludedProcesses.Contains(cleanName, StringComparer.OrdinalIgnoreCase))
129129
{
130130
UserExcludedProcesses.Add(cleanName);
131-
App.Settings.Save();
132131
OnPropertyChanged(nameof(UserExcludedProcesses));
133132
NewProcessName = "";
134133
}
@@ -141,7 +140,6 @@ public void RemoveProcessExclusion(string processName)
141140
if (item != null)
142141
{
143142
UserExcludedProcesses.Remove(item);
144-
App.Settings.Save();
145143
OnPropertyChanged(nameof(UserExcludedProcesses));
146144
SelectedProcess = "";
147145
EditProcessName = "";
@@ -166,7 +164,6 @@ public void UpdateProcessExclusion(string oldName, string newName)
166164
if (index >= 0)
167165
{
168166
UserExcludedProcesses[index] = cleanNewName;
169-
App.Settings.Save();
170167
OnPropertyChanged(nameof(UserExcludedProcesses));
171168
SelectedProcess = cleanNewName;
172169
EditProcessName = cleanNewName;

0 commit comments

Comments
 (0)