mirror of
https://github.com/Stone-Red-Code/DesktopMagic.git
synced 2026-09-04 00:46:12 +02:00
Fix plugin settings sync when multiple monitors use same layout
This commit is contained in:
@@ -58,9 +58,6 @@ public class WeatherPlugin : AsyncPlugin
|
|||||||
showTime.OnValueChanged += Application.UpdateWindow;
|
showTime.OnValueChanged += Application.UpdateWindow;
|
||||||
fontSizeSlider.OnValueChanged += Application.UpdateWindow;
|
fontSizeSlider.OnValueChanged += Application.UpdateWindow;
|
||||||
|
|
||||||
await UpdateLocationAndWeather();
|
|
||||||
Application.UpdateWindow();
|
|
||||||
|
|
||||||
searchButton.OnClick += () =>
|
searchButton.OnClick += () =>
|
||||||
{
|
{
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
@@ -73,6 +70,9 @@ public class WeatherPlugin : AsyncPlugin
|
|||||||
Application.UpdateWindow();
|
Application.UpdateWindow();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
await UpdateLocationAndWeather();
|
||||||
|
Application.UpdateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<Bitmap?> MainAsync(CancellationToken cancellationToken)
|
public override async Task<Bitmap?> MainAsync(CancellationToken cancellationToken)
|
||||||
|
|||||||
@@ -291,6 +291,32 @@ public sealed class Manager
|
|||||||
SaveSettings();
|
SaveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly Dictionary<(Layout, uint), SettingSynchronizer> settingSynchronizers = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets (or creates) the synchronizer that keeps the settings of all windows showing the
|
||||||
|
/// given plugin in the given layout in sync.
|
||||||
|
/// </summary>
|
||||||
|
internal SettingSynchronizer GetSettingSynchronizer(Layout layout, uint pluginId)
|
||||||
|
{
|
||||||
|
(Layout, uint) key = (layout, pluginId);
|
||||||
|
if (!settingSynchronizers.TryGetValue(key, out SettingSynchronizer? synchronizer))
|
||||||
|
{
|
||||||
|
synchronizer = new SettingSynchronizer();
|
||||||
|
settingSynchronizers.Add(key, synchronizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return synchronizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Drops the synchronizer for the given plugin in the given layout once no windows use it anymore.
|
||||||
|
/// </summary>
|
||||||
|
internal void ReleaseSettingSynchronizer(Layout layout, uint pluginId)
|
||||||
|
{
|
||||||
|
_ = settingSynchronizers.Remove((layout, pluginId));
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Settings Management
|
#region Settings Management
|
||||||
|
|||||||
@@ -21,5 +21,8 @@ public interface IPluginWindow
|
|||||||
void Hide();
|
void Hide();
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
void ApplySettingValue(string id, string value);
|
||||||
|
void ApplyButtonClick(string id);
|
||||||
|
|
||||||
event System.ComponentModel.CancelEventHandler Closing;
|
event System.ComponentModel.CancelEventHandler Closing;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using DesktopMagic.Settings;
|
|||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@@ -44,6 +45,7 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
private readonly Rectangle screenBounds;
|
private readonly Rectangle screenBounds;
|
||||||
private readonly string screenDeviceName;
|
private readonly string screenDeviceName;
|
||||||
private bool isUpdatingPosition = false;
|
private bool isUpdatingPosition = false;
|
||||||
|
private bool _editMode = false;
|
||||||
|
|
||||||
private CancellationTokenSource? pluginCancellationTokenSource;
|
private CancellationTokenSource? pluginCancellationTokenSource;
|
||||||
private FileSystemWatcher? pluginFileWatcher;
|
private FileSystemWatcher? pluginFileWatcher;
|
||||||
@@ -58,8 +60,13 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
private readonly PropertyChangedEventHandler themePropertyChangedHandler;
|
private readonly PropertyChangedEventHandler themePropertyChangedHandler;
|
||||||
private Theme? subscribedTheme;
|
private Theme? subscribedTheme;
|
||||||
private NotifyCollectionChangedEventHandler? themesCollectionChangedHandler;
|
private NotifyCollectionChangedEventHandler? themesCollectionChangedHandler;
|
||||||
private readonly List<Setting> subscribedSettings = [];
|
private readonly List<(Setting Setting, Action Handler)> subscribedSettings = [];
|
||||||
private readonly List<(Setting Setting, Action Handler)> defaultSettingsSubscriptions = [];
|
private readonly List<(Setting Setting, Action Handler)> defaultSettingsSubscriptions = [];
|
||||||
|
private readonly List<(Button Button, Action Handler)> subscribedButtonClicks = [];
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, Setting> localSettings = [];
|
||||||
|
private SettingSynchronizer? synchronizer;
|
||||||
|
private bool suppressButtonSync = false;
|
||||||
|
|
||||||
public bool IsRunning { get; private set; } = true;
|
public bool IsRunning { get; private set; } = true;
|
||||||
public PluginMetadata PluginMetadata { get; private set; }
|
public PluginMetadata PluginMetadata { get; private set; }
|
||||||
@@ -121,6 +128,12 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
|
|
||||||
PluginFolderPath = pluginFolderPath;
|
PluginFolderPath = pluginFolderPath;
|
||||||
|
|
||||||
|
if (settings.Owner is not null)
|
||||||
|
{
|
||||||
|
synchronizer = Manager.Instance.GetSettingSynchronizer(settings.Owner, PluginMetadata.Id);
|
||||||
|
synchronizer.Register(this);
|
||||||
|
}
|
||||||
|
|
||||||
assemblyLoadContext = CreateAssemblyLoadContext();
|
assemblyLoadContext = CreateAssemblyLoadContext();
|
||||||
|
|
||||||
// Initialize hot reload watcher if plugin supports unloading and is external
|
// Initialize hot reload watcher if plugin supports unloading and is external
|
||||||
@@ -346,6 +359,8 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
|
|
||||||
public void SetEditMode(bool enabled)
|
public void SetEditMode(bool enabled)
|
||||||
{
|
{
|
||||||
|
_editMode = enabled;
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
Topmost = true;
|
Topmost = true;
|
||||||
@@ -646,7 +661,14 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
|
|
||||||
void SetWindowLayer()
|
void SetWindowLayer()
|
||||||
{
|
{
|
||||||
WindowPos.SetWindowLayer(this, pluginClassInstance.windowLayer.Value);
|
if (_editMode)
|
||||||
|
{
|
||||||
|
Topmost = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WindowPos.SetWindowLayer(this, pluginClassInstance.windowLayer.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRotation()
|
void SetRotation()
|
||||||
@@ -686,7 +708,7 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
defaultSettingsSubscriptions.Add((setting, handler));
|
defaultSettingsSubscriptions.Add((setting, handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPluginSettingValueChanged()
|
private void OnPluginSettingValueChanged(Setting setting, string id)
|
||||||
{
|
{
|
||||||
pluginClassInstance?.OnSettingsChanged();
|
pluginClassInstance?.OnSettingsChanged();
|
||||||
|
|
||||||
@@ -694,6 +716,34 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
{
|
{
|
||||||
pluginClassInstance.Application.UpdateWindow();
|
pluginClassInstance.Application.UpdateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronizer?.SettingChanged(this, id, setting.GetJsonValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplySettingValue(string id, string value)
|
||||||
|
{
|
||||||
|
if (localSettings.TryGetValue(id, out Setting? setting) && setting.GetJsonValue() != value)
|
||||||
|
{
|
||||||
|
setting.SetJsonValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyButtonClick(string id)
|
||||||
|
{
|
||||||
|
if (!localSettings.TryGetValue(id, out Setting? setting) || setting is not Button button)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
suppressButtonSync = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
button.Click();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
suppressButtonSync = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadOptions(object instance)
|
private async Task LoadOptions(object instance)
|
||||||
@@ -713,16 +763,36 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
{
|
{
|
||||||
if (attribute is SettingAttribute elementAttribute)
|
if (attribute is SettingAttribute elementAttribute)
|
||||||
{
|
{
|
||||||
|
localSettings[elementAttribute.Id] = element;
|
||||||
|
|
||||||
SettingElement settingElement = new SettingElement(element, elementAttribute.Id, elementAttribute.Name, elementAttribute.OrderIndex);
|
SettingElement settingElement = new SettingElement(element, elementAttribute.Id, elementAttribute.Name, elementAttribute.OrderIndex);
|
||||||
|
|
||||||
if (settings.Settings.Exists(e => e.Id == elementAttribute.Id))
|
if (settings.Settings.Exists(e => e.Id == elementAttribute.Id))
|
||||||
{
|
{
|
||||||
SettingElement settingsSettingElement = settings.Settings.First(e => e.Id == elementAttribute.Id);
|
SettingElement settingsSettingElement = settings.Settings.First(e => e.Id == elementAttribute.Id);
|
||||||
settingElement.JsonValue = settingsSettingElement.JsonValue;
|
string savedValue = settingsSettingElement.JsonValue;
|
||||||
|
if (!string.IsNullOrEmpty(savedValue) || element is not Label and not Button)
|
||||||
|
{
|
||||||
|
settingElement.JsonValue = savedValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
element.OnValueChanged += OnPluginSettingValueChanged;
|
Action valueChangedHandler = () => OnPluginSettingValueChanged(element, elementAttribute.Id);
|
||||||
subscribedSettings.Add(element);
|
element.OnValueChanged += valueChangedHandler;
|
||||||
|
subscribedSettings.Add((element, valueChangedHandler));
|
||||||
|
|
||||||
|
if (element is Button button)
|
||||||
|
{
|
||||||
|
Action clickHandler = () =>
|
||||||
|
{
|
||||||
|
if (!suppressButtonSync)
|
||||||
|
{
|
||||||
|
synchronizer?.ButtonClicked(this, elementAttribute.Id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
button.OnClick += clickHandler;
|
||||||
|
subscribedButtonClicks.Add((button, clickHandler));
|
||||||
|
}
|
||||||
|
|
||||||
settingElements.Add(settingElement);
|
settingElements.Add(settingElement);
|
||||||
break;
|
break;
|
||||||
@@ -1070,6 +1140,15 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
|
|
||||||
UnsubscribeEvents();
|
UnsubscribeEvents();
|
||||||
DetachSettings();
|
DetachSettings();
|
||||||
|
|
||||||
|
if (synchronizer is not null && settings.Owner is not null)
|
||||||
|
{
|
||||||
|
if (synchronizer.Unregister(this))
|
||||||
|
{
|
||||||
|
Manager.Instance.ReleaseSettingSynchronizer(settings.Owner, PluginMetadata.Id);
|
||||||
|
}
|
||||||
|
synchronizer = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DetachSettings()
|
private void DetachSettings()
|
||||||
@@ -1098,9 +1177,9 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
themesCollectionChangedHandler = null;
|
themesCollectionChangedHandler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Setting setting in subscribedSettings)
|
foreach ((Setting Setting, Action Handler) subscription in subscribedSettings)
|
||||||
{
|
{
|
||||||
setting.OnValueChanged -= OnPluginSettingValueChanged;
|
subscription.Setting.OnValueChanged -= subscription.Handler;
|
||||||
}
|
}
|
||||||
subscribedSettings.Clear();
|
subscribedSettings.Clear();
|
||||||
|
|
||||||
@@ -1109,6 +1188,14 @@ public partial class PluginWindow : Window, IPluginWindow
|
|||||||
subscription.Setting.OnValueChanged -= subscription.Handler;
|
subscription.Setting.OnValueChanged -= subscription.Handler;
|
||||||
}
|
}
|
||||||
defaultSettingsSubscriptions.Clear();
|
defaultSettingsSubscriptions.Clear();
|
||||||
|
|
||||||
|
foreach ((Button Button, Action Handler) subscription in subscribedButtonClicks)
|
||||||
|
{
|
||||||
|
subscription.Button.OnClick -= subscription.Handler;
|
||||||
|
}
|
||||||
|
subscribedButtonClicks.Clear();
|
||||||
|
|
||||||
|
localSettings.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePosition()
|
private void UpdatePosition()
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
|
||||||
|
namespace DesktopMagic.Plugins;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Keeps the per-instance plugin settings of every window sharing the same layout in sync.
|
||||||
|
/// Each window owns its own <see cref="DesktopMagic.Api.Settings.Setting"/> objects (plugins
|
||||||
|
/// hold them in readonly fields and subscribe to them in Start), so a value change on one
|
||||||
|
/// window has to be mirrored onto the sibling windows.
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class SettingSynchronizer
|
||||||
|
{
|
||||||
|
private readonly object _lock = new();
|
||||||
|
private readonly List<IPluginWindow> windows = [];
|
||||||
|
private readonly HashSet<(IPluginWindow Window, string Id)> inFlight = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a window so it receives mirrored settings from the other windows of this layout.
|
||||||
|
/// </summary>
|
||||||
|
public void Register(IPluginWindow window)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
if (!windows.Contains(window))
|
||||||
|
{
|
||||||
|
windows.Add(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unregisters a window and returns whether no windows remain.
|
||||||
|
/// </summary>
|
||||||
|
public bool Unregister(IPluginWindow window)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
windows.Remove(window);
|
||||||
|
return windows.Count == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mirrors a setting value change onto every other registered window.
|
||||||
|
/// </summary>
|
||||||
|
public void SettingChanged(IPluginWindow origin, string id, string value)
|
||||||
|
{
|
||||||
|
Mirror(origin, id, window => window.ApplySettingValue(id, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mirrors a button click onto every other registered window.
|
||||||
|
/// </summary>
|
||||||
|
public void ButtonClicked(IPluginWindow origin, string id)
|
||||||
|
{
|
||||||
|
Mirror(origin, id, window => window.ApplyButtonClick(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Mirror(IPluginWindow origin, string id, Action<IPluginWindow> apply)
|
||||||
|
{
|
||||||
|
IPluginWindow[] snapshot;
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
snapshot = windows.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (IPluginWindow window in snapshot)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(window, origin) || !window.IsRunning)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
if (!inFlight.Add((window, id)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window is not DispatcherObject dispatcherObject)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
inFlight.Remove((window, id));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = dispatcherObject.Dispatcher.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
apply(window);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
inFlight.Remove((window, id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ using DesktopMagic.Settings;
|
|||||||
using Microsoft.Web.WebView2.Core;
|
using Microsoft.Web.WebView2.Core;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -41,6 +42,10 @@ public partial class WebPluginWindow : Window, IPluginWindow
|
|||||||
private readonly List<(Setting Setting, Action Handler)> subscribedSettings = [];
|
private readonly List<(Setting Setting, Action Handler)> subscribedSettings = [];
|
||||||
private readonly List<(Button Button, Action Handler)> subscribedButtonClicks = [];
|
private readonly List<(Button Button, Action Handler)> subscribedButtonClicks = [];
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, Setting> localSettings = [];
|
||||||
|
private SettingSynchronizer? synchronizer;
|
||||||
|
private bool suppressButtonSync = false;
|
||||||
|
|
||||||
public bool IsRunning { get; private set; } = true;
|
public bool IsRunning { get; private set; } = true;
|
||||||
public PluginMetadata PluginMetadata { get; private set; }
|
public PluginMetadata PluginMetadata { get; private set; }
|
||||||
public string PluginFolderPath { get; private set; }
|
public string PluginFolderPath { get; private set; }
|
||||||
@@ -101,6 +106,12 @@ public partial class WebPluginWindow : Window, IPluginWindow
|
|||||||
|
|
||||||
PluginFolderPath = pluginFolderPath;
|
PluginFolderPath = pluginFolderPath;
|
||||||
|
|
||||||
|
if (settings.Owner is not null)
|
||||||
|
{
|
||||||
|
synchronizer = Manager.Instance.GetSettingSynchronizer(settings.Owner, PluginMetadata.Id);
|
||||||
|
synchronizer.Register(this);
|
||||||
|
}
|
||||||
|
|
||||||
if (pluginMetadata.SupportsUnloading && !string.IsNullOrEmpty(pluginFolderPath))
|
if (pluginMetadata.SupportsUnloading && !string.IsNullOrEmpty(pluginFolderPath))
|
||||||
{
|
{
|
||||||
InitializeHotReload();
|
InitializeHotReload();
|
||||||
@@ -157,6 +168,32 @@ public partial class WebPluginWindow : Window, IPluginWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ApplySettingValue(string id, string value)
|
||||||
|
{
|
||||||
|
if (localSettings.TryGetValue(id, out Setting? setting) && setting.GetJsonValue() != value)
|
||||||
|
{
|
||||||
|
setting.SetJsonValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyButtonClick(string id)
|
||||||
|
{
|
||||||
|
if (!localSettings.TryGetValue(id, out Setting? setting) || setting is not Button button)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
suppressButtonSync = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
button.Click();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
suppressButtonSync = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnSourceInitialized(EventArgs e)
|
protected override void OnSourceInitialized(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnSourceInitialized(e);
|
base.OnSourceInitialized(e);
|
||||||
@@ -290,6 +327,15 @@ public partial class WebPluginWindow : Window, IPluginWindow
|
|||||||
|
|
||||||
UnsubscribeEvents();
|
UnsubscribeEvents();
|
||||||
|
|
||||||
|
if (synchronizer is not null && settings.Owner is not null)
|
||||||
|
{
|
||||||
|
if (synchronizer.Unregister(this))
|
||||||
|
{
|
||||||
|
Manager.Instance.ReleaseSettingSynchronizer(settings.Owner, PluginMetadata.Id);
|
||||||
|
}
|
||||||
|
synchronizer = null;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (isInitialized && webView.CoreWebView2 != null)
|
if (isInitialized && webView.CoreWebView2 != null)
|
||||||
@@ -324,6 +370,8 @@ public partial class WebPluginWindow : Window, IPluginWindow
|
|||||||
button.OnClick -= handler;
|
button.OnClick -= handler;
|
||||||
}
|
}
|
||||||
subscribedButtonClicks.Clear();
|
subscribedButtonClicks.Clear();
|
||||||
|
|
||||||
|
localSettings.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePosition()
|
private void UpdatePosition()
|
||||||
@@ -450,12 +498,18 @@ public partial class WebPluginWindow : Window, IPluginWindow
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
localSettings[id] = setting;
|
||||||
|
|
||||||
SettingElement settingElement = new(setting, id, name, orderIndex);
|
SettingElement settingElement = new(setting, id, name, orderIndex);
|
||||||
|
|
||||||
if (settings.Settings.Exists(e => e.Id == id))
|
if (settings.Settings.Exists(e => e.Id == id))
|
||||||
{
|
{
|
||||||
SettingElement saved = settings.Settings.First(e => e.Id == id);
|
SettingElement saved = settings.Settings.First(e => e.Id == id);
|
||||||
settingElement.JsonValue = saved.JsonValue;
|
string savedValue = saved.JsonValue;
|
||||||
|
if (!string.IsNullOrEmpty(savedValue) || setting is not Label and not Button)
|
||||||
|
{
|
||||||
|
settingElement.JsonValue = savedValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string capturedId = id;
|
string capturedId = id;
|
||||||
@@ -463,6 +517,11 @@ public partial class WebPluginWindow : Window, IPluginWindow
|
|||||||
{
|
{
|
||||||
Action clickHandler = () =>
|
Action clickHandler = () =>
|
||||||
{
|
{
|
||||||
|
if (!suppressButtonSync)
|
||||||
|
{
|
||||||
|
synchronizer?.ButtonClicked(this, capturedId);
|
||||||
|
}
|
||||||
|
|
||||||
_ = webView.Dispatcher.InvokeAsync(async () =>
|
_ = webView.Dispatcher.InvokeAsync(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -481,6 +540,8 @@ public partial class WebPluginWindow : Window, IPluginWindow
|
|||||||
|
|
||||||
Action valueChangedHandler = () =>
|
Action valueChangedHandler = () =>
|
||||||
{
|
{
|
||||||
|
synchronizer?.SettingChanged(this, capturedId, setting.GetJsonValue());
|
||||||
|
|
||||||
_ = webView.Dispatcher.InvokeAsync(async () =>
|
_ = webView.Dispatcher.InvokeAsync(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -46,4 +46,14 @@ public class Button : Setting
|
|||||||
{
|
{
|
||||||
OnClick?.Invoke();
|
OnClick?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal override string GetJsonValue()
|
||||||
|
{
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void SetJsonValue(string value)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -38,4 +38,14 @@ public class Label : Setting
|
|||||||
Value = value;
|
Value = value;
|
||||||
Bold = bold;
|
Bold = bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal override string GetJsonValue()
|
||||||
|
{
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void SetJsonValue(string value)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user