Skip to content

Commit

Permalink
LivelyProperties performance rewrite
Browse files Browse the repository at this point in the history
- Rewrote LivelyProperties to use templating, virtualization and JsonConverter.
Instant startup time and can handle 100k+ controls (old version crashes.)
- LivelyProperties disk file is only updated on dialog/window close.
- x:Load workaround for microsoft/microsoft-ui-xaml#8412
- New FolderDropdown UserControl.
- Removed broken ImageEx UserControl.
- Refactoring.
  • Loading branch information
rocksdanister committed Apr 22, 2024
1 parent b935a52 commit c8e3a02
Show file tree
Hide file tree
Showing 41 changed files with 1,847 additions and 1,259 deletions.
11 changes: 11 additions & 0 deletions src/Lively/Lively.Common/Helpers/Files/FileUtil.cs
Expand Up @@ -125,6 +125,17 @@ public static void EmptyDirectory(string directory)
}
}

public static List<string> GetFiles(string path, string searchPattern, SearchOption searchOption)
{
var searchPatterns = searchPattern.Split('|');
var files = new List<string>();
foreach (string sp in searchPatterns)
files.AddRange(Directory.GetFiles(path, sp, searchOption));
files.Sort();

return files;
}

/// <summary>
/// Checks if file is greater than the given byte, false if exception
/// </summary>
Expand Down
17 changes: 17 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/ButtonModel.cs
@@ -0,0 +1,17 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class ButtonModel : ControlModel
{
[JsonProperty("value")]
public string Value { get; set; }

public ButtonModel() : base("button") { }
}
}
17 changes: 17 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/CheckboxModel.cs
@@ -0,0 +1,17 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class CheckboxModel : ControlModel
{
[JsonProperty("value")]
public bool Value { get; set; }

public CheckboxModel() : base("checkbox") { }
}
}
17 changes: 17 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/ColorPickerModel.cs
@@ -0,0 +1,17 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class ColorPickerModel : ControlModel
{
[JsonProperty("value")]
public string Value { get; set; }

public ColorPickerModel() : base("color") { }
}
}
30 changes: 30 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/ControlModel.cs
@@ -0,0 +1,30 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class ControlModel
{
[JsonIgnore]
[JsonProperty("name")]
public string Name { get; set; }

[JsonProperty("text")]
public string Text { get; set; }

[JsonProperty("type")]
public string Type { get; }

[JsonProperty("help")]
public string Help { get; set; }

protected ControlModel(string Type)
{
this.Type = Type;
}
}
}
20 changes: 20 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/DropdownModel.cs
@@ -0,0 +1,20 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class DropdownModel : ControlModel
{
[JsonProperty("value")]
public int Value { get; set; }

[JsonProperty("items")]
public string[] Items { get; set; }

public DropdownModel() : base("dropdown") { }
}
}
23 changes: 23 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/FolderDropdownModel.cs
@@ -0,0 +1,23 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class FolderDropdownModel : ControlModel
{
[JsonProperty("value")]
public string Value { get; set; }

[JsonProperty("folder")]
public string Folder { get; set; }

[JsonProperty("filter")]
public string Filter { get; set; }

public FolderDropdownModel() : base("folderDropdown") { }
}
}
17 changes: 17 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/LabelModel.cs
@@ -0,0 +1,17 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class LabelModel : ControlModel
{
[JsonProperty("value")]
public string Value { get; set; }

public LabelModel() : base("label") { }
}
}
20 changes: 20 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/ScalerDropdownModel.cs
@@ -0,0 +1,20 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class ScalerDropdownModel : ControlModel
{
[JsonProperty("value")]
public int Value { get; set; }

[JsonProperty("items")]
public string[] Items { get; set; }

public ScalerDropdownModel() : base("scalerDropdown") { }
}
}
31 changes: 31 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/SliderModel.cs
@@ -0,0 +1,31 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class SliderModel : ControlModel
{
[JsonIgnore]
[JsonProperty("tick")]
public int Tick { get; set; }

[JsonProperty("min")]
public double Min { get; set; }

[JsonProperty("max")]
public double Max { get; set; }

[JsonProperty("value")]
public double Value { get; set; }

// Default value 1, otherwise if missing it will be 0 and crash on moving slider.
[JsonProperty("step")]
public double Step { get; set; } = 1f;

public SliderModel() : base("slider") { }
}
}
17 changes: 17 additions & 0 deletions src/Lively/Lively.Models/LivelyControls/TextboxModel.cs
@@ -0,0 +1,17 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lively.Models.LivelyControls
{
public class TextboxModel : ControlModel
{
[JsonProperty("value")]
public string Value { get; set; }

public TextboxModel() : base("textbox") { }
}
}
@@ -0,0 +1,19 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Text;

