From 762575749c28b8cd31c22ff31ad09c9442b443f8 Mon Sep 17 00:00:00 2001 From: rampaa Date: Sat, 31 Aug 2024 22:23:12 +0300 Subject: [PATCH] Add "Popup position relative to cursor" setting --- JL.Windows/ConfigManager.cs | 42 +++++++++++++++++ JL.Windows/GUI/PopupWindow.xaml.cs | 68 ++++++++++++--------------- JL.Windows/GUI/PreferencesWindow.xaml | 13 +++++ 3 files changed, 84 insertions(+), 39 deletions(-) diff --git a/JL.Windows/ConfigManager.cs b/JL.Windows/ConfigManager.cs index 169b5480..96dc8c3c 100644 --- a/JL.Windows/ConfigManager.cs +++ b/JL.Windows/ConfigManager.cs @@ -87,6 +87,8 @@ internal static class ConfigManager }; public static double PopupXOffset { get; set; } = 10; public static double PopupYOffset { get; set; } = 20; + public static bool PositionPopupLeftOfCursor { get; private set; } // = false; + public static bool PositionPopupAboveCursor { get; private set; } // = false; public static bool PopupFlipX { get; private set; } = true; public static bool PopupFlipY { get; private set; } = true; public static Brush PrimarySpellingColor { get; private set; } = Brushes.Chocolate; @@ -562,6 +564,43 @@ public static void ApplyPreferences() MainWindow.Instance.MainTextBox.FontFamily = new FontFamily(mainWindowFontStr); } + { + string? popupPositionRelativeToCursorStr = ConfigDBManager.GetSettingValue(connection, "PopupPositionRelativeToCursor"); + if (popupPositionRelativeToCursorStr is null) + { + popupPositionRelativeToCursorStr = "BottomRight"; + ConfigDBManager.InsertSetting(connection, "PopupPositionRelativeToCursor", popupPositionRelativeToCursorStr); + } + + switch (popupPositionRelativeToCursorStr) + { + case "TopLeft": + PositionPopupAboveCursor = true; + PositionPopupLeftOfCursor = true; + break; + + case "TopRight": + PositionPopupAboveCursor = true; + PositionPopupLeftOfCursor = false; + break; + + case "BottomLeft": + PositionPopupAboveCursor = false; + PositionPopupLeftOfCursor = true; + break; + + case "BottomRight": + PositionPopupAboveCursor = false; + PositionPopupLeftOfCursor = false; + break; + + default: + PositionPopupAboveCursor = false; + PositionPopupLeftOfCursor = false; + break; + } + } + { string? popupFlipStr = ConfigDBManager.GetSettingValue(connection, "PopupFlip"); if (popupFlipStr is null) @@ -879,6 +918,7 @@ public static void LoadPreferenceWindow(PreferencesWindow preferenceWindow) preferenceWindow.ProfileComboBox.SelectedItem = ProfileUtils.CurrentProfileName; preferenceWindow.ThemeComboBox.SelectedValue = ConfigDBManager.GetSettingValue(connection, "Theme"); preferenceWindow.MinimumLogLevelComboBox.SelectedValue = ConfigDBManager.GetSettingValue(connection, "MinimumLogLevel"); + preferenceWindow.PopupPositionRelativeToCursorComboBox.SelectedValue = ConfigDBManager.GetSettingValue(connection, "PopupPositionRelativeToCursor"); preferenceWindow.PopupFlipComboBox.SelectedValue = ConfigDBManager.GetSettingValue(connection, "PopupFlip"); preferenceWindow.LookupModeComboBox.SelectedValue = ConfigDBManager.GetSettingValue(connection, "LookupMode"); } @@ -1208,6 +1248,8 @@ public static async Task SavePreferences(PreferencesWindow preferenceWindow) ConfigDBManager.UpdateSetting(connection, nameof(PopupYOffset), preferenceWindow.PopupYOffsetNumericUpDown.Value.ToString(CultureInfo.InvariantCulture)); + ConfigDBManager.UpdateSetting(connection, "PopupPositionRelativeToCursor", preferenceWindow.PopupPositionRelativeToCursorComboBox.SelectedValue.ToString()!); + ConfigDBManager.UpdateSetting(connection, "PopupFlip", preferenceWindow.PopupFlipComboBox.SelectedValue.ToString()!); ConfigDBManager.UpdateSetting(connection, nameof(ShowMiningModeReminder), diff --git a/JL.Windows/GUI/PopupWindow.xaml.cs b/JL.Windows/GUI/PopupWindow.xaml.cs index d8608687..8ebb1c1f 100644 --- a/JL.Windows/GUI/PopupWindow.xaml.cs +++ b/JL.Windows/GUI/PopupWindow.xaml.cs @@ -12,6 +12,7 @@ using JL.Core.Utilities; using JL.Windows.SpeechSynthesis; using JL.Windows.Utilities; +using Rectangle = System.Drawing.Rectangle; namespace JL.Windows.GUI; @@ -415,59 +416,48 @@ private void UpdatePosition(Point cursorPosition) double currentWidth = ActualWidth * WindowsUtils.Dpi.DpiScaleX; double currentHeight = ActualHeight * WindowsUtils.Dpi.DpiScaleY; - bool needsFlipX = ConfigManager.PopupFlipX && mouseX + currentWidth > WindowsUtils.ActiveScreen.Bounds.Right; - bool needsFlipY = ConfigManager.PopupFlipY && mouseY + currentHeight > WindowsUtils.ActiveScreen.Bounds.Bottom; + double newLeft = ConfigManager.PositionPopupLeftOfCursor + ? mouseX - (currentWidth + WindowsUtils.DpiAwareXOffset) + : mouseX + WindowsUtils.DpiAwareXOffset; - double newLeft; - double newTop; + double newTop = ConfigManager.PositionPopupAboveCursor + ? mouseY - (currentHeight + WindowsUtils.DpiAwareYOffset) + : mouseY + WindowsUtils.DpiAwareYOffset; - UnavoidableMouseEnter = false; + Rectangle screenBounds = WindowsUtils.ActiveScreen.Bounds; - if (needsFlipX) + if (ConfigManager.PopupFlipX) { - // flip Leftwards while preventing -OOB - newLeft = mouseX - (currentWidth + WindowsUtils.DpiAwareXOffset); - if (newLeft < WindowsUtils.ActiveScreen.Bounds.X) + if (ConfigManager.PositionPopupLeftOfCursor && newLeft < screenBounds.Left) { - newLeft = WindowsUtils.ActiveScreen.Bounds.X; + newLeft = mouseX + WindowsUtils.DpiAwareXOffset; } - } - else - { - // no flip - newLeft = mouseX + WindowsUtils.DpiAwareXOffset; - } - - if (needsFlipY) - { - // flip Upwards while preventing -OOB - newTop = mouseY - (currentHeight + WindowsUtils.DpiAwareYOffset); - if (newTop < WindowsUtils.ActiveScreen.Bounds.Y) + else if (!ConfigManager.PositionPopupLeftOfCursor && newLeft + currentWidth > screenBounds.Right) { - newTop = WindowsUtils.ActiveScreen.Bounds.Y; + newLeft = mouseX - (currentWidth + WindowsUtils.DpiAwareXOffset); } } - else - { - // no flip - newTop = mouseY + WindowsUtils.DpiAwareYOffset; - } - // stick to edges if +OOB - if (newLeft + currentWidth > WindowsUtils.ActiveScreen.Bounds.Right) - { - newLeft = WindowsUtils.ActiveScreen.Bounds.Right - currentWidth; - } + newLeft = Math.Max(screenBounds.Left, Math.Min(newLeft, screenBounds.Right - currentWidth)); - if (newTop + currentHeight > WindowsUtils.ActiveScreen.Bounds.Bottom) + if (ConfigManager.PopupFlipY) { - newTop = WindowsUtils.ActiveScreen.Bounds.Bottom - currentHeight; + if (ConfigManager.PositionPopupAboveCursor && newTop < screenBounds.Top) + { + newTop = mouseY + WindowsUtils.DpiAwareYOffset; + } + else if (!ConfigManager.PositionPopupAboveCursor && newTop + currentHeight > screenBounds.Bottom) + { + newTop = mouseY - (currentHeight + WindowsUtils.DpiAwareYOffset); + } } - if (mouseX >= newLeft && mouseX <= newLeft + currentWidth && mouseY >= newTop && mouseY <= newTop + currentHeight) - { - UnavoidableMouseEnter = true; - } + newTop = Math.Max(screenBounds.Top, Math.Min(newTop, screenBounds.Bottom - currentHeight)); + + UnavoidableMouseEnter = mouseX >= newLeft + && mouseX <= newLeft + currentWidth + && mouseY >= newTop + && mouseY <= newTop + currentHeight; WinApi.MoveWindowToPosition(WindowHandle, newLeft, newTop); } diff --git a/JL.Windows/GUI/PreferencesWindow.xaml b/JL.Windows/GUI/PreferencesWindow.xaml index e5ede3cf..fdd4cfda 100644 --- a/JL.Windows/GUI/PreferencesWindow.xaml +++ b/JL.Windows/GUI/PreferencesWindow.xaml @@ -637,6 +637,19 @@ HorizontalAlignment="Right" /> + + + + + + + + + +