Files
HawkeyeVision/framework/MaterialSkin.Core/Controls/MaterialSingleLineTextField.cs
2025-07-14 12:03:59 +02:00

1170 lines
30 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using MaterialSkin.Animations;
namespace MaterialSkin.Controls
{
public class MaterialSingleLineTextField : Control, IMaterialControl
{
//Properties for managing the material design properties
[Browsable(false)]
public int Depth { get; set; }
[Browsable(false)]
public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
[Browsable(false)]
public MouseState MouseState { get; set; }
private readonly BaseTextBox _baseTextBox;
private readonly AnimationManager _animationManager;
public override string Text { get { return _baseTextBox.Text; } set { _baseTextBox.Text = value; } }
public new object Tag { get { return _baseTextBox.Tag; } set { _baseTextBox.Tag = value; } }
public new int MaxLength { get { return _baseTextBox.MaxLength; } set { _baseTextBox.MaxLength = value; } }
public string SelectedText { get { return _baseTextBox.SelectedText; } set { _baseTextBox.SelectedText = value; } }
public string Hint { get { return _baseTextBox.Hint; } set { _baseTextBox.Hint = value; } }
public int SelectionStart { get { return _baseTextBox.SelectionStart; } set { _baseTextBox.SelectionStart = value; } }
public int SelectionLength { get { return _baseTextBox.SelectionLength; } set { _baseTextBox.SelectionLength = value; } }
public int TextLength => _baseTextBox.TextLength;
public bool UseSystemPasswordChar { get { return _baseTextBox.UseSystemPasswordChar; } set { _baseTextBox.UseSystemPasswordChar = value; } }
public char PasswordChar { get { return _baseTextBox.PasswordChar; } set { _baseTextBox.PasswordChar = value; } }
public void SelectAll() { _baseTextBox.SelectAll(); }
public void Clear() { _baseTextBox.Clear(); }
public void Focus() { _baseTextBox.Focus(); }
# region Forwarding events to baseTextBox
public event EventHandler AcceptsTabChanged
{
add
{
_baseTextBox.AcceptsTabChanged += value;
}
remove
{
_baseTextBox.AcceptsTabChanged -= value;
}
}
public new event EventHandler AutoSizeChanged
{
add
{
_baseTextBox.AutoSizeChanged += value;
}
remove
{
_baseTextBox.AutoSizeChanged -= value;
}
}
public new event EventHandler BackgroundImageChanged
{
add
{
_baseTextBox.BackgroundImageChanged += value;
}
remove
{
_baseTextBox.BackgroundImageChanged -= value;
}
}
public new event EventHandler BackgroundImageLayoutChanged
{
add
{
_baseTextBox.BackgroundImageLayoutChanged += value;
}
remove
{
_baseTextBox.BackgroundImageLayoutChanged -= value;
}
}
public new event EventHandler BindingContextChanged
{
add
{
_baseTextBox.BindingContextChanged += value;
}
remove
{
_baseTextBox.BindingContextChanged -= value;
}
}
public event EventHandler BorderStyleChanged
{
add
{
_baseTextBox.BorderStyleChanged += value;
}
remove
{
_baseTextBox.BorderStyleChanged -= value;
}
}
public new event EventHandler CausesValidationChanged
{
add
{
_baseTextBox.CausesValidationChanged += value;
}
remove
{
_baseTextBox.CausesValidationChanged -= value;
}
}
public new event UICuesEventHandler ChangeUICues
{
add
{
_baseTextBox.ChangeUICues += value;
}
remove
{
_baseTextBox.ChangeUICues -= value;
}
}
public new event EventHandler Click
{
add
{
_baseTextBox.Click += value;
}
remove
{
_baseTextBox.Click -= value;
}
}
public new event EventHandler ClientSizeChanged
{
add
{
_baseTextBox.ClientSizeChanged += value;
}
remove
{
_baseTextBox.ClientSizeChanged -= value;
}
}
public new event EventHandler ContextMenuStripChanged
{
add
{
_baseTextBox.ContextMenuStripChanged += value;
}
remove
{
_baseTextBox.ContextMenuStripChanged -= value;
}
}
public new event ControlEventHandler ControlAdded
{
add
{
_baseTextBox.ControlAdded += value;
}
remove
{
_baseTextBox.ControlAdded -= value;
}
}
public new event ControlEventHandler ControlRemoved
{
add
{
_baseTextBox.ControlRemoved += value;
}
remove
{
_baseTextBox.ControlRemoved -= value;
}
}
public new event EventHandler CursorChanged
{
add
{
_baseTextBox.CursorChanged += value;
}
remove
{
_baseTextBox.CursorChanged -= value;
}
}
public new event EventHandler Disposed
{
add
{
_baseTextBox.Disposed += value;
}
remove
{
_baseTextBox.Disposed -= value;
}
}
public new event EventHandler DockChanged
{
add
{
_baseTextBox.DockChanged += value;
}
remove
{
_baseTextBox.DockChanged -= value;
}
}
public new event EventHandler DoubleClick
{
add
{
_baseTextBox.DoubleClick += value;
}
remove
{
_baseTextBox.DoubleClick -= value;
}
}
public new event DragEventHandler DragDrop
{
add
{
_baseTextBox.DragDrop += value;
}
remove
{
_baseTextBox.DragDrop -= value;
}
}
public new event DragEventHandler DragEnter
{
add
{
_baseTextBox.DragEnter += value;
}
remove
{
_baseTextBox.DragEnter -= value;
}
}
public new event EventHandler DragLeave
{
add
{
_baseTextBox.DragLeave += value;
}
remove
{
_baseTextBox.DragLeave -= value;
}
}
public new event DragEventHandler DragOver
{
add
{
_baseTextBox.DragOver += value;
}
remove
{
_baseTextBox.DragOver -= value;
}
}
public new event EventHandler EnabledChanged
{
add
{
_baseTextBox.EnabledChanged += value;
}
remove
{
_baseTextBox.EnabledChanged -= value;
}
}
public new event EventHandler Enter
{
add
{
_baseTextBox.Enter += value;
}
remove
{
_baseTextBox.Enter -= value;
}
}
public new event EventHandler FontChanged
{
add
{
_baseTextBox.FontChanged += value;
}
remove
{
_baseTextBox.FontChanged -= value;
}
}
public new event EventHandler ForeColorChanged
{
add
{
_baseTextBox.ForeColorChanged += value;
}
remove
{
_baseTextBox.ForeColorChanged -= value;
}
}
public new event GiveFeedbackEventHandler GiveFeedback
{
add
{
_baseTextBox.GiveFeedback += value;
}
remove
{
_baseTextBox.GiveFeedback -= value;
}
}
public new event EventHandler GotFocus
{
add
{
_baseTextBox.GotFocus += value;
}
remove
{
_baseTextBox.GotFocus -= value;
}
}
public new event EventHandler HandleCreated
{
add
{
_baseTextBox.HandleCreated += value;
}
remove
{
_baseTextBox.HandleCreated -= value;
}
}
public new event EventHandler HandleDestroyed
{
add
{
_baseTextBox.HandleDestroyed += value;
}
remove
{
_baseTextBox.HandleDestroyed -= value;
}
}
public new event HelpEventHandler HelpRequested
{
add
{
_baseTextBox.HelpRequested += value;
}
remove
{
_baseTextBox.HelpRequested -= value;
}
}
public event EventHandler HideSelectionChanged
{
add
{
_baseTextBox.HideSelectionChanged += value;
}
remove
{
_baseTextBox.HideSelectionChanged -= value;
}
}
public new event EventHandler ImeModeChanged
{
add
{
_baseTextBox.ImeModeChanged += value;
}
remove
{
_baseTextBox.ImeModeChanged -= value;
}
}
public new event InvalidateEventHandler Invalidated
{
add
{
_baseTextBox.Invalidated += value;
}
remove
{
_baseTextBox.Invalidated -= value;
}
}
public new event KeyEventHandler KeyDown
{
add
{
_baseTextBox.KeyDown += value;
}
remove
{
_baseTextBox.KeyDown -= value;
}
}
public new event KeyPressEventHandler KeyPress
{
add
{
_baseTextBox.KeyPress += value;
}
remove
{
_baseTextBox.KeyPress -= value;
}
}
public new event KeyEventHandler KeyUp
{
add
{
_baseTextBox.KeyUp += value;
}
remove
{
_baseTextBox.KeyUp -= value;
}
}
public new event LayoutEventHandler Layout
{
add
{
_baseTextBox.Layout += value;
}
remove
{
_baseTextBox.Layout -= value;
}
}
public new event EventHandler Leave
{
add
{
_baseTextBox.Leave += value;
}
remove
{
_baseTextBox.Leave -= value;
}
}
public new event EventHandler LocationChanged
{
add
{
_baseTextBox.LocationChanged += value;
}
remove
{
_baseTextBox.LocationChanged -= value;
}
}
public new event EventHandler LostFocus
{
add
{
_baseTextBox.LostFocus += value;
}
remove
{
_baseTextBox.LostFocus -= value;
}
}
public new event EventHandler MarginChanged
{
add
{
_baseTextBox.MarginChanged += value;
}
remove
{
_baseTextBox.MarginChanged -= value;
}
}
public event EventHandler ModifiedChanged
{
add
{
_baseTextBox.ModifiedChanged += value;
}
remove
{
_baseTextBox.ModifiedChanged -= value;
}
}
public new event EventHandler MouseCaptureChanged
{
add
{
_baseTextBox.MouseCaptureChanged += value;
}
remove
{
_baseTextBox.MouseCaptureChanged -= value;
}
}
public new event MouseEventHandler MouseClick
{
add
{
_baseTextBox.MouseClick += value;
}
remove
{
_baseTextBox.MouseClick -= value;
}
}
public new event MouseEventHandler MouseDoubleClick
{
add
{
_baseTextBox.MouseDoubleClick += value;
}
remove
{
_baseTextBox.MouseDoubleClick -= value;
}
}
public new event MouseEventHandler MouseDown
{
add
{
_baseTextBox.MouseDown += value;
}
remove
{
_baseTextBox.MouseDown -= value;
}
}
public new event EventHandler MouseEnter
{
add
{
_baseTextBox.MouseEnter += value;
}
remove
{
_baseTextBox.MouseEnter -= value;
}
}
public new event EventHandler MouseHover
{
add
{
_baseTextBox.MouseHover += value;
}
remove
{
_baseTextBox.MouseHover -= value;
}
}
public new event EventHandler MouseLeave
{
add
{
_baseTextBox.MouseLeave += value;
}
remove
{
_baseTextBox.MouseLeave -= value;
}
}
public new event MouseEventHandler MouseMove
{
add
{
_baseTextBox.MouseMove += value;
}
remove
{
_baseTextBox.MouseMove -= value;
}
}
public new event MouseEventHandler MouseUp
{
add
{
_baseTextBox.MouseUp += value;
}
remove
{
_baseTextBox.MouseUp -= value;
}
}
public new event MouseEventHandler MouseWheel
{
add
{
_baseTextBox.MouseWheel += value;
}
remove
{
_baseTextBox.MouseWheel -= value;
}
}
public new event EventHandler Move
{
add
{
_baseTextBox.Move += value;
}
remove
{
_baseTextBox.Move -= value;
}
}
public event EventHandler MultilineChanged
{
add
{
_baseTextBox.MultilineChanged += value;
}
remove
{
_baseTextBox.MultilineChanged -= value;
}
}
public new event EventHandler PaddingChanged
{
add
{
_baseTextBox.PaddingChanged += value;
}
remove
{
_baseTextBox.PaddingChanged -= value;
}
}
public new event PaintEventHandler Paint
{
add
{
_baseTextBox.Paint += value;
}
remove
{
_baseTextBox.Paint -= value;
}
}
public new event EventHandler ParentChanged
{
add
{
_baseTextBox.ParentChanged += value;
}
remove
{
_baseTextBox.ParentChanged -= value;
}
}
public new event PreviewKeyDownEventHandler PreviewKeyDown
{
add
{
_baseTextBox.PreviewKeyDown += value;
}
remove
{
_baseTextBox.PreviewKeyDown -= value;
}
}
public new event QueryAccessibilityHelpEventHandler QueryAccessibilityHelp
{
add
{
_baseTextBox.QueryAccessibilityHelp += value;
}
remove
{
_baseTextBox.QueryAccessibilityHelp -= value;
}
}
public new event QueryContinueDragEventHandler QueryContinueDrag
{
add
{
_baseTextBox.QueryContinueDrag += value;
}
remove
{
_baseTextBox.QueryContinueDrag -= value;
}
}
public event EventHandler ReadOnlyChanged
{
add
{
_baseTextBox.ReadOnlyChanged += value;
}
remove
{
_baseTextBox.ReadOnlyChanged -= value;
}
}
public new event EventHandler RegionChanged
{
add
{
_baseTextBox.RegionChanged += value;
}
remove
{
_baseTextBox.RegionChanged -= value;
}
}
public new event EventHandler Resize
{
add
{
_baseTextBox.Resize += value;
}
remove
{
_baseTextBox.Resize -= value;
}
}
public new event EventHandler RightToLeftChanged
{
add
{
_baseTextBox.RightToLeftChanged += value;
}
remove
{
_baseTextBox.RightToLeftChanged -= value;
}
}
public new event EventHandler SizeChanged
{
add
{
_baseTextBox.SizeChanged += value;
}
remove
{
_baseTextBox.SizeChanged -= value;
}
}
public new event EventHandler StyleChanged
{
add
{
_baseTextBox.StyleChanged += value;
}
remove
{
_baseTextBox.StyleChanged -= value;
}
}
public new event EventHandler SystemColorsChanged
{
add
{
_baseTextBox.SystemColorsChanged += value;
}
remove
{
_baseTextBox.SystemColorsChanged -= value;
}
}
public new event EventHandler TabIndexChanged
{
add
{
_baseTextBox.TabIndexChanged += value;
}
remove
{
_baseTextBox.TabIndexChanged -= value;
}
}
public new event EventHandler TabStopChanged
{
add
{
_baseTextBox.TabStopChanged += value;
}
remove
{
_baseTextBox.TabStopChanged -= value;
}
}
public event EventHandler TextAlignChanged
{
add
{
_baseTextBox.TextAlignChanged += value;
}
remove
{
_baseTextBox.TextAlignChanged -= value;
}
}
public new event EventHandler TextChanged
{
add
{
_baseTextBox.TextChanged += value;
}
remove
{
_baseTextBox.TextChanged -= value;
}
}
public new event EventHandler Validated
{
add
{
_baseTextBox.Validated += value;
}
remove
{
_baseTextBox.Validated -= value;
}
}
public new event CancelEventHandler Validating
{
add
{
_baseTextBox.Validating += value;
}
remove
{
_baseTextBox.Validating -= value;
}
}
public new event EventHandler VisibleChanged
{
add
{
_baseTextBox.VisibleChanged += value;
}
remove
{
_baseTextBox.VisibleChanged -= value;
}
}
#endregion
public MaterialSingleLineTextField()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.DoubleBuffer, true);
_animationManager = new AnimationManager
{
Increment = 0.06,
AnimationType = AnimationType.EaseInOut,
InterruptAnimation = false
};
_animationManager.OnAnimationProgress += sender => Invalidate();
_baseTextBox = new BaseTextBox
{
BorderStyle = BorderStyle.None,
Font = SkinManager.ROBOTO_REGULAR_11,
ForeColor = SkinManager.GetPrimaryTextColor(),
Location = new Point(0, 0),
Width = Width,
Height = Height - 5
};
if (!Controls.Contains(_baseTextBox) && !DesignMode)
{
Controls.Add(_baseTextBox);
}
_baseTextBox.GotFocus += (sender, args) => _animationManager.StartNewAnimation(AnimationDirection.In);
_baseTextBox.LostFocus += (sender, args) => _animationManager.StartNewAnimation(AnimationDirection.Out);
BackColorChanged += (sender, args) =>
{
_baseTextBox.BackColor = BackColor;
_baseTextBox.ForeColor = SkinManager.GetPrimaryTextColor();
};
//Fix for tabstop
_baseTextBox.TabStop = true;
this.TabStop = false;
}
protected override void OnPaint(PaintEventArgs pevent)
{
var g = pevent.Graphics;
g.Clear(Parent.BackColor);
var lineY = _baseTextBox.Bottom + 3;
if (!_animationManager.IsAnimating())
{
//No animation
g.FillRectangle(_baseTextBox.Focused ? SkinManager.ColorScheme.PrimaryBrush : SkinManager.GetDividersBrush(), _baseTextBox.Location.X, lineY, _baseTextBox.Width, _baseTextBox.Focused ? 2 : 1);
}
else
{
//Animate
int animationWidth = (int)(_baseTextBox.Width * _animationManager.GetProgress());
int halfAnimationWidth = animationWidth / 2;
int animationStart = _baseTextBox.Location.X + _baseTextBox.Width / 2;
//Unfocused background
g.FillRectangle(SkinManager.GetDividersBrush(), _baseTextBox.Location.X, lineY, _baseTextBox.Width, 1);
//Animated focus transition
g.FillRectangle(SkinManager.ColorScheme.PrimaryBrush, animationStart - halfAnimationWidth, lineY, animationWidth, 2);
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
_baseTextBox.Location = new Point(0, 0);
_baseTextBox.Width = Width;
Height = _baseTextBox.Height + 5;
}
protected override void OnCreateControl()
{
base.OnCreateControl();
_baseTextBox.BackColor = Parent.BackColor;
_baseTextBox.ForeColor = SkinManager.GetPrimaryTextColor();
}
private class BaseTextBox : TextBox
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, string lParam);
private const int EM_SETCUEBANNER = 0x1501;
private const char EmptyChar = (char)0;
private const char VisualStylePasswordChar = '\u25CF';
private const char NonVisualStylePasswordChar = '\u002A';
private string hint = string.Empty;
public string Hint
{
get { return hint; }
set
{
hint = value;
SendMessage(Handle, EM_SETCUEBANNER, (int)IntPtr.Zero, Hint);
}
}
private char _passwordChar = EmptyChar;
public new char PasswordChar
{
get { return _passwordChar; }
set
{
_passwordChar = value;
SetBasePasswordChar();
}
}
public new void SelectAll()
{
BeginInvoke((MethodInvoker)delegate ()
{
base.Focus();
base.SelectAll();
});
}
public new void Focus()
{
BeginInvoke((MethodInvoker)delegate ()
{
base.Focus();
});
}
private char _useSystemPasswordChar = EmptyChar;
public new bool UseSystemPasswordChar
{
get { return _useSystemPasswordChar != EmptyChar; }
set
{
if (value)
{
_useSystemPasswordChar = Application.RenderWithVisualStyles ? VisualStylePasswordChar : NonVisualStylePasswordChar;
}
else
{
_useSystemPasswordChar = EmptyChar;
}
SetBasePasswordChar();
}
}
private void SetBasePasswordChar()
{
base.PasswordChar = UseSystemPasswordChar ? _useSystemPasswordChar : _passwordChar;
}
public BaseTextBox()
{
MaterialContextMenuStrip cms = new TextBoxContextMenuStrip();
cms.Opening += ContextMenuStripOnOpening;
cms.OnItemClickStart += ContextMenuStripOnItemClickStart;
ContextMenuStrip = cms;
}
private void ContextMenuStripOnItemClickStart(object sender, ToolStripItemClickedEventArgs toolStripItemClickedEventArgs)
{
switch (toolStripItemClickedEventArgs.ClickedItem.Text)
{
case "Undo":
Undo();
break;
case "Cut":
Cut();
break;
case "Copy":
Copy();
break;
case "Paste":
Paste();
break;
case "Delete":
SelectedText = string.Empty;
break;
case "Select All":
SelectAll();
break;
}
}
private void ContextMenuStripOnOpening(object sender, CancelEventArgs cancelEventArgs)
{
var strip = sender as TextBoxContextMenuStrip;
if (strip != null)
{
strip.Undo.Enabled = CanUndo;
strip.Cut.Enabled = !string.IsNullOrEmpty(SelectedText);
strip.Copy.Enabled = !string.IsNullOrEmpty(SelectedText);
strip.Paste.Enabled = Clipboard.ContainsText();
strip.Delete.Enabled = !string.IsNullOrEmpty(SelectedText);
strip.SelectAll.Enabled = !string.IsNullOrEmpty(Text);
}
}
}
private class TextBoxContextMenuStrip : MaterialContextMenuStrip
{
public readonly ToolStripItem Undo = new MaterialToolStripMenuItem { Text = "Undo" };
public readonly ToolStripItem Seperator1 = new ToolStripSeparator();
public readonly ToolStripItem Cut = new MaterialToolStripMenuItem { Text = "Cut" };
public readonly ToolStripItem Copy = new MaterialToolStripMenuItem { Text = "Copy" };
public readonly ToolStripItem Paste = new MaterialToolStripMenuItem { Text = "Paste" };
public readonly ToolStripItem Delete = new MaterialToolStripMenuItem { Text = "Delete" };
public readonly ToolStripItem Seperator2 = new ToolStripSeparator();
public readonly ToolStripItem SelectAll = new MaterialToolStripMenuItem { Text = "Select All" };
public TextBoxContextMenuStrip()
{
Items.AddRange(new[]
{
Undo,
Seperator1,
Cut,
Copy,
Paste,
Delete,
Seperator2,
SelectAll
});
}
}
}
}