namespace Lively.Models.UserControls
{
public partial class FolderDropdownUserControlModel : ObservableObject
{
[ObservableProperty]
private string fileName;

[ObservableProperty]
private string filePath;

[ObservableProperty]
private string imagePath;
}
}
11 changes: 8 additions & 3 deletions src/Lively/Lively.UI.WinUI/App.xaml.cs
Expand Up @@ -105,14 +105,18 @@ protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs ar
{
var libraryVm = Services.GetRequiredService<LibraryViewModel>();
var model = libraryVm.LibraryItems.FirstOrDefault(x => selection.LivelyInfoFolderPath == x.LivelyInfoFolderPath);
var viewModel = App.Services.GetRequiredService<CustomiseWallpaperViewModel>();
if (model is not null)
{
var tray = new LivelyPropertiesTray(model);
tray.Closed += (s, e) =>
var window = new LivelyPropertiesTray(viewModel);
window.Title = model.Title;
window.Closed += (s, e) =>
{
viewModel.OnClose();
App.ShutDown();
};
tray.Show();
viewModel.Load(model);
window.Show();
}
}
}
Expand Down Expand Up @@ -160,6 +164,7 @@ private IServiceProvider ConfigureServices()
//transient
//.AddTransient<HelpViewModel>()
.AddTransient<AboutViewModel>()
.AddTransient<CustomiseWallpaperViewModel>()
.AddTransient<PatreonSupportersViewModel>()
.AddTransient<AddWallpaperViewModel>()
.AddTransient<ControlPanelViewModel>()
Expand Down
@@ -0,0 +1,62 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Lively.UI.WinUI.Behaviors
{
public class CheckBoxCheckedChangedBehavior
{
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(CheckBoxCheckedChangedBehavior), new PropertyMetadata(null, OnCommandChanged));

public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached("CommandParameter", typeof(object), typeof(CheckBoxCheckedChangedBehavior), new PropertyMetadata(null));

public static ICommand GetCommand(CheckBox checkBox)
{
return (ICommand)checkBox.GetValue(CommandProperty);
}

public static void SetCommand(CheckBox checkBox, ICommand value)
{
checkBox.SetValue(CommandProperty, value);
}

public static object GetCommandParameter(CheckBox checkBox)
{
return checkBox.GetValue(CommandParameterProperty);
}

public static void SetCommandParameter(CheckBox checkBox, object value)
{
checkBox.SetValue(CommandParameterProperty, value);
}

private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is CheckBox checkBox)
{
checkBox.Checked -= OnCheckBoxCheckedChanged;
checkBox.Unchecked -= OnCheckBoxCheckedChanged;
if (e.NewValue is ICommand command)
{
checkBox.Checked += OnCheckBoxCheckedChanged;
checkBox.Unchecked += OnCheckBoxCheckedChanged;
}
}
}

private static void OnCheckBoxCheckedChanged(object sender, RoutedEventArgs e)
{
if (sender is CheckBox checkBox && GetCommand(checkBox) != null && GetCommand(checkBox).CanExecute(GetCommandParameter(checkBox)))
{
GetCommand(checkBox).Execute(GetCommandParameter(checkBox));
}
}
}
}

0 comments on commit c8e3a02

Please sign in to comment.