diff --git a/src/CurvaLauncher.Common/IAsyncMenuQueryResult.cs b/src/CurvaLauncher.Common/IAsyncMenuQueryResult.cs new file mode 100644 index 0000000..a89cb08 --- /dev/null +++ b/src/CurvaLauncher.Common/IAsyncMenuQueryResult.cs @@ -0,0 +1,6 @@ +namespace CurvaLauncher; + +public interface IAsyncMenuQueryResult : IQueryResult +{ + public Task> GetMenuItemsAsync(CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/CurvaLauncher.Common/ISyncMenuQueryResult.cs b/src/CurvaLauncher.Common/ISyncMenuQueryResult.cs new file mode 100644 index 0000000..04c5aff --- /dev/null +++ b/src/CurvaLauncher.Common/ISyncMenuQueryResult.cs @@ -0,0 +1,6 @@ +namespace CurvaLauncher; + +public interface ISyncMenuQueryResult : IQueryResult +{ + public IEnumerable GetMenuItems(); +} \ No newline at end of file diff --git a/src/CurvaLauncher/MainWindow.xaml b/src/CurvaLauncher/MainWindow.xaml index 45c9698..e2e5fc2 100644 --- a/src/CurvaLauncher/MainWindow.xaml +++ b/src/CurvaLauncher/MainWindow.xaml @@ -32,9 +32,9 @@ + - @@ -42,6 +42,8 @@ + - @@ -128,7 +129,7 @@ - - + @@ -193,6 +195,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/CurvaLauncher/MainWindow.xaml.cs b/src/CurvaLauncher/MainWindow.xaml.cs index 9de56e2..423dfd8 100644 --- a/src/CurvaLauncher/MainWindow.xaml.cs +++ b/src/CurvaLauncher/MainWindow.xaml.cs @@ -61,7 +61,7 @@ private void WindowDeactivated(object sender, EventArgs e) ViewModel.QueryResults.Clear(); ViewModel.SelectedQueryResult = null; - resultBox.SelectedItem = null; + ResultBox.SelectedItem = null; App.CloseLauncher(); } @@ -69,8 +69,14 @@ private void WindowDeactivated(object sender, EventArgs e) private void QueryBox_PreviewKeyDown(object sender, KeyEventArgs e) { + if (ViewModel.ImmediateResults.Count != 0) + { + return; + } + if (e.Key == Key.Up && string.IsNullOrWhiteSpace(ViewModel.QueryText) && + !string.IsNullOrWhiteSpace(ViewModel.LastInvokedQueryText) && ViewModel.LastInvokedQueryText is string lastInvokedQueryText) { SetQueryText(lastInvokedQueryText); @@ -79,17 +85,22 @@ private void QueryBox_PreviewKeyDown(object sender, KeyEventArgs e) } [RelayCommand] - public void ScrollToSelectedQueryResult() + public void ScrollToSelectedItem(ListView? listView) { - if (resultBox.SelectedItem is null || - resultBox.SelectedIndex < 0) + if (listView is null) + { + return; + } + + if (listView.SelectedItem is null || + listView.SelectedIndex < 0) { return; } try { - resultBox.ScrollIntoView(resultBox.SelectedItem); + listView.ScrollIntoView(listView.SelectedItem); } catch { } } diff --git a/src/CurvaLauncher/Models/CurvaLauncherPluginInstance.cs b/src/CurvaLauncher/Models/CurvaLauncherPluginInstance.cs index 0d0b717..4510a97 100644 --- a/src/CurvaLauncher/Models/CurvaLauncherPluginInstance.cs +++ b/src/CurvaLauncher/Models/CurvaLauncherPluginInstance.cs @@ -11,13 +11,13 @@ namespace CurvaLauncher.Models; -public partial class CurvaLauncherPluginInstance : ObservableObject +public partial class PluginInstance : ObservableObject { public IPlugin Plugin { get; } public Task InitTask { get; private set; } = Task.CompletedTask; - private CurvaLauncherPluginInstance(IPlugin plugin) + private PluginInstance(IPlugin plugin) { Plugin = plugin; if (plugin is II18nPlugin i18nPlugin) @@ -78,7 +78,7 @@ public async IAsyncEnumerable QueryAsync(string query) } } - public static bool TryCreate(Type type, [NotNullWhen(true)] out CurvaLauncherPluginInstance? curvaLauncherPlugin) + public static bool TryCreate(Type type, [NotNullWhen(true)] out PluginInstance? curvaLauncherPlugin) { curvaLauncherPlugin = null; @@ -90,9 +90,9 @@ public static bool TryCreate(Type type, [NotNullWhen(true)] out CurvaLauncherPlu var plugin = Activator.CreateInstance(type, CurvaLauncherContextImpl.Instance); if (plugin is IAsyncPlugin asyncPlugin) - curvaLauncherPlugin = new CurvaLauncherPluginInstance(asyncPlugin); + curvaLauncherPlugin = new PluginInstance(asyncPlugin); else if (plugin is ISyncPlugin syncPlugin) - curvaLauncherPlugin = new CurvaLauncherPluginInstance(syncPlugin); + curvaLauncherPlugin = new PluginInstance(syncPlugin); return curvaLauncherPlugin != null; } diff --git a/src/CurvaLauncher/Models/ImmediateResults/ImmediateResult.cs b/src/CurvaLauncher/Models/ImmediateResults/ImmediateResult.cs index 6d18bd2..7858c08 100644 --- a/src/CurvaLauncher/Models/ImmediateResults/ImmediateResult.cs +++ b/src/CurvaLauncher/Models/ImmediateResults/ImmediateResult.cs @@ -2,10 +2,11 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.ComponentModel; namespace CurvaLauncher.Models.ImmediateResults { - public abstract class ImmediateResult + public abstract class ImmediateResult : ObservableObject { } diff --git a/src/CurvaLauncher/Models/ImmediateResults/MenuResult.cs b/src/CurvaLauncher/Models/ImmediateResults/MenuResult.cs new file mode 100644 index 0000000..ef7ac51 --- /dev/null +++ b/src/CurvaLauncher/Models/ImmediateResults/MenuResult.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Linq; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace CurvaLauncher.Models.ImmediateResults +{ + public partial class MenuResult : ImmediateResult + { + [ObservableProperty] + private int _selectedIndex; + + [ObservableProperty] + private QueryResultModel? _selectedItem; + + public IReadOnlyList Items { get; } + + public MenuResult(PluginInstance pluginInstance, IReadOnlyList items) + { + Items = items + .Select(item => new QueryResultModel(pluginInstance, item)) + .OrderByDescending(item => item.Weight) + .ToArray(); + } + } +} diff --git a/src/CurvaLauncher/Models/ImmediateResults/SubResultListResult.cs b/src/CurvaLauncher/Models/ImmediateResults/SubResultListResult.cs deleted file mode 100644 index ed23707..0000000 --- a/src/CurvaLauncher/Models/ImmediateResults/SubResultListResult.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; - -namespace CurvaLauncher.Models.ImmediateResults -{ - public class SubResultListResult : ImmediateResult - { - public IReadOnlyList Results { get; } - - public SubResultListResult(IReadOnlyList results) - { - Results = results; - } - } -} diff --git a/src/CurvaLauncher/Models/QueryResultModel.cs b/src/CurvaLauncher/Models/QueryResultModel.cs index 1d510f9..a9da6c9 100644 --- a/src/CurvaLauncher/Models/QueryResultModel.cs +++ b/src/CurvaLauncher/Models/QueryResultModel.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; @@ -16,25 +17,26 @@ namespace CurvaLauncher.Models; public partial class QueryResultModel : ObservableObject { + private readonly PluginInstance _pluginInstance; private readonly IQueryResult _rawQueryResult; - private QueryResultModel(float weight, string title, string description, ImageSource? icon, IQueryResult rawQueryResult) + public QueryResultModel(PluginInstance pluginInstance, IQueryResult rawQueryResult) { - Weight = weight; - Title = title; - Description = description; - _icon = icon; + _pluginInstance = pluginInstance; _rawQueryResult = rawQueryResult; + _icon = rawQueryResult.Icon; + + SetupFallbackIcon(() => pluginInstance.Plugin.Icon); } private ImageSource? _icon; - public float Weight { get; } - public string Title { get; } - public string Description { get; } + public float Weight => _pluginInstance.Weight * _rawQueryResult.Weight; + public string Title => _rawQueryResult.Title; + public string Description => _rawQueryResult.Description; public ImageSource? Icon => _icon; - public void SetFallbackIcon(Func iconFactory) + private void SetupFallbackIcon(Func iconFactory) { if (_icon == null) { @@ -58,70 +60,47 @@ public void SetFallbackIcon(Func iconFactory) .GetRequiredService() .Send(SaveQueryMessage.Instance); - if (_rawQueryResult is ISyncActionQueryResult syncQueryResult) + try { - try + if (_rawQueryResult is ISyncActionQueryResult syncQueryResult) { syncQueryResult.Invoke(); + App.CloseLauncher(); } - catch (Exception ex) - { - MessageBox.Show($"{ex.Message}", "CurvaLauncher Result Invoke failed", MessageBoxButton.OK, MessageBoxImage.Error); - } - - return null; - } - else if (_rawQueryResult is IAsyncActionQueryResult asyncQueryResult) - { - try + else if (_rawQueryResult is IAsyncActionQueryResult asyncQueryResult) { await asyncQueryResult.InvokeAsync(App.GetLauncherCancellationToken()); + App.CloseLauncher(); } - catch (OperationCanceledException) + else if (_rawQueryResult is ISyncDocumentQueryResult syncDocumentQueryResult) { - // pass + return new DocumentResult(syncDocumentQueryResult.GenerateDocument()); } - catch (Exception ex) + else if (_rawQueryResult is IAsyncDocumentQueryResult asyncDocumentQueryResult) { - MessageBox.Show($"{ex.Message}", "CurvaLauncher Result Invoke failed", MessageBoxButton.OK, MessageBoxImage.Error); + var document = await asyncDocumentQueryResult.GenerateDocumentAsync(cancellationToken); + return new DocumentResult(document); } - - return null; - } - else if (_rawQueryResult is ISyncDocumentQueryResult syncDocumentQueryResult) - { - try + else if (_rawQueryResult is ISyncMenuQueryResult syncMenuQueryResult) { - return new DocumentResult(syncDocumentQueryResult.GenerateDocument()); + var menuItems = syncMenuQueryResult.GetMenuItems(); + return new MenuResult(_pluginInstance, menuItems.ToList()); } - catch (Exception ex) + else if (_rawQueryResult is IAsyncMenuQueryResult asyncMenuQueryResult) { - MessageBox.Show($"{ex.Message}", "CurvaLauncher Result Invoke failed", MessageBoxButton.OK, MessageBoxImage.Error); + var menuItems = await asyncMenuQueryResult.GetMenuItemsAsync(cancellationToken); + return new MenuResult(_pluginInstance, menuItems.ToList()); } - - return null; } - else if (_rawQueryResult is IAsyncDocumentQueryResult asyncDocumentQueryResult) + catch (OperationCanceledException) { - try - { - var document = await asyncDocumentQueryResult.GenerateDocumentAsync(cancellationToken); - return new DocumentResult(document); - } - catch (Exception ex) - { - MessageBox.Show($"{ex.Message}", "CurvaLauncher Result Invoke failed", MessageBoxButton.OK, MessageBoxImage.Error); - } - - return null; + // pass + } + catch (Exception ex) + { + MessageBox.Show($"{ex.Message}", "CurvaLauncher Result Invoke failed", MessageBoxButton.OK, MessageBoxImage.Error); } - App.CloseLauncher(); return null; } - - public static QueryResultModel Create(CurvaLauncherPluginInstance pluginInstance, IQueryResult queryResult) - { - return new QueryResultModel(pluginInstance.Weight * queryResult.Weight, queryResult.Title, queryResult.Description, queryResult.Icon, queryResult); - } } diff --git a/src/CurvaLauncher/Services/ConfigService.cs b/src/CurvaLauncher/Services/ConfigService.cs index 101e0c0..770293b 100644 --- a/src/CurvaLauncher/Services/ConfigService.cs +++ b/src/CurvaLauncher/Services/ConfigService.cs @@ -52,7 +52,7 @@ private void LoadConfig(out AppConfig config) config = JsonSerializer.Deserialize(fs, JsonUtils.Options) ?? new AppConfig(); } - private AppConfig.PluginConfig GetPluginConfig(CurvaLauncherPluginInstance pluginInstance) + private AppConfig.PluginConfig GetPluginConfig(PluginInstance pluginInstance) { return new() { diff --git a/src/CurvaLauncher/Services/PluginService.cs b/src/CurvaLauncher/Services/PluginService.cs index 35c3f11..408ed99 100644 --- a/src/CurvaLauncher/Services/PluginService.cs +++ b/src/CurvaLauncher/Services/PluginService.cs @@ -24,7 +24,7 @@ public partial class PluginService public string Path { get; set; } = "Plugins"; - public ObservableCollection PluginInstances { get; } = new(); + public ObservableCollection PluginInstances { get; } = new(); public PluginService( PathService pathService, @@ -45,9 +45,9 @@ private DirectoryInfo EnsurePluginDirectory() return dir; } - private void CoreLoadPlugins(out List plugins) + private void CoreLoadPlugins(out List plugins) { - plugins = new List(); + plugins = new List(); var dir = EnsurePluginDirectory(); var dllFiles = dir.GetFiles("*.dll"); @@ -55,13 +55,13 @@ private void CoreLoadPlugins(out List plugins) AppConfig config = _configService.Config; foreach (FileInfo dllFile in dllFiles) - if (CoreLoadPlugin(config, dllFile.FullName, out CurvaLauncherPluginInstance? plugin)) + if (CoreLoadPlugin(config, dllFile.FullName, out PluginInstance? plugin)) { plugins.Add(plugin); } } - private bool CoreLoadPlugin(AppConfig config, string dllFilePath, [NotNullWhen(true)] out CurvaLauncherPluginInstance? pluginInstance) + private bool CoreLoadPlugin(AppConfig config, string dllFilePath, [NotNullWhen(true)] out PluginInstance? pluginInstance) { pluginInstance = null; @@ -76,7 +76,7 @@ private bool CoreLoadPlugin(AppConfig config, string dllFilePath, [NotNullWhen(t if (pluginType == null) return false; - if (!CurvaLauncherPluginInstance.TryCreate(pluginType, out pluginInstance)) + if (!PluginInstance.TryCreate(pluginType, out pluginInstance)) return false; var typeName = pluginType.FullName!; @@ -117,7 +117,7 @@ private bool CoreLoadPlugin(AppConfig config, string dllFilePath, [NotNullWhen(t } } - private void MoveCommandPluginsToTheBeginning(IList plugins) + private void MoveCommandPluginsToTheBeginning(IList plugins) { int indexStart = 0; for (int i = 1; i < plugins.Count; i++) diff --git a/src/CurvaLauncher/ViewModels/MainViewModel.cs b/src/CurvaLauncher/ViewModels/MainViewModel.cs index 6147bea..c0b418a 100644 --- a/src/CurvaLauncher/ViewModels/MainViewModel.cs +++ b/src/CurvaLauncher/ViewModels/MainViewModel.cs @@ -1,4 +1,5 @@ -using System.Collections.ObjectModel; +using System; +using System.Collections.ObjectModel; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -21,16 +22,16 @@ public partial class MainViewModel : ObservableObject, IRecipient QueryResults { get; } = new(); public ObservableCollection ImmediateResults { get; } = new(); @@ -83,13 +84,11 @@ await Task.Run(async () => if (cancellationToken.IsCancellationRequested) return; - var model = QueryResultModel.Create(pluginInstance, result); + var model = new QueryResultModel(pluginInstance, result); queryResults.Add(model); dispatcher.Invoke(() => { - model.SetFallbackIcon(() => pluginInstance.Plugin.Icon); - for (int i = 0; i < queryResults.Count; i++) { if (QueryResults.Count > i) @@ -140,52 +139,105 @@ public void Query() [RelayCommand] public async Task Invoke(QueryResultModel queryResult, CancellationToken cancellationToken) { - var imResult = await queryResult.Invoke(cancellationToken); - - if (imResult is not null) + try { - ImmediateResults.Add(imResult); + var imResult = await queryResult.Invoke(cancellationToken); - OnPropertyChanged(nameof(ShowQueryResult)); - OnPropertyChanged(nameof(ShowImmediateResults)); - OnPropertyChanged(nameof(CurrentImmediateResult)); + if (imResult is not null) + { + ImmediateResults.Add(imResult); + + OnPropertyChanged(nameof(ShowQueryResult)); + OnPropertyChanged(nameof(ShowImmediateResults)); + OnPropertyChanged(nameof(CurrentImmediateResult)); + } + } + catch (Exception) + { + // pass now } } [RelayCommand] public Task InvokeSelected(CancellationToken cancellationToken) { - if (SelectedQueryResult == null) - return Task.CompletedTask; + if (ImmediateResults.Count == 0) + { + if (SelectedQueryResult == null) + return Task.CompletedTask; + + var task = InvokeCommand.ExecuteAsync(SelectedQueryResult); + + return task; + } + else if (CurrentImmediateResult is MenuResult menuResult) + { + if (menuResult.SelectedItem == null) + return Task.CompletedTask; + + var task = InvokeCommand.ExecuteAsync(menuResult.SelectedItem); - return InvokeCommand.ExecuteAsync(SelectedQueryResult); + return task; + } + + return Task.CompletedTask; } [RelayCommand] public void SelectNext() { - if (QueryResults.Count == 0) - return; + if (ImmediateResults.Count == 0) + { + if (QueryResults.Count == 0) + { + return; + } + + SelectedQueryResultIndex = (SelectedQueryResultIndex + 1) % QueryResults.Count; + } + else if (CurrentImmediateResult is MenuResult menuResult) + { + if (menuResult.Items.Count == 0) + { + return; + } - SelectedQueryResultIndex = (SelectedQueryResultIndex + 1) % QueryResults.Count; + menuResult.SelectedIndex = (menuResult.SelectedIndex + 1) % menuResult.Items.Count; + } } [RelayCommand] public void SelectPrev() { - if (QueryResults.Count == 0) + if (ImmediateResults.Count == 0) { - if (LastInvokedQueryText != null && string.IsNullOrWhiteSpace(QueryText)) - QueryText = LastInvokedQueryText; + if (QueryResults.Count == 0) + { + if (LastInvokedQueryText != null && string.IsNullOrWhiteSpace(QueryText)) + QueryText = LastInvokedQueryText; - return; + return; + } + + int newIndex = (SelectedQueryResultIndex - 1) % QueryResults.Count; + if (newIndex == -1) + newIndex = QueryResults.Count - 1; + + SelectedQueryResultIndex = newIndex; } + else if (CurrentImmediateResult is MenuResult menuResult) + { + if (menuResult.Items.Count == 0) + { + return; + } - int newIndex = (SelectedQueryResultIndex - 1) % QueryResults.Count; - if (newIndex == -1) - newIndex = QueryResults.Count - 1; + int newIndex = (menuResult.SelectedIndex - 1) % menuResult.Items.Count; + if (newIndex == -1) + newIndex = menuResult.Items.Count - 1; - SelectedQueryResultIndex = newIndex; + menuResult.SelectedIndex = newIndex; + } } [RelayCommand] diff --git a/src/CurvaLauncher/ViewModels/SettingsPluginViewModel.cs b/src/CurvaLauncher/ViewModels/SettingsPluginViewModel.cs index 124223a..1feadba 100644 --- a/src/CurvaLauncher/ViewModels/SettingsPluginViewModel.cs +++ b/src/CurvaLauncher/ViewModels/SettingsPluginViewModel.cs @@ -6,5 +6,5 @@ namespace CurvaLauncher.ViewModels; public partial class SettingsPluginViewModel : ObservableObject { [ObservableProperty] - private CurvaLauncherPluginInstance? _selectedPluginInstance; + private PluginInstance? _selectedPluginInstance; } diff --git a/src/CurvaLauncher/Views/Components/PluginOptionsControl.xaml.cs b/src/CurvaLauncher/Views/Components/PluginOptionsControl.xaml.cs index 681a6d7..5aceef5 100644 --- a/src/CurvaLauncher/Views/Components/PluginOptionsControl.xaml.cs +++ b/src/CurvaLauncher/Views/Components/PluginOptionsControl.xaml.cs @@ -10,9 +10,9 @@ namespace CurvaLauncher.Views.Components; public partial class PluginOptionsControl : UserControl { - public CurvaLauncherPluginInstance PluginInstance { get; } + public PluginInstance PluginInstance { get; } - public PluginOptionsControl(CurvaLauncherPluginInstance pluginInstance) + public PluginOptionsControl(PluginInstance pluginInstance) { PluginInstance = pluginInstance; diff --git a/src/CurvaLauncher/Views/Pages/SettingsPluginPage.xaml b/src/CurvaLauncher/Views/Pages/SettingsPluginPage.xaml index e3f9eae..33d18bf 100644 --- a/src/CurvaLauncher/Views/Pages/SettingsPluginPage.xaml +++ b/src/CurvaLauncher/Views/Pages/SettingsPluginPage.xaml @@ -45,7 +45,7 @@ - + public partial class SettingsPluginPage : Wpf.Ui.Controls.UiPage { - private readonly Dictionary _cachedPluginOptions = new(); + private readonly Dictionary _cachedPluginOptions = new(); public SettingsPluginPage( SettingsPluginViewModel viewModel, @@ -47,7 +47,7 @@ public SettingsPluginPage( [RelayCommand] - public void NavigateToPluginSettings(CurvaLauncherPluginInstance? pluginInstance) + public void NavigateToPluginSettings(PluginInstance? pluginInstance) { if (pluginInstance is null) return; diff --git a/src/Plugins/CurvaLauncher.Plugins.Test/TestMenuQueryResult.cs b/src/Plugins/CurvaLauncher.Plugins.Test/TestMenuQueryResult.cs new file mode 100644 index 0000000..b7be5d1 --- /dev/null +++ b/src/Plugins/CurvaLauncher.Plugins.Test/TestMenuQueryResult.cs @@ -0,0 +1,21 @@ +using System.Windows.Media; + +namespace CurvaLauncher.Plugins.Test +{ + public class TestMenuQueryResult : ISyncMenuQueryResult + { + public string Title => "Test Menu"; + + public string Description => "Show test menu"; + + public float Weight => 1; + + public ImageSource? Icon => null; + + public IEnumerable GetMenuItems() + { + yield return new TestQueryResult("Show test message box", string.Empty, 1); + yield return new TestDocumentQueryResult(); + } + } +} \ No newline at end of file diff --git a/src/Plugins/CurvaLauncher.Plugins.Test/TestPlugin.cs b/src/Plugins/CurvaLauncher.Plugins.Test/TestPlugin.cs index cbe85db..df18773 100644 --- a/src/Plugins/CurvaLauncher.Plugins.Test/TestPlugin.cs +++ b/src/Plugins/CurvaLauncher.Plugins.Test/TestPlugin.cs @@ -41,11 +41,12 @@ public TestPlugin(CurvaLauncherContext context) : base(context) public override IEnumerable Query(string query) { - for (int i = 0; i < ResultCount - 1; i++) + for (int i = 0; i < ResultCount - 2; i++) { yield return new TestQueryResult($"{Title} {i}", Description, (float)i / ResultCount); } + yield return new TestMenuQueryResult(); yield return new TestDocumentQueryResult(); } diff --git a/src/Plugins/CurvaLauncher.Plugins.ZXing/Libraries/ZXing.NET/Pdf417/Decoder/PDF417ScanningDecoder.cs b/src/Plugins/CurvaLauncher.Plugins.ZXing/Libraries/ZXing.NET/Pdf417/Decoder/PDF417ScanningDecoder.cs index 300d903..d85c61b 100644 --- a/src/Plugins/CurvaLauncher.Plugins.ZXing/Libraries/ZXing.NET/Pdf417/Decoder/PDF417ScanningDecoder.cs +++ b/src/Plugins/CurvaLauncher.Plugins.ZXing/Libraries/ZXing.NET/Pdf417/Decoder/PDF417ScanningDecoder.cs @@ -85,11 +85,11 @@ public static DecoderResult decode(BitMatrix image, // if a barcode was not decoded where it was detected instead of throwing a new exception object. return null; } - var resultBox = detectionResult.Box; - if (firstPass && resultBox != null && - (resultBox.MinY < boundingBox.MinY || resultBox.MaxY > boundingBox.MaxY)) + var ResultBox = detectionResult.Box; + if (firstPass && ResultBox != null && + (ResultBox.MinY < boundingBox.MinY || ResultBox.MaxY > boundingBox.MaxY)) { - boundingBox = resultBox; + boundingBox = ResultBox; } else {