From ba5beefe5531d8d23a7ea4b56b68178e59dd8db3 Mon Sep 17 00:00:00 2001 From: Joseph Finney Date: Wed, 15 May 2024 22:34:02 -0500 Subject: [PATCH 1/8] Add new View menuitem --- Text-Grab/Views/GrabFrame.xaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Text-Grab/Views/GrabFrame.xaml b/Text-Grab/Views/GrabFrame.xaml index 9ddb460d..2e72dc01 100644 --- a/Text-Grab/Views/GrabFrame.xaml +++ b/Text-Grab/Views/GrabFrame.xaml @@ -216,6 +216,20 @@ InputGestureText="Del" /> + + + + + Date: Wed, 15 May 2024 22:58:18 -0500 Subject: [PATCH 2/8] Add "Close on Grab" ability Closes #445 --- Text-Grab/App.config | 3 + Text-Grab/Properties/Settings.Designer.cs | 12 + Text-Grab/Properties/Settings.settings | 3 + Text-Grab/Views/GrabFrame.xaml | 21 +- Text-Grab/Views/GrabFrame.xaml.cs | 262 ++++++++++++---------- 5 files changed, 182 insertions(+), 119 deletions(-) diff --git a/Text-Grab/App.config b/Text-Grab/App.config index adf5ed82..f92e81cd 100644 --- a/Text-Grab/App.config +++ b/Text-Grab/App.config @@ -139,6 +139,9 @@ False + + False + \ No newline at end of file diff --git a/Text-Grab/Properties/Settings.Designer.cs b/Text-Grab/Properties/Settings.Designer.cs index f42e5580..65a0283a 100644 --- a/Text-Grab/Properties/Settings.Designer.cs +++ b/Text-Grab/Properties/Settings.Designer.cs @@ -550,5 +550,17 @@ public bool EtwUseMargins { this["EtwUseMargins"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool CloseFrameOnGrab { + get { + return ((bool)(this["CloseFrameOnGrab"])); + } + set { + this["CloseFrameOnGrab"] = value; + } + } } } diff --git a/Text-Grab/Properties/Settings.settings b/Text-Grab/Properties/Settings.settings index 8d341e21..77310ecf 100644 --- a/Text-Grab/Properties/Settings.settings +++ b/Text-Grab/Properties/Settings.settings @@ -134,5 +134,8 @@ False + + False + \ No newline at end of file diff --git a/Text-Grab/Views/GrabFrame.xaml b/Text-Grab/Views/GrabFrame.xaml index 2e72dc01..5a2d73a5 100644 --- a/Text-Grab/Views/GrabFrame.xaml +++ b/Text-Grab/Views/GrabFrame.xaml @@ -69,6 +69,10 @@ CanExecute="CanChangeWordBorderExecute" Command="{x:Static local:GrabFrame.MergeWordsCommand}" Executed="MergeWordBordersExecuted" /> + @@ -220,14 +224,25 @@ + Click="ScrollBehaviorMenuItem_Click" + IsCheckable="True" + Tag="Nothing" /> + Click="" + IsCheckable="True" + Tag="Resize" /> + + @@ -606,7 +621,7 @@ Margin="0" ButtonSymbol="Copy24" ButtonText="Grab" - Click="GrabBTN_Click" + Command="{x:Static local:GrabFrame.GrabCommand}" ToolTip="Grab text in the Grab Frame" /> diff --git a/Text-Grab/Views/GrabFrame.xaml.cs b/Text-Grab/Views/GrabFrame.xaml.cs index 2a01c823..0bbf3894 100644 --- a/Text-Grab/Views/GrabFrame.xaml.cs +++ b/Text-Grab/Views/GrabFrame.xaml.cs @@ -1,13 +1,11 @@ using Fasetto.Word; -using Humanizer; using System; -using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; -using System.Drawing.Imaging; using System.IO; using System.Linq; +using System.Linq.Expressions; using System.Runtime.InteropServices; using System.Text; using System.Text.Json; @@ -22,7 +20,6 @@ using System.Windows.Navigation; using System.Windows.Threading; using Text_Grab.Controls; -using Text_Grab.Extensions; using Text_Grab.Models; using Text_Grab.Properties; using Text_Grab.Services; @@ -48,6 +45,7 @@ public partial class GrabFrame : Window public static RoutedCommand PasteCommand = new(); public static RoutedCommand RedoCommand = new(); public static RoutedCommand UndoCommand = new(); + public static RoutedCommand GrabCommand = new(); private ResultTable? AnalyzedResultTable; private Point clickedPoint; private Language? currentLanguage; @@ -125,8 +123,10 @@ private async Task LoadContentFromHistory(HistoryInfo history) { foreach (WordBorderInfo info in wbInfoList) { - WordBorder wb = new(info); - wb.OwnerGrabFrame = this; + WordBorder wb = new(info) + { + OwnerGrabFrame = this + }; if (wb.IsBarcode) wb.SetAsBarcode(); @@ -143,18 +143,18 @@ private async Task LoadContentFromHistory(HistoryInfo history) if (history.PositionRect != Rect.Empty) { - this.Left = history.PositionRect.Left; - this.Top = history.PositionRect.Top; - this.Height = history.PositionRect.Height; - this.Width = history.PositionRect.Width; + Left = history.PositionRect.Left; + Top = history.PositionRect.Top; + Height = history.PositionRect.Height; + Width = history.PositionRect.Width; if (history.SourceMode == TextGrabMode.Fullscreen) { int borderThickness = 2; int titleBarHeight = 32; int bottomBarHeight = 42; - this.Height += (titleBarHeight + bottomBarHeight); - this.Width += (2 * borderThickness); + Height += (titleBarHeight + bottomBarHeight); + Width += (2 * borderThickness); } } @@ -167,14 +167,14 @@ public Rect GetImageContentRect() { // This is a WIP to try to remove the gray letterboxes on either // side of the image when zooming it. - + Rect imageRect = Rect.Empty; if (frameContentImageSource is null) return imageRect; imageRect = RectanglesCanvas.GetAbsolutePlacement(true); - var rectCanvasSize = RectanglesCanvas.RenderSize; + Size rectCanvasSize = RectanglesCanvas.RenderSize; imageRect.Width = rectCanvasSize.Width; imageRect.Height = rectCanvasSize.Height; @@ -207,7 +207,7 @@ private void StandardInitialize() GetGrabFrameUserSettings(); SetRefreshOrOcrFrameBtnVis(); - this.DataContext = this; + DataContext = this; } #endregion Constructors @@ -273,10 +273,10 @@ public HistoryInfo AsHistoryItem() Rect sizePosRect = new() { - Width = this.Width, - Height = this.Height, - X = this.Left, - Y = this.Top + Width = Width, + Height = Height, + X = Left, + Y = Top }; string id = string.Empty; @@ -382,14 +382,17 @@ public void DeleteThisWordBorder(WordBorder wordBorder, bool startEndTransaction public async void GrabFrame_Loaded(object sender, RoutedEventArgs e) { - this.PreviewMouseWheel += HandlePreviewMouseWheel; - this.PreviewKeyDown += Window_PreviewKeyDown; - this.PreviewKeyUp += Window_PreviewKeyUp; + PreviewMouseWheel += HandlePreviewMouseWheel; + PreviewKeyDown += Window_PreviewKeyDown; + PreviewKeyUp += Window_PreviewKeyUp; RoutedCommand pasteCommand = new(); _ = pasteCommand.InputGestures.Add(new KeyGesture(Key.V, ModifierKeys.Control | ModifierKeys.Shift)); _ = CommandBindings.Add(new CommandBinding(pasteCommand, PasteExecuted)); + _ = GrabCommand.InputGestures.Add(new KeyGesture(Key.G, ModifierKeys.Control)); + _ = CommandBindings.Add(new CommandBinding(GrabCommand, GrabExecuted)); + CheckBottomRowButtonsVis(); if (historyItem is not null) @@ -398,18 +401,18 @@ public async void GrabFrame_Loaded(object sender, RoutedEventArgs e) public void GrabFrame_Unloaded(object sender, RoutedEventArgs e) { - this.Activated -= GrabFrameWindow_Activated; - this.Closed -= Window_Closed; - this.Deactivated -= GrabFrameWindow_Deactivated; - this.DragLeave -= GrabFrameWindow_DragLeave; - this.DragOver -= GrabFrameWindow_DragOver; - this.Loaded -= GrabFrame_Loaded; - this.LocationChanged -= Window_LocationChanged; - this.SizeChanged -= Window_SizeChanged; - this.Unloaded -= GrabFrame_Unloaded; - this.PreviewMouseWheel -= HandlePreviewMouseWheel; - this.PreviewKeyDown -= Window_PreviewKeyDown; - this.PreviewKeyUp -= Window_PreviewKeyUp; + Activated -= GrabFrameWindow_Activated; + Closed -= Window_Closed; + Deactivated -= GrabFrameWindow_Deactivated; + DragLeave -= GrabFrameWindow_DragLeave; + DragOver -= GrabFrameWindow_DragOver; + Loaded -= GrabFrame_Loaded; + LocationChanged -= Window_LocationChanged; + SizeChanged -= Window_SizeChanged; + Unloaded -= GrabFrame_Unloaded; + PreviewMouseWheel -= HandlePreviewMouseWheel; + PreviewKeyDown -= Window_PreviewKeyDown; + PreviewKeyUp -= Window_PreviewKeyUp; reDrawTimer.Stop(); reDrawTimer.Tick -= ReDrawTimer_Tick; @@ -461,7 +464,7 @@ public void MergeSelectedWordBorders() UndoRedo.StartTransaction(); - var deletedWordBorders = DeleteSelectedWordBorders(); + List deletedWordBorders = DeleteSelectedWordBorders(); UndoRedo.InsertUndoRedoOperation(UndoRedoOperation.RemoveWordBorder, new GrabFrameOperationArgs() { @@ -596,7 +599,7 @@ internal void SearchForSimilar(WordBorder wordBorder) private static float GetWidthOfString(string str, int width, int height) { - using System.Drawing.Bitmap objBitmap = new System.Drawing.Bitmap(width, height); + using System.Drawing.Bitmap objBitmap = new(width, height); using System.Drawing.Graphics objGraphics = System.Drawing.Graphics.FromImage(objBitmap); System.Drawing.SizeF stringSize = objGraphics.MeasureString(str, new System.Drawing.Font("Segoe UI", (int)(height * 0.8))); @@ -610,7 +613,7 @@ private static float GetWidthOfString(string str, int width, int height) // Check for files in the hovering data object. if (args.Data.GetDataPresent(DataFormats.FileDrop, true)) { - var fileNames = args.Data.GetData(DataFormats.FileDrop, true) as string[]; + string[]? fileNames = args.Data.GetData(DataFormats.FileDrop, true) as string[]; // Check for a single file or folder. if (fileNames?.Length is 1) { @@ -756,12 +759,12 @@ private void CanUndoCommand(object sender, CanExecuteRoutedEventArgs e) private void CheckBottomRowButtonsVis() { - if (this.Width < 270) + if (Width < 270) ButtonsStackPanel.Visibility = Visibility.Collapsed; else ButtonsStackPanel.Visibility = Visibility.Visible; - if (this.Width < 390) + if (Width < 390) { SearchBox.Visibility = Visibility.Collapsed; ClearBTN.Visibility = Visibility.Collapsed; @@ -776,7 +779,7 @@ private void CheckBottomRowButtonsVis() ClearBTN.Visibility = Visibility.Collapsed; } - if (this.Width < 480) + if (Width < 480) LanguagesComboBox.Visibility = Visibility.Collapsed; else LanguagesComboBox.Visibility = Visibility.Visible; @@ -784,7 +787,7 @@ private void CheckBottomRowButtonsVis() private void CheckSelectBorderIntersections(bool finalCheck = false) { - Rect rectSelect = new Rect(Canvas.GetLeft(selectBorder), Canvas.GetTop(selectBorder), selectBorder.Width, selectBorder.Height); + Rect rectSelect = new(Canvas.GetLeft(selectBorder), Canvas.GetTop(selectBorder), selectBorder.Width, selectBorder.Height); bool clickedEmptySpace = true; bool smallSelection = false; @@ -793,7 +796,7 @@ private void CheckSelectBorderIntersections(bool finalCheck = false) foreach (WordBorder wordBorder in wordBorders) { - Rect wbRect = new Rect(Canvas.GetLeft(wordBorder), Canvas.GetTop(wordBorder), wordBorder.Width, wordBorder.Height); + Rect wbRect = new(Canvas.GetLeft(wordBorder), Canvas.GetTop(wordBorder), wordBorder.Width, wordBorder.Height); if (rectSelect.IntersectsWith(wbRect)) { @@ -863,7 +866,7 @@ private List DeleteSelectedWordBorders() return selectedWordBorders; - foreach (var wordBorder in selectedWordBorders) + foreach (WordBorder wordBorder in selectedWordBorders) { RectanglesCanvas.Children.Remove(wordBorder); wordBorders.Remove(wordBorder); @@ -876,7 +879,7 @@ private void DeleteWordBordersExecuted(object sender, ExecutedRoutedEventArgs? e { ShouldSaveOnClose = true; UndoRedo.StartTransaction(); - var deletedWordBorders = DeleteSelectedWordBorders(); + List deletedWordBorders = DeleteSelectedWordBorders(); UndoRedo.InsertUndoRedoOperation(UndoRedoOperation.RemoveWordBorder, new GrabFrameOperationArgs() { @@ -905,7 +908,7 @@ private async Task DrawRectanglesAroundWords(string searchWord = "") Point windowPosition = this.GetAbsolutePosition(); DpiScale dpi = VisualTreeHelper.GetDpi(this); - System.Drawing.Rectangle rectCanvasSize = new System.Drawing.Rectangle + System.Drawing.Rectangle rectCanvasSize = new() { Width = (int)((ActualWidth + 2) * dpi.DpiScaleX), Height = (int)((ActualHeight - 64) * dpi.DpiScaleY), @@ -978,11 +981,11 @@ private async Task DrawRectanglesAroundWords(string searchWord = "") UndoRedo.InsertUndoRedoOperation(UndoRedoOperation.AddWordBorder, new GrabFrameOperationArgs() - { - WordBorder = wordBorderBox, - WordBorders = wordBorders, - GrabFrameCanvas = RectanglesCanvas - }); + { + WordBorder = wordBorderBox, + WordBorders = wordBorders, + GrabFrameCanvas = RectanglesCanvas + }); } lineNumber++; @@ -1004,7 +1007,7 @@ private async Task DrawRectanglesAroundWords(string searchWord = "") private void EditMatchesMenuItem_Click(object sender, RoutedEventArgs e) { - var selectedWords = wordBorders.Where(m => m.IsSelected).ToList(); + List selectedWords = wordBorders.Where(m => m.IsSelected).ToList(); if (selectedWords.Count == 0) return; @@ -1120,7 +1123,7 @@ private void FreezeGrabFrame() FreezeToggleButton.IsChecked = true; Topmost = false; - this.Background = new SolidColorBrush(Colors.DimGray); + Background = new SolidColorBrush(Colors.DimGray); RectanglesBorder.Background.Opacity = 0; IsFreezeMode = true; } @@ -1201,30 +1204,12 @@ private void GetGrabFrameUserSettings() { AutoOcrCheckBox.IsChecked = DefaultSettings.GrabFrameAutoOcr; AlwaysUpdateEtwCheckBox.IsChecked = DefaultSettings.GrabFrameUpdateEtw; + CloseOnGrabMenuItem.IsChecked = DefaultSettings.CloseFrameOnGrab; } private void GrabBTN_Click(object sender, RoutedEventArgs e) { - if (string.IsNullOrWhiteSpace(FrameText)) - return; - - if (destinationTextBox is not null) - { - if (AlwaysUpdateEtwCheckBox.IsChecked is false) - destinationTextBox.SelectedText = FrameText; - - destinationTextBox.Select(destinationTextBox.SelectionStart + destinationTextBox.SelectionLength, 0); - destinationTextBox.AppendText(Environment.NewLine); - UpdateFrameText(); - - return; - } - if (!DefaultSettings.NeverAutoUseClipboard) - try { Clipboard.SetDataObject(FrameText, true); } catch { } - - if (DefaultSettings.ShowToast) - NotificationUtilities.ShowToast(FrameText); } private void GrabFrameWindow_Activated(object? sender, EventArgs e) @@ -1280,7 +1265,7 @@ private async void GrabFrameWindow_Drop(object sender, DragEventArgs e) { // Mark the event as handled, so TextBox's native Drop handler is not called. e.Handled = true; - var fileName = IsSingleFile(e); + string? fileName = IsSingleFile(e); if (fileName is null) return; Activate(); @@ -1336,7 +1321,7 @@ private void HandleDelete(object? sender = null, RoutedEventArgs? e = null) return; UndoRedo.StartTransaction(); - var deletedWordBorders = DeleteSelectedWordBorders(); + List deletedWordBorders = DeleteSelectedWordBorders(); UndoRedo.InsertUndoRedoOperation(UndoRedoOperation.RemoveWordBorder, new GrabFrameOperationArgs() { @@ -1378,37 +1363,37 @@ private void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e) // Source: StackOverflow, read on Sep. 10, 2021 // https://stackoverflow.com/a/53698638/7438031 - if (this.WindowState == WindowState.Maximized) + if (WindowState == WindowState.Maximized) return; e.Handled = true; - double aspectRatio = (this.Height - 66) / (this.Width - 4); + double aspectRatio = (Height - 66) / (Width - 4); bool isShiftDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift); bool isCtrlDown = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl); if (e.Delta > 0) { - this.Width += 100; - this.Left -= 50; + Width += 100; + Left -= 50; if (!isShiftDown) { - this.Height += 100 * aspectRatio; - this.Top -= 50 * aspectRatio; + Height += 100 * aspectRatio; + Top -= 50 * aspectRatio; } } else if (e.Delta < 0) { - if (this.Width > 120 && this.Height > 120) + if (Width > 120 && Height > 120) { - this.Width -= 100; - this.Left += 50; + Width -= 100; + Left += 50; if (!isShiftDown) { - this.Height -= 100 * aspectRatio; - this.Top += 50 * aspectRatio; + Height -= 100 * aspectRatio; + Top += 50 * aspectRatio; } } } @@ -1558,15 +1543,15 @@ private void OnCloseButtonClick(object sender, RoutedEventArgs e) private void OnMinimizeButtonClick(object sender, RoutedEventArgs e) { - this.WindowState = WindowState.Minimized; + WindowState = WindowState.Minimized; } private void OnRestoreButtonClick(object sender, RoutedEventArgs e) { - if (this.WindowState == WindowState.Maximized) - this.WindowState = WindowState.Normal; + if (WindowState == WindowState.Maximized) + WindowState = WindowState.Normal; else - this.WindowState = WindowState.Maximized; + WindowState = WindowState.Maximized; SetRestoreState(); } @@ -1574,7 +1559,7 @@ private void OnRestoreButtonClick(object sender, RoutedEventArgs e) private async void OpenImageMenuItem_Click(object? sender = null, RoutedEventArgs? e = null) { // Create OpenFileDialog - Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); + Microsoft.Win32.OpenFileDialog dlg = new(); // Set filter for file extension and default file extension dlg.Filter = FileUtilities.GetImageFilter(); @@ -1678,8 +1663,8 @@ private void RectanglesCanvas_MouseMove(object sender, MouseEventArgs e) Point movingPoint = e.GetPosition(RectanglesCanvas); - var left = Math.Min(clickedPoint.X, movingPoint.X); - var top = Math.Min(clickedPoint.Y, movingPoint.Y); + double left = Math.Min(clickedPoint.X, movingPoint.X); + double top = Math.Min(clickedPoint.Y, movingPoint.Y); if (isMiddleDown) { @@ -1703,7 +1688,7 @@ private void RectanglesCanvas_MouseMove(object sender, MouseEventArgs e) if (isCtrlDown) { double smallestHeight = 6; - double largestHeight = this.Height; + double largestHeight = Height; double gridSnapSize = 3.0; selectBorder.Height = Math.Clamp(selectBorder.Height, smallestHeight, largestHeight); @@ -1797,11 +1782,11 @@ private async void RefreshBTN_Click(object? sender = null, RoutedEventArgs? e = UndoRedo.InsertUndoRedoOperation(UndoRedoOperation.RemoveWordBorder, new GrabFrameOperationArgs() - { - RemovingWordBorders = new(wordBorders), - WordBorders = wordBorders, - GrabFrameCanvas = RectanglesCanvas - }); +{ + RemovingWordBorders = new(wordBorders), + WordBorders = wordBorders, + GrabFrameCanvas = RectanglesCanvas +}); ResetGrabFrame(); @@ -1823,7 +1808,7 @@ private void RemoveTableLines() { Canvas? tableLines = null; - foreach (var child in RectanglesCanvas.Children) + foreach (object? child in RectanglesCanvas.Children) if (child is Canvas element && element.Tag is "TableLines") tableLines = element; @@ -1951,7 +1936,7 @@ private void SelectAllWordBorders(object? sender = null, RoutedEventArgs? e = nu private void SetGrabFrameUserSettings() { - string windowSizeAndPosition = $"{this.Left},{this.Top},{this.Width},{this.Height}"; + string windowSizeAndPosition = $"{Left},{Top},{Width},{Height}"; DefaultSettings.GrabFrameWindowSizeAndPosition = windowSizeAndPosition; DefaultSettings.GrabFrameAutoOcr = AutoOcrCheckBox.IsChecked; DefaultSettings.GrabFrameUpdateEtw = AlwaysUpdateEtwCheckBox.IsChecked; @@ -2078,7 +2063,7 @@ private void TryToPlaceTable() Point windowPosition = this.GetAbsolutePosition(); DpiScale dpi = VisualTreeHelper.GetDpi(this); - System.Drawing.Rectangle rectCanvasSize = new System.Drawing.Rectangle + System.Drawing.Rectangle rectCanvasSize = new() { Width = (int)((ActualWidth + 2) * dpi.DpiScaleX), Height = (int)((ActualHeight - 64) * dpi.DpiScaleY), @@ -2118,20 +2103,22 @@ private void TryToReadBarcodes(DpiScale dpi) float[] xs = rawPoints.Reverse().Take(4).Select(x => x.X).ToArray(); float[] ys = rawPoints.Reverse().Take(4).Select(x => x.Y).ToArray(); - Point minPoint = new Point(xs.Min(), ys.Min()); - Point maxPoint = new Point(xs.Max(), ys.Max()); - Point diffs = new Point(maxPoint.X - minPoint.X, maxPoint.Y - minPoint.Y); + Point minPoint = new(xs.Min(), ys.Min()); + Point maxPoint = new(xs.Max(), ys.Max()); + Point diffs = new(maxPoint.X - minPoint.X, maxPoint.Y - minPoint.Y); if (diffs.Y < 5) diffs.Y = diffs.X / 10; - WordBorder wb = new(); - wb.Word = result.Text; - wb.Width = diffs.X / dpi.DpiScaleX + 12; - wb.Height = diffs.Y / dpi.DpiScaleY + 12; - wb.Left = minPoint.X / (dpi.DpiScaleX) - 6; - wb.Top = minPoint.Y / (dpi.DpiScaleY) - 6; - wb.OwnerGrabFrame = this; + WordBorder wb = new() + { + Word = result.Text, + Width = diffs.X / dpi.DpiScaleX + 12, + Height = diffs.Y / dpi.DpiScaleY + 12, + Left = minPoint.X / (dpi.DpiScaleX) - 6, + Top = minPoint.Y / (dpi.DpiScaleY) - 6, + OwnerGrabFrame = this + }; wb.SetAsBarcode(); wordBorders.Add(wb); _ = RectanglesCanvas.Children.Add(wb); @@ -2161,7 +2148,7 @@ private void UnfreezeGrabFrame() RectanglesBorder.Background.Opacity = 0.05; FreezeToggleButton.IsChecked = false; FreezeToggleButton.Visibility = Visibility.Visible; - this.Background = new SolidColorBrush(Colors.Transparent); + Background = new SolidColorBrush(Colors.Transparent); IsFreezeMode = false; reDrawTimer.Start(); } @@ -2190,11 +2177,6 @@ private void UpdateFrameText() FrameText = stringBuilder.ToString(); - if (string.IsNullOrEmpty(FrameText)) - GrabBTN.IsEnabled = false; - else - GrabBTN.IsEnabled = true; - if (IsFromEditWindow && destinationTextBox is not null && AlwaysUpdateEtwCheckBox.IsChecked is true @@ -2274,5 +2256,53 @@ private void Window_SizeChanged(object sender, SizeChangedEventArgs e) reDrawTimer.Stop(); reDrawTimer.Start(); } + + private void CloseOnGrabMenuItem_Click(object sender, RoutedEventArgs e) + { + DefaultSettings.CloseFrameOnGrab = CloseOnGrabMenuItem.IsChecked is true; + } + + private void CanExecuteGrab(object sender, CanExecuteRoutedEventArgs e) + { + if (string.IsNullOrEmpty(FrameText)) + e.CanExecute = false; + else + e.CanExecute = true; + } + + private void GrabExecuted(object sender, ExecutedRoutedEventArgs e) + { + if (string.IsNullOrWhiteSpace(FrameText)) + return; + + if (destinationTextBox is not null) + { + if (AlwaysUpdateEtwCheckBox.IsChecked is false) + destinationTextBox.SelectedText = FrameText; + + destinationTextBox.Select(destinationTextBox.SelectionStart + destinationTextBox.SelectionLength, 0); + destinationTextBox.AppendText(Environment.NewLine); + UpdateFrameText(); + + if (CloseOnGrabMenuItem.IsChecked) + Close(); + return; + } + + if (!DefaultSettings.NeverAutoUseClipboard) + try { Clipboard.SetDataObject(FrameText, true); } catch { } + + if (DefaultSettings.ShowToast) + NotificationUtilities.ShowToast(FrameText); + + if (CloseOnGrabMenuItem.IsChecked) + Close(); + } + + private void ScrollBehaviorMenuItem_Click(object sender, RoutedEventArgs e) + { + + } + #endregion Methods } From 4e982e8ada6bbefcedbcc0682ff18dbb6b407d60 Mon Sep 17 00:00:00 2001 From: Joseph Finney Date: Wed, 15 May 2024 23:13:13 -0500 Subject: [PATCH 3/8] Add options to change scroll behavior Closes #442 --- Text-Grab/App.config | 3 +++ Text-Grab/Enums.cs | 7 +++++ Text-Grab/Properties/Settings.Designer.cs | 12 +++++++++ Text-Grab/Properties/Settings.settings | 3 +++ Text-Grab/Views/GrabFrame.xaml | 7 ++--- Text-Grab/Views/GrabFrame.xaml.cs | 33 ++++++++++++++++++++++- 6 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Text-Grab/App.config b/Text-Grab/App.config index f92e81cd..f852fa6e 100644 --- a/Text-Grab/App.config +++ b/Text-Grab/App.config @@ -142,6 +142,9 @@ False + + Resize + \ No newline at end of file diff --git a/Text-Grab/Enums.cs b/Text-Grab/Enums.cs index 1daafcef..9f892d44 100644 --- a/Text-Grab/Enums.cs +++ b/Text-Grab/Enums.cs @@ -76,4 +76,11 @@ public enum VirtualKeyCodes : short LeftButton = 0x01, RightButton = 0x02, MiddleButton = 0x04 +} + +public enum ScrollBehavior +{ + None = 0, + Resize = 1, + Zoom = 2, } \ No newline at end of file diff --git a/Text-Grab/Properties/Settings.Designer.cs b/Text-Grab/Properties/Settings.Designer.cs index 65a0283a..95b517f6 100644 --- a/Text-Grab/Properties/Settings.Designer.cs +++ b/Text-Grab/Properties/Settings.Designer.cs @@ -562,5 +562,17 @@ public bool CloseFrameOnGrab { this["CloseFrameOnGrab"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Resize")] + public string GrabFrameScrollBehavior { + get { + return ((string)(this["GrabFrameScrollBehavior"])); + } + set { + this["GrabFrameScrollBehavior"] = value; + } + } } } diff --git a/Text-Grab/Properties/Settings.settings b/Text-Grab/Properties/Settings.settings index 77310ecf..fc262f6b 100644 --- a/Text-Grab/Properties/Settings.settings +++ b/Text-Grab/Properties/Settings.settings @@ -137,5 +137,8 @@ False + + Resize + \ No newline at end of file diff --git a/Text-Grab/Views/GrabFrame.xaml b/Text-Grab/Views/GrabFrame.xaml index 5a2d73a5..21959f29 100644 --- a/Text-Grab/Views/GrabFrame.xaml +++ b/Text-Grab/Views/GrabFrame.xaml @@ -223,18 +223,19 @@ + Tag="None" /> diff --git a/Text-Grab/Views/GrabFrame.xaml.cs b/Text-Grab/Views/GrabFrame.xaml.cs index 0bbf3894..fe61a1d7 100644 --- a/Text-Grab/Views/GrabFrame.xaml.cs +++ b/Text-Grab/Views/GrabFrame.xaml.cs @@ -72,6 +72,7 @@ public partial class GrabFrame : Window private double windowFrameImageScale = 1; private ObservableCollection wordBorders = new(); private readonly static Settings DefaultSettings = AppUtilities.TextGrabSettings; + private ScrollBehavior scrollBehavior = ScrollBehavior.Resize; #endregion Fields @@ -1205,6 +1206,8 @@ private void GetGrabFrameUserSettings() AutoOcrCheckBox.IsChecked = DefaultSettings.GrabFrameAutoOcr; AlwaysUpdateEtwCheckBox.IsChecked = DefaultSettings.GrabFrameUpdateEtw; CloseOnGrabMenuItem.IsChecked = DefaultSettings.CloseFrameOnGrab; + _ = Enum.TryParse(DefaultSettings.GrabFrameScrollBehavior, out scrollBehavior); + SetScrollBehaviorMenuItems(); } private void GrabBTN_Click(object sender, RoutedEventArgs e) @@ -1363,7 +1366,7 @@ private void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e) // Source: StackOverflow, read on Sep. 10, 2021 // https://stackoverflow.com/a/53698638/7438031 - if (WindowState == WindowState.Maximized) + if (WindowState == WindowState.Maximized || scrollBehavior == ScrollBehavior.None) return; e.Handled = true; @@ -2301,7 +2304,35 @@ private void GrabExecuted(object sender, ExecutedRoutedEventArgs e) private void ScrollBehaviorMenuItem_Click(object sender, RoutedEventArgs e) { + if (sender is not MenuItem menuItem || !Enum.TryParse(menuItem.Tag.ToString(), out scrollBehavior)) + return; + + DefaultSettings.GrabFrameScrollBehavior = scrollBehavior.ToString(); + SetScrollBehaviorMenuItems(); + } + private void SetScrollBehaviorMenuItems() + { + switch (scrollBehavior) + { + case ScrollBehavior.None: + NoScrollBehaviorMenuItem.IsChecked = true; + ResizeScrollMenuItem.IsChecked = false; + ZoomScrollMenuItem.IsChecked = false; + break; + case ScrollBehavior.Resize: + NoScrollBehaviorMenuItem.IsChecked = false; + ResizeScrollMenuItem.IsChecked = true; + ZoomScrollMenuItem.IsChecked = false; + break; + case ScrollBehavior.Zoom: + NoScrollBehaviorMenuItem.IsChecked = false; + ResizeScrollMenuItem.IsChecked = false; + ZoomScrollMenuItem.IsChecked = true; + break; + default: + break; + } } #endregion Methods From 73babc63a4e471095e35222cf927e843aa72bb7f Mon Sep 17 00:00:00 2001 From: Joseph Finney Date: Tue, 28 May 2024 14:02:23 -0700 Subject: [PATCH 4/8] Add make word single line option --- Text-Grab/Controls/WordBorder.xaml | 5 +++++ Text-Grab/Controls/WordBorder.xaml.cs | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/Text-Grab/Controls/WordBorder.xaml b/Text-Grab/Controls/WordBorder.xaml index a2845c0c..339fcf7c 100644 --- a/Text-Grab/Controls/WordBorder.xaml +++ b/Text-Grab/Controls/WordBorder.xaml @@ -83,6 +83,11 @@ HorizontalAlignment="Left" Click="TryToAlphaMenuItem_Click" Header="Try To Make _Letters" /> + Date: Tue, 28 May 2024 14:25:36 -0700 Subject: [PATCH 5/8] Add Grab single line and Grab Menu Items --- Text-Grab/Views/GrabFrame.xaml | 34 ++++++++++++++++++--- Text-Grab/Views/GrabFrame.xaml.cs | 51 ++++++++++++++++++++++++------- 2 files changed, 69 insertions(+), 16 deletions(-) diff --git a/Text-Grab/Views/GrabFrame.xaml b/Text-Grab/Views/GrabFrame.xaml index 21959f29..e45dca65 100644 --- a/Text-Grab/Views/GrabFrame.xaml +++ b/Text-Grab/Views/GrabFrame.xaml @@ -73,7 +73,10 @@ CanExecute="CanExecuteGrab" Command="{x:Static local:GrabFrame.GrabCommand}" Executed="GrabExecuted" /> - + @@ -139,6 +142,17 @@ InputGestureText="Ctrl + O" /> + + + + Stretch="UniformToFill"> + + + + - + diff --git a/Text-Grab/Views/GrabFrame.xaml.cs b/Text-Grab/Views/GrabFrame.xaml.cs index fe61a1d7..134a2d98 100644 --- a/Text-Grab/Views/GrabFrame.xaml.cs +++ b/Text-Grab/Views/GrabFrame.xaml.cs @@ -46,6 +46,7 @@ public partial class GrabFrame : Window public static RoutedCommand RedoCommand = new(); public static RoutedCommand UndoCommand = new(); public static RoutedCommand GrabCommand = new(); + public static RoutedCommand GrabTrimCommand = new(); private ResultTable? AnalyzedResultTable; private Point clickedPoint; private Language? currentLanguage; @@ -198,10 +199,6 @@ private void StandardInitialize() reSearchTimer.Interval = new(0, 0, 0, 0, 300); reSearchTimer.Tick += ReSearchTimer_Tick; - RoutedCommand newCmd = new(); - _ = newCmd.InputGestures.Add(new KeyGesture(Key.Escape)); - _ = CommandBindings.Add(new CommandBinding(newCmd, Escape_Keyed)); - _ = UndoRedo.HasUndoOperations(); _ = UndoRedo.HasRedoOperations(); @@ -387,12 +384,18 @@ public async void GrabFrame_Loaded(object sender, RoutedEventArgs e) PreviewKeyDown += Window_PreviewKeyDown; PreviewKeyUp += Window_PreviewKeyUp; + RoutedCommand escapeCmd = new(); + _ = escapeCmd.InputGestures.Add(new KeyGesture(Key.Escape)); + _ = CommandBindings.Add(new CommandBinding(escapeCmd, Escape_Keyed)); + RoutedCommand pasteCommand = new(); _ = pasteCommand.InputGestures.Add(new KeyGesture(Key.V, ModifierKeys.Control | ModifierKeys.Shift)); _ = CommandBindings.Add(new CommandBinding(pasteCommand, PasteExecuted)); _ = GrabCommand.InputGestures.Add(new KeyGesture(Key.G, ModifierKeys.Control)); - _ = CommandBindings.Add(new CommandBinding(GrabCommand, GrabExecuted)); + // _ = CommandBindings.Add(new CommandBinding(GrabCommand, GrabExecuted)); + + _ = GrabTrimCommand.InputGestures.Add(new KeyGesture(Key.G, ModifierKeys.Control | ModifierKeys.Shift | ModifierKeys.Control)); CheckBottomRowButtonsVis(); @@ -441,7 +444,6 @@ public void GrabFrame_Unloaded(object sender, RoutedEventArgs e) EditToggleButton.Click -= EditToggleButton_Click; SettingsBTN.Click -= SettingsBTN_Click; EditTextToggleButton.Click -= EditTextBTN_Click; - GrabBTN.Click -= GrabBTN_Click; } public void MergeSelectedWordBorders() @@ -1210,11 +1212,6 @@ private void GetGrabFrameUserSettings() SetScrollBehaviorMenuItems(); } - private void GrabBTN_Click(object sender, RoutedEventArgs e) - { - - } - private void GrabFrameWindow_Activated(object? sender, EventArgs e) { RectanglesCanvas.Opacity = 1; @@ -2302,6 +2299,38 @@ private void GrabExecuted(object sender, ExecutedRoutedEventArgs e) Close(); } + private void GrabTrimExecuted(object sender, ExecutedRoutedEventArgs e) + { + if (string.IsNullOrWhiteSpace(FrameText)) + return; + + string trimmedSingleLineFrameText = FrameText.MakeStringSingleLine(); + + if (destinationTextBox is not null) + { + if (AlwaysUpdateEtwCheckBox.IsChecked is false) + destinationTextBox.SelectedText = trimmedSingleLineFrameText; + + destinationTextBox.Select(destinationTextBox.SelectionStart + destinationTextBox.SelectionLength, 0); + destinationTextBox.AppendText(Environment.NewLine); + UpdateFrameText(); + + if (CloseOnGrabMenuItem.IsChecked) + Close(); + return; + } + + if (!DefaultSettings.NeverAutoUseClipboard) + try { Clipboard.SetDataObject(trimmedSingleLineFrameText, true); } catch { } + + if (DefaultSettings.ShowToast) + NotificationUtilities.ShowToast(trimmedSingleLineFrameText); + + if (CloseOnGrabMenuItem.IsChecked) + Close(); + } + + private void ScrollBehaviorMenuItem_Click(object sender, RoutedEventArgs e) { if (sender is not MenuItem menuItem || !Enum.TryParse(menuItem.Tag.ToString(), out scrollBehavior)) From 5bc1c51ba5071b383bf5e3d9e12a0f6d630b5fc0 Mon Sep 17 00:00:00 2001 From: Joseph Finney Date: Tue, 28 May 2024 15:56:14 -0700 Subject: [PATCH 6/8] Can Zoom in on the GrabFrame --- Text-Grab/Controls/ZoomBorder.cs | 158 ++++++++++++++++++++++++++++++ Text-Grab/Views/GrabFrame.xaml | 138 +++++++++++++------------- Text-Grab/Views/GrabFrame.xaml.cs | 38 ++++++- 3 files changed, 263 insertions(+), 71 deletions(-) create mode 100644 Text-Grab/Controls/ZoomBorder.cs diff --git a/Text-Grab/Controls/ZoomBorder.cs b/Text-Grab/Controls/ZoomBorder.cs new file mode 100644 index 00000000..952c6f20 --- /dev/null +++ b/Text-Grab/Controls/ZoomBorder.cs @@ -0,0 +1,158 @@ +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +// From StackOverFlow: +// https://stackoverflow.com/questions/741956/pan-zoom-image +// Answered by https://stackoverflow.com/users/282801/wies%c5%82aw-%c5%a0olt%c3%a9s +// Read on 2024-05-02 +// Modified to match code style of this project + +namespace Text_Grab.Controls; + +public class ZoomBorder : Border +{ + private UIElement? child = null; + private Point origin; + private Point start; + + private TranslateTransform GetTranslateTransform(UIElement element) => + (TranslateTransform)((TransformGroup)element.RenderTransform) + .Children.First(tr => tr is TranslateTransform); + + private ScaleTransform GetScaleTransform(UIElement element) => + (ScaleTransform)((TransformGroup)element.RenderTransform) + .Children.First(tr => tr is ScaleTransform); + + public override UIElement Child + { + get { return base.Child; } + set + { + if (value != null && value != Child) + Initialize(value); + base.Child = value; + } + } + + public bool CanPan { get; set; } = true; + + public bool CanZoom { get; set; } = true; + + public void Initialize(UIElement element) + { + child = element; + if (child is null) + return; + + TransformGroup group = new(); + ScaleTransform st = new(); + group.Children.Add(st); + TranslateTransform tt = new(); + group.Children.Add(tt); + child.RenderTransform = group; + child.RenderTransformOrigin = new Point(0.0, 0.0); + MouseWheel += Child_MouseWheel; + MouseLeftButtonDown += Child_MouseLeftButtonDown; + MouseLeftButtonUp += Child_MouseLeftButtonUp; + PreviewMouseDown += ZoomBorder_PreviewMouseDown; + MouseMove += Child_MouseMove; + PreviewMouseRightButtonDown += new MouseButtonEventHandler( + Child_PreviewMouseRightButtonDown); + } + + private void ZoomBorder_PreviewMouseDown(object sender, MouseButtonEventArgs e) + { + if (e.MiddleButton == MouseButtonState.Pressed) + Reset(); + } + + public void Reset() + { + if (child is null) + return; + + // reset zoom + ScaleTransform st = GetScaleTransform(child); + st.ScaleX = 1.0; + st.ScaleY = 1.0; + + // reset pan + TranslateTransform tt = GetTranslateTransform(child); + tt.X = 0.0; + tt.Y = 0.0; + } + + private void Child_MouseWheel(object sender, MouseWheelEventArgs e) + { + if (child is null || !CanZoom) + return; + + ScaleTransform st = GetScaleTransform(child); + TranslateTransform tt = GetTranslateTransform(child); + + double zoom = e.Delta > 0 ? .2 : -.2; + if (!(e.Delta > 0) && (st.ScaleX < .4 || st.ScaleY < .4)) + return; + + Point relative = e.GetPosition(child); + double absoluteX; + double absoluteY; + + absoluteX = relative.X * st.ScaleX + tt.X; + absoluteY = relative.Y * st.ScaleY + tt.Y; + + st.ScaleX += zoom; + st.ScaleY += zoom; + + tt.X = absoluteX - relative.X * st.ScaleX; + tt.Y = absoluteY - relative.Y * st.ScaleY; + } + + private void Child_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + if (child is null) + return; + + TranslateTransform tt = GetTranslateTransform(child); + start = e.GetPosition(this); + origin = new Point(tt.X, tt.Y); + Cursor = Cursors.Hand; + // child.CaptureMouse(); + } + + private void Child_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + if (child is null) + return; + + child.ReleaseMouseCapture(); + Cursor = Cursors.Arrow; + } + + void Child_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) + { + } + + private void Child_MouseMove(object sender, MouseEventArgs e) + { + if (child is null + || GetScaleTransform(child) is not ScaleTransform st + || st.ScaleX == 1.0 + || Mouse.LeftButton == MouseButtonState.Released + || !CanPan + || KeyboardExtensions.IsShiftDown() + || KeyboardExtensions.IsCtrlDown()) + { + child?.ReleaseMouseCapture(); + return; + } + + TranslateTransform tt = GetTranslateTransform(child); + Vector v = start - e.GetPosition(this); + tt.X = origin.X - v.X; + tt.Y = origin.Y - v.Y; + } +} \ No newline at end of file diff --git a/Text-Grab/Views/GrabFrame.xaml b/Text-Grab/Views/GrabFrame.xaml index e45dca65..13310bb8 100644 --- a/Text-Grab/Views/GrabFrame.xaml +++ b/Text-Grab/Views/GrabFrame.xaml @@ -373,74 +373,76 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Date: Tue, 28 May 2024 15:58:50 -0700 Subject: [PATCH 7/8] code style --- Text-Grab/Views/GrabFrame.xaml.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Text-Grab/Views/GrabFrame.xaml.cs b/Text-Grab/Views/GrabFrame.xaml.cs index c775e9fb..b6529676 100644 --- a/Text-Grab/Views/GrabFrame.xaml.cs +++ b/Text-Grab/Views/GrabFrame.xaml.cs @@ -1183,17 +1183,17 @@ private SolidColorBrush GetBackgroundBrushFromBitmap(ref DpiScale dpi, double sc System.Drawing.Color pxColorRightBottom = bmp.GetPixel(pxRight, pxBottom); System.Drawing.Color pxColorLeftBottom = bmp.GetPixel(pxLeft, pxBottom); - List MediaColorList = new() - { + List MediaColorList = + [ ColorHelper.MediaColorFromDrawingColor(pxColorLeftTop), ColorHelper.MediaColorFromDrawingColor(pxColorRightTop), ColorHelper.MediaColorFromDrawingColor(pxColorRightBottom), ColorHelper.MediaColorFromDrawingColor(pxColorLeftBottom), - }; + ]; - System.Windows.Media.Color? MostCommonColor = MediaColorList.GroupBy(c => c) - .OrderBy(g => g.Count()) - .LastOrDefault()?.Key; + Color? MostCommonColor = MediaColorList.GroupBy(c => c) + .OrderBy(g => g.Count()) + .LastOrDefault()?.Key; backgroundBrush = ColorHelper.SolidColorBrushFromDrawingColor(pxColorLeftTop); @@ -1378,15 +1378,12 @@ private void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e) e.Handled = true; double aspectRatio = (Height - 66) / (Width - 4); - bool isShiftDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift); - bool isCtrlDown = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl); - if (e.Delta > 0) { Width += 100; Left -= 50; - if (!isShiftDown) + if (!KeyboardExtensions.IsShiftDown()) { Height += 100 * aspectRatio; Top -= 50 * aspectRatio; @@ -1399,7 +1396,7 @@ private void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e) Width -= 100; Left += 50; - if (!isShiftDown) + if (!KeyboardExtensions.IsShiftDown()) { Height -= 100 * aspectRatio; Top += 50 * aspectRatio; From 1bac2acd0b729e93b32cd270d0af45983843e043 Mon Sep 17 00:00:00 2001 From: Joseph Finney Date: Fri, 31 May 2024 21:43:52 -0500 Subject: [PATCH 8/8] Add word preview to Zoom GF option --- Text-Grab/Views/GrabFrame.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Text-Grab/Views/GrabFrame.xaml b/Text-Grab/Views/GrabFrame.xaml index 13310bb8..d276ba4f 100644 --- a/Text-Grab/Views/GrabFrame.xaml +++ b/Text-Grab/Views/GrabFrame.xaml @@ -250,7 +250,7 @@