Skip to content

Commit

Permalink
Added OCR overlay, bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
hlysine committed Oct 6, 2020
1 parent 214728e commit 67ce363
Show file tree
Hide file tree
Showing 13 changed files with 917 additions and 13 deletions.
29 changes: 29 additions & 0 deletions QuickDictionary/Helper.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace QuickDictionary
{
public static class Helper
{
public static void HideBoundingBox(object root)
{
Control control = root as Control;
if (control != null)
control.FocusVisualStyle = null;

if (root is DependencyObject)
{
foreach (object child in LogicalTreeHelper.GetChildren((DependencyObject)root))
{
HideBoundingBox(child);
}
}
}

/// <summary>
/// Blocks while condition is true or timeout occurs.
/// </summary>
Expand Down Expand Up @@ -47,6 +65,17 @@ public static async Task WaitUntil(Func<bool> condition, int frequency = 25, int
throw new TimeoutException();
}

public static System.Windows.Point RealPixelsToWpf(Window w, System.Windows.Point p)
{
var t = PresentationSource.FromVisual(w).CompositionTarget.TransformFromDevice;
return t.Transform(p);
}

public static double DistanceToPoint(this RectangleF rect, double x, double y)
{
return Math.Sqrt(Math.Pow(Math.Max(0, Math.Abs(rect.X + rect.Width / 2 - x) - rect.Width / 2), 2) + Math.Pow(Math.Max(0, Math.Abs(rect.Y + rect.Height / 2 - y) - rect.Height / 2), 2));
}

public static async Task<string> GetFinalRedirectAsync(string url)
{
if (string.IsNullOrWhiteSpace(url))
Expand Down
145 changes: 145 additions & 0 deletions QuickDictionary/KeyboardHook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace QuickDictionary
{
public sealed class KeyboardHook : IDisposable
{

/// <summary>
/// Represents the window that is used internally to get the messages.
/// </summary>
private class Window : NativeWindow, IDisposable
{
private static int WM_HOTKEY = 0x0312;

public Window()
{
// create the handle for the window.
this.CreateHandle(new CreateParams());
}

/// <summary>
/// Overridden to get the notifications.
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);

// check if we got a hot key pressed.
if (m.Msg == WM_HOTKEY)
{
// get the keys.
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
ModifierKeys modifier = (ModifierKeys)((int)m.LParam & 0xFFFF);

// invoke the event to notify the parent.
if (KeyPressed != null)
KeyPressed(this, new KeyPressedEventArgs(modifier, key));
}
}

public event EventHandler<KeyPressedEventArgs> KeyPressed;

#region IDisposable Members

public void Dispose()
{
this.DestroyHandle();
}

#endregion
}

private Window _window = new Window();
private int _currentId;

public KeyboardHook()
{
// register the event of the inner native window.
_window.KeyPressed += delegate (object sender, KeyPressedEventArgs args)
{
if (KeyPressed != null)
KeyPressed(this, args);
};
}

/// <summary>
/// Registers a hot key in the system.
/// </summary>
/// <param name="modifier">The modifiers that are associated with the hot key.</param>
/// <param name="key">The key itself that is associated with the hot key.</param>
public void RegisterHotKey(ModifierKeys modifier, Keys key)
{
// increment the counter.
_currentId = _currentId + 1;

// register the hot key.
if (!NativeMethods.RegisterHotKey(_window.Handle, _currentId, (uint)modifier, (uint)key))
throw new InvalidOperationException("Couldn’t register the hot key.");
}

/// <summary>
/// A hot key has been pressed.
/// </summary>
public event EventHandler<KeyPressedEventArgs> KeyPressed;

#region IDisposable Members

public void Dispose()
{
// unregister all the registered hot keys.
for (int i = _currentId; i > 0; i--)
{
NativeMethods.UnregisterHotKey(_window.Handle, i);
}

// dispose the inner native window.
_window.Dispose();
}

#endregion
}

/// <summary>
/// Event Args for the event that is fired after the hot key has been pressed.
/// </summary>
public class KeyPressedEventArgs : EventArgs
{
private ModifierKeys _modifier;
private Keys _key;

internal KeyPressedEventArgs(ModifierKeys modifier, Keys key)
{
_modifier = modifier;
_key = key;
}

public ModifierKeys Modifier
{
get { return _modifier; }
}

public Keys Key
{
get { return _key; }
}
}

/// <summary>
/// The enumeration of possible modifiers.
/// </summary>
[Flags]
public enum ModifierKeys : uint
{
Alt = 1,
Control = 2,
Shift = 4,
Win = 8
}
}
106 changes: 95 additions & 11 deletions QuickDictionary/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,57 @@
FontFamily="{DynamicResource MaterialDesignFont}"
mc:Ignorable="d"
Title="Quick Dictionary"
Height="450"
Width="800"
Height="800"
Width="400"
Name="mainWindow"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
SourceInitialized="Window_SourceInitialized"
Topmost="True">
<Grid>
SourceInitialized="Window_SourceInitialized"
Topmost="{Binding IsChecked, ElementName=checkTopmost}">
<Window.Resources>
<Storyboard
x:Key="shakeStoryboard">
<!--<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)">-->
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="mainWindow"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
FillBehavior="Stop">
<SplineDoubleKeyFrame
KeyTime="00:00:00.0500000"
Value="-10" />
<SplineDoubleKeyFrame
KeyTime="00:00:00.1000000"
Value="0" />
<SplineDoubleKeyFrame
KeyTime="00:00:00.1500000"
Value="10" />
<SplineDoubleKeyFrame
KeyTime="00:00:00.2000000"
Value="0" />
<SplineDoubleKeyFrame
KeyTime="00:00:00.2500000"
Value="-10" />
<SplineDoubleKeyFrame
KeyTime="00:00:00.3000000"
Value="0" />
<SplineDoubleKeyFrame
KeyTime="00:00:00.3500000"
Value="10" />
<SplineDoubleKeyFrame
KeyTime="00:00:00.4000000"
Value="0" />
</DoubleAnimationUsingKeyFrames >
</Storyboard >
</Window.Resources>
<Window.RenderTransform>
<TranslateTransform
Y="0"
X="0" />
</Window.RenderTransform >
<Grid
Name="root">
<Grid.RowDefinitions>
<RowDefinition
Height="Auto" />
<RowDefinition
Height="Auto" />
<RowDefinition
Expand All @@ -43,14 +87,51 @@
Margin="5"
Style="{StaticResource MaterialDesignOutlinedTextFieldTextBox}"
materialDesign:HintAssist.Hint="Word"
PreviewKeyUp="txtWord_PreviewKeyUp"/>
ToolTip="Enter a word (Alt+F)"
PreviewKeyUp="txtWord_PreviewKeyUp" />
<Button
Name="btnOCR"
Grid.Column="1"
Style="{StaticResource MaterialDesignIconButton}"
ToolTip="OCR look up (Alt+G)"
Click="btnOCR_Click">
<materialDesign:PackIcon
Kind="Show" />
</Button>
<ProgressBar
Name="progressLoading"
Grid.Column="2"
Style="{StaticResource MaterialDesignCircularProgressBar}"
Value="0"
IsIndeterminate="True"
Visibility="Hidden" />
</Grid>
<Grid
Margin="5"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="Auto" />
<ColumnDefinition
Width="Auto" />
<ColumnDefinition
Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Name="checkPause"
Margin="5 0 0 0"
Style="{StaticResource MaterialDesignCheckBox}"
Grid.Column="1">
Style="{StaticResource MaterialDesignCheckBox}"
Grid.Column="0"
ToolTip="Stop looking up words in the clipboard">
Pause
</CheckBox>
<CheckBox
Name="checkTopmost"
Margin="5 0 0 0"
Style="{StaticResource MaterialDesignCheckBox}"
Grid.Column="1">
Always on top
</CheckBox>
<ListBox
x:Name="listDictionaries"
Margin="5 0 0 0"
Expand All @@ -61,7 +142,9 @@
<ListBox.ItemTemplate>
<DataTemplate>
<materialDesign:Badged
Badge="{Binding PrecedenceString}">
Margin="0 5 0 0"
Badge="{Binding PrecedenceString}"
ToolTip="{Binding Name}">
<materialDesign:PackIcon
Kind="{Binding Icon}" />
</materialDesign:Badged>
Expand All @@ -71,8 +154,9 @@
</Grid>
<cefSharp:ChromiumWebBrowser
Name="browser"
Grid.Row="1"
Grid.Row="2"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
HorizontalAlignment="Stretch"
LoadingStateChanged="browser_LoadingStateChanged" />
</Grid>
</Window>
Loading

0 comments on commit 67ce363

Please sign in to comment.