diff --git a/WheelWizard/Services/ModManager.cs b/WheelWizard/Services/ModManager.cs
index 3cce2a06..b51cb587 100644
--- a/WheelWizard/Services/ModManager.cs
+++ b/WheelWizard/Services/ModManager.cs
@@ -30,7 +30,6 @@ private set
}
}
- private bool _isProcessing;
private bool _isBatchUpdating;
private ModManager()
@@ -107,17 +106,23 @@ private void Mod_PropertyChanged(object sender, PropertyChangedEventArgs e)
if (_isBatchUpdating)
return;
- if (
- e.PropertyName != nameof(Mod.IsEnabled)
- && e.PropertyName != nameof(Mod.Title)
- && e.PropertyName != nameof(Mod.Author)
- && e.PropertyName != nameof(Mod.ModID)
- && e.PropertyName != nameof(Mod.Priority)
- )
+ if (e.PropertyName == nameof(Mod.Priority))
+ {
+ SaveModsAsync();
+ SortModsByPriority();
return;
+ }
- SaveModsAsync();
- SortModsByPriority();
+ if (
+ e.PropertyName == nameof(Mod.IsEnabled)
+ || e.PropertyName == nameof(Mod.Title)
+ || e.PropertyName == nameof(Mod.Author)
+ || e.PropertyName == nameof(Mod.ModID)
+ )
+ {
+ SaveModsAsync();
+ OnPropertyChanged(nameof(Mods));
+ }
}
private void SortModsByPriority()
@@ -207,12 +212,18 @@ await Task.Run(() =>
public void ToggleAllMods(bool enable)
{
- foreach (var mod in Mods)
+ _isBatchUpdating = true;
+ try
+ {
+ foreach (var mod in Mods)
+ mod.IsEnabled = enable;
+ }
+ finally
{
- mod.IsEnabled = enable;
+ _isBatchUpdating = false;
}
- _isProcessing = !_isProcessing;
+ SaveModsAsync();
OnPropertyChanged(nameof(Mods));
}
diff --git a/WheelWizard/Views/App.axaml b/WheelWizard/Views/App.axaml
index f7afb145..1b9991a0 100644
--- a/WheelWizard/Views/App.axaml
+++ b/WheelWizard/Views/App.axaml
@@ -49,27 +49,27 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/WheelWizard/Views/App.axaml.cs b/WheelWizard/Views/App.axaml.cs
index e1d16884..32ba582c 100644
--- a/WheelWizard/Views/App.axaml.cs
+++ b/WheelWizard/Views/App.axaml.cs
@@ -6,6 +6,7 @@
using WheelWizard.Services;
using WheelWizard.Services.LiveData;
using WheelWizard.Services.UrlProtocol;
+using WheelWizard.Views.Behaviors;
using WheelWizard.WheelWizardData;
using WheelWizard.WiiManagement;
using WheelWizard.WiiManagement.GameLicense;
@@ -38,6 +39,13 @@ public void SetServiceProvider(IServiceProvider serviceProvider)
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
+ InitializeBehaviorOverrides();
+ }
+
+ private void InitializeBehaviorOverrides()
+ {
+ //Behavior overrides are native components where we are overriding the behavior of
+ ToolTipBubbleBehavior.Initialize();
}
private static void OpenGameBananaModWindow()
diff --git a/WheelWizard/Views/Behaviors/ToolTipBubbleBehavior.cs b/WheelWizard/Views/Behaviors/ToolTipBubbleBehavior.cs
new file mode 100644
index 00000000..80d17f1c
--- /dev/null
+++ b/WheelWizard/Views/Behaviors/ToolTipBubbleBehavior.cs
@@ -0,0 +1,355 @@
+using System.Runtime.CompilerServices;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Diagnostics;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using Avalonia.Threading;
+
+namespace WheelWizard.Views.Behaviors;
+
+public static class ToolTipBubbleBehavior
+{
+ private const string BubblePointerLeftClass = "BubblePointerLeft";
+ private const string BubblePointerMiddleClass = "BubblePointerMiddle";
+ private const string BubblePointerRightClass = "BubblePointerRight";
+ private const string BubbleAnimateInClass = "BubbleAnimateIn";
+ private const string BubbleAnimateOutClass = "BubbleAnimateOut";
+ private const double TailCenterOffsetFromSide = 22d;
+ private const double TooltipVerticalOffset = -4d;
+ private static readonly TimeSpan HoverOpenDelay = TimeSpan.FromMilliseconds(200);
+ private static readonly TimeSpan MinimumVisibleTime = TimeSpan.FromSeconds(1);
+ private static readonly TimeSpan CloseAnimationDuration = TimeSpan.FromMilliseconds(40);
+ private static readonly ConditionalWeakTable ToolTipStates = new();
+ private static bool _isInitialized;
+
+ public static void Initialize()
+ {
+ if (_isInitialized)
+ return;
+
+ _isInitialized = true;
+ ToolTip.TipProperty.Changed.AddClassHandler(OnTipChanged);
+ ToolTip.ToolTipOpeningEvent.AddClassHandler(OnToolTipOpening);
+ ToolTip.IsOpenProperty.Changed.AddClassHandler(OnIsOpenChanged);
+ InputElement.IsPointerOverProperty.Changed.AddClassHandler(OnIsPointerOverChanged);
+ }
+
+ private static void OnTipChanged(Control control, AvaloniaPropertyChangedEventArgs args)
+ {
+ var newTip = args.GetNewValue