diff --git a/src/Eto.WinForms/Eto.WinForms.csproj b/src/Eto.WinForms/Eto.WinForms.csproj index 0ee8c7f1f1..d400687dff 100755 --- a/src/Eto.WinForms/Eto.WinForms.csproj +++ b/src/Eto.WinForms/Eto.WinForms.csproj @@ -16,6 +16,7 @@ $(DefineConstants);WINFORMS MSB4011;$(NoWarn) true + True @@ -118,9 +119,24 @@ You do not need to use any of the classes of this assembly (unless customizing t + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + diff --git a/src/Eto.WinForms/Forms/Controls/SearchBoxHandler.cs b/src/Eto.WinForms/Forms/Controls/SearchBoxHandler.cs old mode 100644 new mode 100755 index 41ed11db83..6e65b64a28 --- a/src/Eto.WinForms/Forms/Controls/SearchBoxHandler.cs +++ b/src/Eto.WinForms/Forms/Controls/SearchBoxHandler.cs @@ -1,10 +1,110 @@ -using SD = System.Drawing; -using SWF = System.Windows.Forms; +using sd = System.Drawing; +using swf = System.Windows.Forms; using Eto.Forms; +using Eto.WinForms.CustomControls; +using System; namespace Eto.WinForms.Forms.Controls { - public class SearchBoxHandler : TextBoxHandler, SearchBox.IHandler + public class EtoSearchTextBox : EtoTextBox { + private readonly swf.PictureBox searchImage; + + private readonly swf.Button clearSearchButton; + + public EtoSearchTextBox() + { + clearSearchButton = new swf.Button + { + Dock = swf.DockStyle.Right, + Size = new sd.Size(16, 16), + TabStop = false, + FlatStyle = swf.FlatStyle.Flat, + Cursor = swf.Cursors.Arrow, + ImageAlign = sd.ContentAlignment.MiddleCenter, + Image = Resources.Clear + }; + clearSearchButton.FlatAppearance.BorderSize = 0; + clearSearchButton.Click += Clear_Click; + + searchImage = new swf.PictureBox + { + Dock = swf.DockStyle.Left, + Size = new sd.Size(16, 16), + TabIndex = 0, + SizeMode = swf.PictureBoxSizeMode.CenterImage, + Image = Resources.Search + }; + + + Controls.Add(clearSearchButton); + Controls.Add(searchImage); + + UpdateClearButton(); + } + + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + SetRounded(); + } + + protected override void OnCreateControl() + { + base.OnCreateControl(); + SetRounded(); + } + + private void SetRounded() + { + Region = sd.Region.FromHrgn(Win32.CreateRoundRectRgn(1, 1, Width, Height, Height * 2 / 3, Height * 2 / 3)); + Win32.SendMessage(Handle, Win32.WM.EM_SETMARGINS, (IntPtr)3, (IntPtr)((16 << 16) + 16)); + } + + private void Clear_Click(object sender, EventArgs e) + { + Text = string.Empty; + Focus(); + } + + protected override void OnTextChanged(EventArgs e) + { + base.OnTextChanged(e); + UpdateClearButton(); + } + + private void UpdateClearButton() + { + var showClearButton = !string.IsNullOrEmpty(Text); + if (clearSearchButton.Visible != showClearButton) + { + clearSearchButton.Visible = showClearButton; + } + } + + public sd.Image SearchImage + { + set => searchImage.Image = value; + get => searchImage.Image; + } + + public sd.Image CancelSearchImage + { + set => clearSearchButton.Image = value; + get => clearSearchButton.Image; + } + } + + public class SearchBoxHandler : TextBoxHandler, SearchBox.IHandler + { + public override swf.TextBox SwfTextBox => Control; + + public override EtoTextBox EtoTextBox => Control; + + public SearchBoxHandler() + { + Control = new EtoSearchTextBox(); + } } } diff --git a/src/Eto.WinForms/Resources.Designer.cs b/src/Eto.WinForms/Resources.Designer.cs new file mode 100755 index 0000000000..5854b455ca --- /dev/null +++ b/src/Eto.WinForms/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Eto.WinForms { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Eto.WinForms.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Clear { + get { + object obj = ResourceManager.GetObject("Clear", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Search { + get { + object obj = ResourceManager.GetObject("Search", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/src/Eto.WinForms/Resources.resx b/src/Eto.WinForms/Resources.resx new file mode 100755 index 0000000000..2d6a719c4b --- /dev/null +++ b/src/Eto.WinForms/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Resources\Clear.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Search.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/src/Eto.WinForms/Resources/Clear.png b/src/Eto.WinForms/Resources/Clear.png new file mode 100644 index 0000000000..bcc8034f1e Binary files /dev/null and b/src/Eto.WinForms/Resources/Clear.png differ diff --git a/src/Eto.WinForms/Resources/Search.png b/src/Eto.WinForms/Resources/Search.png new file mode 100644 index 0000000000..8dbef3ed55 Binary files /dev/null and b/src/Eto.WinForms/Resources/Search.png differ diff --git a/src/Eto.WinForms/Win32.cs b/src/Eto.WinForms/Win32.cs old mode 100644 new mode 100755 index f42122b30e..a38ecc01ac --- a/src/Eto.WinForms/Win32.cs +++ b/src/Eto.WinForms/Win32.cs @@ -182,6 +182,7 @@ public enum WM ECM_FIRST = 0x1500, EM_SETCUEBANNER = ECM_FIRST + 1, + EM_SETMARGINS = 0xd3, DPICHANGED = 0x02E0, NCCREATE = 0x0081, @@ -500,6 +501,10 @@ public static IntPtr GetThreadFocusWindow(uint? threadId = null) [DllImport("gdi32.dll")] public static extern bool OffsetWindowOrgEx(IntPtr hdc, int nXOffset, int nYOffset, ref POINT lpPoint); + [DllImport("gdi32.dll")] + public static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nheightRect, int nweightRect); + + [DllImport("user32.dll")] public static extern IntPtr WindowFromPoint(POINT lpPoint); diff --git a/src/Eto.Wpf/Forms/Controls/SearchBoxHandler.cs b/src/Eto.Wpf/Forms/Controls/SearchBoxHandler.cs old mode 100644 new mode 100755 index 65960c7a15..a6a307a24d --- a/src/Eto.Wpf/Forms/Controls/SearchBoxHandler.cs +++ b/src/Eto.Wpf/Forms/Controls/SearchBoxHandler.cs @@ -1,8 +1,59 @@ using Eto.Forms; +using Xceed.Wpf.Toolkit; +using static Eto.Win32; +using mwc = Xceed.Wpf.Toolkit; +using swc = System.Windows.Controls; +using sw = System.Windows; +using System.Windows.Input; +using System; namespace Eto.Wpf.Forms.Controls { - public class SearchBoxHandler : TextBoxHandler, SearchBox.IHandler + public class EtoSearchTextBox : EtoWatermarkTextBox { + static readonly sw.DependencyPropertyKey IsEmptyPropertyKey = + sw.DependencyProperty.RegisterReadOnly("IsEmpty", typeof(bool), typeof(EtoSearchTextBox), new sw.PropertyMetadata(true)); + + public static readonly sw.DependencyProperty IsEmptyProperty = IsEmptyPropertyKey.DependencyProperty; + + + public static readonly sw.DependencyProperty ClearCommandProperty = sw.DependencyProperty.Register("ClearCommand", typeof(ICommand), typeof(EtoSearchTextBox)); + + public bool IsEmpty => (bool)GetValue(IsEmptyProperty); + + protected override void OnTextChanged(swc.TextChangedEventArgs e) + { + base.OnTextChanged(e); + SetValue(IsEmptyPropertyKey, string.IsNullOrEmpty(Text)); + } + + public EtoSearchTextBox() + { + ClearCommand = new RelayCommand(Clear); + } + + public ICommand ClearCommand + { + get => (ICommand)GetValue(ClearCommandProperty); + set => SetValue(ClearCommandProperty, value); + } + + } + + public class SearchBoxHandler : TextBoxHandler, SearchBox.IHandler + { + internal static object CurrentText_Key = new object(); + internal static object CurrentSelection_Key = new object(); + internal static object DisableTextChanged_Key = new object(); + + protected override swc.TextBox TextBox => Control; + + protected override WatermarkTextBox CreateControl() => new EtoSearchTextBox { Handler = this, KeepWatermarkOnGotFocus = true }; + + public override string PlaceholderText + { + get => Control.Watermark as string; + set => Control.Watermark = value; + } } } diff --git a/src/Eto.Wpf/themes/aero.normalcolor.xaml b/src/Eto.Wpf/themes/aero.normalcolor.xaml deleted file mode 100644 index 8c06311633..0000000000 --- a/src/Eto.Wpf/themes/aero.normalcolor.xaml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/Eto.Wpf/themes/aero2.normalcolor.xaml b/src/Eto.Wpf/themes/aero2.normalcolor.xaml deleted file mode 100644 index ad6f8dae4a..0000000000 --- a/src/Eto.Wpf/themes/aero2.normalcolor.xaml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/Eto.Wpf/themes/classic.xaml b/src/Eto.Wpf/themes/classic.xaml deleted file mode 100644 index f91389e91e..0000000000 --- a/src/Eto.Wpf/themes/classic.xaml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Eto.Wpf/themes/controls/SearchTextBox.xaml b/src/Eto.Wpf/themes/controls/SearchTextBox.xaml new file mode 100755 index 0000000000..436ecf7bcc --- /dev/null +++ b/src/Eto.Wpf/themes/controls/SearchTextBox.xaml @@ -0,0 +1,135 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Eto.Wpf/themes/controls/ToggleButton.xaml b/src/Eto.Wpf/themes/controls/ToggleButton.xaml new file mode 100755 index 0000000000..acf9173dd7 --- /dev/null +++ b/src/Eto.Wpf/themes/controls/ToggleButton.xaml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Eto.Wpf/themes/controls/WatermarkTextBox.xaml b/src/Eto.Wpf/themes/controls/WatermarkTextBox.xaml new file mode 100755 index 0000000000..83d4955a68 --- /dev/null +++ b/src/Eto.Wpf/themes/controls/WatermarkTextBox.xaml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Eto.Wpf/themes/luna.homestead.xaml b/src/Eto.Wpf/themes/luna.homestead.xaml deleted file mode 100644 index cc6e75f546..0000000000 --- a/src/Eto.Wpf/themes/luna.homestead.xaml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/Eto.Wpf/themes/luna.metallic.xaml b/src/Eto.Wpf/themes/luna.metallic.xaml deleted file mode 100644 index cc6e75f546..0000000000 --- a/src/Eto.Wpf/themes/luna.metallic.xaml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/Eto.Wpf/themes/luna.normalcolor.xaml b/src/Eto.Wpf/themes/luna.normalcolor.xaml deleted file mode 100644 index cc6e75f546..0000000000 --- a/src/Eto.Wpf/themes/luna.normalcolor.xaml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/Eto.Wpf/themes/royale.normalcolor.xaml b/src/Eto.Wpf/themes/royale.normalcolor.xaml deleted file mode 100644 index cc6e75f546..0000000000 --- a/src/Eto.Wpf/themes/royale.normalcolor.xaml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file