diff options
author | Eric Maupin <ermaup@microsoft.com> | 2018-04-17 21:14:22 +0300 |
---|---|---|
committer | Eric Maupin <ermaup@microsoft.com> | 2018-07-20 19:39:31 +0300 |
commit | 0103b2f2c22fa66d095dbee2041e728d7d1190ce (patch) | |
tree | 2acd89e2529ef9bc25452e49092d9c34b2f00d7a | |
parent | 42cdbbf74952da396616b14539077af048bc6832 (diff) |
[Win] Eyedropperermau-windows-eyedropper
Still needs icon/cursor.
6 files changed, 212 insertions, 2 deletions
diff --git a/Xamarin.PropertyEditing.Windows/Eyedropper.cs b/Xamarin.PropertyEditing.Windows/Eyedropper.cs new file mode 100644 index 0000000..9e1a83e --- /dev/null +++ b/Xamarin.PropertyEditing.Windows/Eyedropper.cs @@ -0,0 +1,151 @@ +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Threading; + +using Xamarin.PropertyEditing.Drawing; + +namespace Xamarin.PropertyEditing.Windows +{ + internal class ColorEventArgs + : EventArgs + { + public ColorEventArgs (CommonColor color) + { + Color = color; + } + + public CommonColor Color + { + get; + } + } + + internal class ColorComittedEventArgs + : ColorEventArgs + { + public ColorComittedEventArgs (CommonColor color) + : base (color) + { + } + + public ColorComittedEventArgs (Exception exception) + : base (default(CommonColor)) + { + Exception = exception; + } + + public Exception Exception + { + get; + } + } + + internal class Eyedropper + : IDisposable + { + public Eyedropper () + { + this.dc = GetDC (IntPtr.Zero); + this.updaterThread = new Thread (Updater); + this.updaterThread.Start (); + } + + public event EventHandler<ColorEventArgs> ColorChanged; + public event EventHandler<ColorComittedEventArgs> ColorComitted; + + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + + ~Eyedropper () + { + Dispose (false); + } + + protected virtual void Dispose (bool disposing) + { + if (!this.running) + return; + + this.running = false; + this.updaterThread.Join (); + ReleaseDC (IntPtr.Zero, this.dc); + } + + private readonly IntPtr dc; + private volatile bool running = true; + private readonly Thread updaterThread; + private readonly SynchronizationContext context = SynchronizationContext.Current; + + private void Updater () + { + // AFAICT it's this or global hooks. Global hooks are bad. + int pixel = 0; + while (this.running) { + if (!this.running) + return; + + if (!GetCursorPos (out POINT point)) { + Finish (new ColorComittedEventArgs (new Win32Exception ())); + return; + } + + short keyState = GetKeyState (VK_LBUTTON); + int newPixel = GetPixel (this.dc, point.x, point.y); + if (keyState > 0) { + Finish (new ColorComittedEventArgs (GetColor (newPixel))); + return; + } + + if (pixel != newPixel) + Update (new ColorEventArgs (GetColor (newPixel))); + + pixel = newPixel; + Thread.Sleep (0); + } + } + + private CommonColor GetColor (int pixel) + { + return new CommonColor ((byte)(pixel & 0x000000ff), (byte)((pixel & 0x0000ff00) >> 0x8), (byte)((pixel & 0x00ff0000) >> 0x10)); + } + + private void Update (ColorEventArgs args) + { + this.context.Post (s => { ColorChanged?.Invoke (this, (ColorEventArgs) s); }, args); + } + + private void Finish (ColorComittedEventArgs args) + { + this.context.Post (s => { + ColorComitted?.Invoke (this, (ColorComittedEventArgs)s); + }, args); + } + + private struct POINT + { + public int x; + public int y; + } + + private const short VK_LBUTTON = 0x01; + + [DllImport ("Gdi32.dll")] + private static extern int GetPixel (IntPtr hdc, int x, int y); + + [DllImport ("User32.dll")] + private static extern short GetKeyState (short vkey); + + [DllImport ("User32.dll")] + private static extern bool GetCursorPos (out POINT point); + + [DllImport ("User32.dll")] + private static extern IntPtr GetDC (IntPtr hwnd); + + [DllImport ("User32.dll")] + private static extern int ReleaseDC (IntPtr hwnd, IntPtr dc); + } +} diff --git a/Xamarin.PropertyEditing.Windows/SolidBrushEditorControl.cs b/Xamarin.PropertyEditing.Windows/SolidBrushEditorControl.cs index 3cee572..1954e27 100644 --- a/Xamarin.PropertyEditing.Windows/SolidBrushEditorControl.cs +++ b/Xamarin.PropertyEditing.Windows/SolidBrushEditorControl.cs @@ -1,6 +1,7 @@ using System; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using Xamarin.PropertyEditing.Drawing; using Xamarin.PropertyEditing.ViewModels; @@ -22,6 +23,10 @@ namespace Xamarin.PropertyEditing.Windows if (this.colorSpacePicker == null) throw new InvalidOperationException ($"{nameof (SolidBrushEditorControl)} is missing a child ComboBox named \"colorSpacePicker\""); + this.eyedropperButton = GetTemplateChild ("eyedropper") as ToggleButton; + if (this.eyedropperButton != null) + this.eyedropperButton.Checked += OnEyedropper; + // Handle color space changes this.colorSpacePicker.SelectionChanged += (s, e) => { if (ViewModel?.Value != null && ViewModel.Property.CanWrite) { @@ -35,9 +40,28 @@ namespace Xamarin.PropertyEditing.Windows AddHandler (CurrentColorCommitterControlBase.CommitHueEvent, new RoutedEventHandler ((s, e) => ViewModel?.Solid.CommitHue ())); } - + + private ToggleButton eyedropperButton; + private Eyedropper eyedropper; private ComboBox colorSpacePicker; private BrushPropertyViewModel ViewModel => DataContext as BrushPropertyViewModel; + + private void OnEyedropper (object sender, RoutedEventArgs e) + { + var eye = new Eyedropper (); + eye.ColorChanged += (o, args) => ViewModel.Solid.Color = args.Color; + eye.ColorComitted += (o, args) => { + if (args.Exception == null) { + ViewModel.Solid.Color = args.Color; + ViewModel.Solid.CommitLastColor (); + } + + ((Eyedropper)o).Dispose (); + this.eyedropperButton.IsChecked = false; + }; + + this.eyedropper = eye; + } } } diff --git a/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml b/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml index e3bdad0..1ee71d1 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/Resources.xaml @@ -740,6 +740,7 @@ </Setter.Value> </Setter> </Style> + <Style TargetType="local:SolidBrushEditorControl"> <Setter Property="Template"> <Setter.Value> @@ -777,13 +778,15 @@ Margin="0,6,0,1" Panel.ZIndex="1"/> <local:HueEditorControl x:Name="hueChooser" HueColor="{Binding Path=Solid.HueColor, Mode=TwoWay}" - Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1,6,3,1" Panel.ZIndex="0" Focusable="False"/> + Grid.Column="1" Grid.Row="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1,6,3,1" Panel.ZIndex="0" Focusable="False"/> <local:CurrentColorEditorControl Color="{Binding Path=Solid.Color, Mode=TwoWay}" InitialColor="{Binding Solid.InitialColor}" LastColor="{Binding Solid.LastColor}" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Stretch" Height="20" Margin="0,0,0,0" Panel.ZIndex="0" Focusable="False"/> + + <ToggleButton Grid.Column="1" Grid.Row="1" Name="eyedropper" Style="{DynamicResource ImageToggleButton}" Width="20" Height="20" /> </Grid> <local:ColorComponentsEditorControl x:Name="componentEditor" Color="{Binding Path=Solid.Color, Mode=TwoWay}" @@ -1880,6 +1883,33 @@ </Setter> </Style> + <Style x:Key="ImageToggleButton" TargetType="ToggleButton"> + <Setter Property="Height" Value="16" /> + <Setter Property="Width" Value="16"/> + <Setter Property="Background" Value="{DynamicResource IconButtonSimpleBackgroundBrush}" /> + <Setter Property="Foreground" Value="{DynamicResource IconButtonForegroundBrush}" /> + <Setter Property="BorderBrush" Value="Transparent" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="ToggleButton"> + <Border Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"> + <ContentPresenter /> + </Border> + <ControlTemplate.Triggers> + <Trigger Property="IsMouseOver" Value="True"> + <Setter TargetName="border" Property="Background" Value="{DynamicResource IconButtonMouseOverBackgroundBrush}" /> + <Setter TargetName="border" Property="BorderBrush" Value="{DynamicResource IconButtonMouseOverBorderBrush}" /> + </Trigger> + <Trigger Property="IsChecked" Value="True"> + <Setter TargetName="border" Property="Background" Value="{DynamicResource IconButtonMouseOverBackgroundBrush}" /> + <Setter TargetName="border" Property="BorderBrush" Value="{DynamicResource IconButtonMouseOverBorderBrush}" /> + </Trigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + <Style x:Key="SearchButtonBase" TargetType="Button" BasedOn="{StaticResource IconButton}"> <Setter Property="Margin" Value="-1" /> <Setter Property="Template"> diff --git a/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml b/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml index 880df43..1f8e5c7 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/VS.Dark.xaml @@ -94,6 +94,8 @@ <SolidColorBrush x:Key="IconButtonSimpleBorderBrush" Color="Transparent" /> <SolidColorBrush x:Key="IconButtonForegroundBrush">#FFF1F1F1</SolidColorBrush> <SolidColorBrush x:Key="IconButtonMouseOverForegroundBrush">#FF007ACC</SolidColorBrush> + <SolidColorBrush x:Key="IconButtonMouseOverBackgroundBrush">#FF3E3E40</SolidColorBrush> + <SolidColorBrush x:Key="IconButtonMouseOverBorderBrush">#FF3E3E40</SolidColorBrush> <SolidColorBrush x:Key="IconButtonPressedForegroundBrush">#FFFFFFFF</SolidColorBrush> <SolidColorBrush x:Key="CategoryExpanderBorderBrush" Color="#333333" /> diff --git a/Xamarin.PropertyEditing.Windows/Themes/VS.Light.xaml b/Xamarin.PropertyEditing.Windows/Themes/VS.Light.xaml index 3e8279a..f9163f9 100644 --- a/Xamarin.PropertyEditing.Windows/Themes/VS.Light.xaml +++ b/Xamarin.PropertyEditing.Windows/Themes/VS.Light.xaml @@ -94,6 +94,8 @@ <SolidColorBrush x:Key="IconButtonSimpleBorderBrush" Color="Transparent" /> <SolidColorBrush x:Key="IconButtonForegroundBrush">#FF1E1E1E</SolidColorBrush> <SolidColorBrush x:Key="IconButtonMouseOverForegroundBrush">#FF1E1E1E</SolidColorBrush> + <SolidColorBrush x:Key="IconButtonMouseOverBackgroundBrush">#FFC9DEF5</SolidColorBrush> + <SolidColorBrush x:Key="IconButtonMouseOverBorderBrush">#FFC9DEF5</SolidColorBrush> <SolidColorBrush x:Key="IconButtonPressedForegroundBrush">#FFFFFFFF</SolidColorBrush> <SolidColorBrush x:Key="ComboBoxBackgroundBrush">#FFFFFFFF</SolidColorBrush> diff --git a/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj b/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj index 6fdaea3..bf9ec15 100644 --- a/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj +++ b/Xamarin.PropertyEditing.Windows/Xamarin.PropertyEditing.Windows.csproj @@ -95,6 +95,7 @@ <Compile Include="CurrentColorEditorControl.cs" /> <Compile Include="DoubleToPercentageConverter.cs" /> <Compile Include="DoubleToQuantityConverter.cs" /> + <Compile Include="Eyedropper.cs" /> <Compile Include="HasItemsToVisibilityConverter.cs" /> <Compile Include="InvertedVisibilityConverter.cs" /> <Compile Include="IPropertiesHost.cs" /> |