| File: System\Windows\Forms\Design\AnchorEditor.AnchorUI.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms.Design\src\System.Windows.Forms.Design.csproj (System.Windows.Forms.Design) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Drawing; namespace System.Windows.Forms.Design; public sealed partial class AnchorEditor { /// <summary> /// User Interface for the AnchorEditor. /// </summary> private class AnchorUI : Control { private readonly SpringControl _bottom; private readonly ContainerPlaceholder _container = new(); private readonly ControlPlaceholder _control = new(); private readonly SpringControl _left; private readonly SpringControl _right; private readonly SpringControl[] _tabOrder; private readonly SpringControl _top; private IWindowsFormsEditorService? _editorService; private AnchorStyles _oldAnchor; public AnchorUI() { _left = new SpringControl(this) { AccessibleRole = AccessibleRole.CheckButton }; _right = new SpringControl(this) { AccessibleRole = AccessibleRole.CheckButton }; _top = new SpringControl(this) { AccessibleRole = AccessibleRole.CheckButton }; _bottom = new SpringControl(this) { AccessibleRole = AccessibleRole.CheckButton }; _tabOrder = [_left, _top, _right, _bottom]; InitializeComponent(); } public object? Value { get; private set; } public void End() { _editorService = null; Value = null; } public virtual AnchorStyles GetSelectedAnchor() { AnchorStyles baseVar = 0; if (_left.IsSolid) { baseVar |= AnchorStyles.Left; } if (_top.IsSolid) { baseVar |= AnchorStyles.Top; } if (_bottom.IsSolid) { baseVar |= AnchorStyles.Bottom; } if (_right.IsSolid) { baseVar |= AnchorStyles.Right; } return baseVar; } internal virtual void InitializeComponent() { int XBORDER = ScaleHelper.ScaleToInitialSystemDpi(SystemInformation.Border3DSize.Width); int YBORDER = ScaleHelper.ScaleToInitialSystemDpi(SystemInformation.Border3DSize.Height); SuspendLayout(); var pixel_10 = ScaleHelper.ScaleToInitialSystemDpi(10); var pixel_30 = ScaleHelper.ScaleToInitialSystemDpi(30); var pixel_40 = ScaleHelper.ScaleToInitialSystemDpi(40); var pixel_60 = ScaleHelper.ScaleToInitialSystemDpi(60); var pixel_90 = ScaleHelper.ScaleToInitialSystemDpi(90); SetBounds(0, 0, pixel_90, pixel_90); AccessibleName = SR.AnchorEditorAccName; _container.Location = new Point(0, 0); _container.Size = new Size(pixel_90, pixel_90); _container.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right; _control.Location = new Point(pixel_30, pixel_30); _control.Size = new Size(pixel_30, pixel_30); _control.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right; _right.Location = new Point(pixel_60, pixel_40); _right.Size = new Size(pixel_30 - XBORDER, pixel_10); _right.TabIndex = 2; _right.TabStop = true; _right.Anchor = AnchorStyles.Right; _right.AccessibleName = SR.AnchorEditorRightAccName; _left.Location = new Point(XBORDER, pixel_40); _left.Size = new Size(pixel_30 - XBORDER, pixel_10); _left.TabIndex = 0; _left.TabStop = true; _left.Anchor = AnchorStyles.Left; _left.AccessibleName = SR.AnchorEditorLeftAccName; _top.Location = new Point(pixel_40, YBORDER); _top.Size = new Size(pixel_10, pixel_30 - YBORDER); _top.TabIndex = 1; _top.TabStop = true; _top.Anchor = AnchorStyles.Top; _top.AccessibleName = SR.AnchorEditorTopAccName; _bottom.Location = new Point(pixel_40, pixel_60); _bottom.Size = new Size(pixel_10, pixel_30 - YBORDER); _bottom.TabIndex = 3; _bottom.TabStop = true; _bottom.Anchor = AnchorStyles.Bottom; _bottom.AccessibleName = SR.AnchorEditorBottomAccName; Controls.Clear(); Controls.AddRange( [ _container ]); _container.Controls.Clear(); _container.Controls.AddRange( [ _control, _top, _left, _bottom, _right ]); ResumeLayout(false); } protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); _top.Focus(); } private void SetValue() { Value = GetSelectedAnchor(); } public void Start(IWindowsFormsEditorService edSvc, object? value) { _editorService = edSvc; Value = value; if (value is AnchorStyles anchorStyles) { _left.IsSolid = (anchorStyles & AnchorStyles.Left) == AnchorStyles.Left; _top.IsSolid = (anchorStyles & AnchorStyles.Top) == AnchorStyles.Top; _bottom.IsSolid = (anchorStyles & AnchorStyles.Bottom) == AnchorStyles.Bottom; _right.IsSolid = (anchorStyles & AnchorStyles.Right) == AnchorStyles.Right; _oldAnchor = anchorStyles; } else { _oldAnchor = AnchorStyles.Top | AnchorStyles.Left; } } private void Teardown(bool saveAnchor) { if (!saveAnchor) { Value = _oldAnchor; } _editorService!.CloseDropDown(); } private class ContainerPlaceholder : Control { public ContainerPlaceholder() { BackColor = SystemColors.Window; ForeColor = SystemColors.WindowText; TabStop = false; } protected override void OnPaint(PaintEventArgs e) { Rectangle rc = ClientRectangle; ControlPaint.DrawBorder3D(e.Graphics, rc, Border3DStyle.Sunken); } } private class ControlPlaceholder : Control { public ControlPlaceholder() { BackColor = SystemColors.Control; TabStop = false; SetStyle(ControlStyles.Selectable, false); } protected override void OnPaint(PaintEventArgs e) { Rectangle rc = ClientRectangle; ControlPaint.DrawButton(e.Graphics, rc, ButtonState.Normal); } } private class SpringControl : Control { private readonly AnchorUI _picker; internal bool _focused; internal bool _solid; public SpringControl(AnchorUI picker) { _picker = picker ?? throw new ArgumentNullException(nameof(picker)); TabStop = true; } protected override AccessibleObject CreateAccessibilityInstance() { return new SpringControlAccessibleObject(this); } public bool IsSolid { get => _solid; set { if (_solid != value) { _solid = value; _picker.SetValue(); Invalidate(); } } } protected override void OnGotFocus(EventArgs e) { if (!_focused) { _focused = true; Invalidate(); } base.OnGotFocus(e); } protected override void OnLostFocus(EventArgs e) { if (_focused) { _focused = false; Invalidate(); } base.OnLostFocus(e); } protected override void OnMouseDown(MouseEventArgs e) { IsSolid = !_solid; Focus(); } protected override void OnPaint(PaintEventArgs e) { Rectangle rc = ClientRectangle; if (_solid) { e.Graphics.FillRectangle(SystemBrushes.ControlDark, rc); e.Graphics.DrawRectangle(SystemPens.WindowFrame, rc.X, rc.Y, rc.Width - 1, rc.Height - 1); } else { ControlPaint.DrawFocusRectangle(e.Graphics, rc); } if (_focused) { rc.Inflate(-2, -2); ControlPaint.DrawFocusRectangle(e.Graphics, rc); } } protected override bool ProcessDialogChar(char charCode) { if (charCode == ' ') { IsSolid = !_solid; return true; } return base.ProcessDialogChar(charCode); } protected override bool ProcessDialogKey(Keys keyData) { if ((keyData & Keys.KeyCode) == Keys.Return && (keyData & (Keys.Alt | Keys.Control)) == 0) { _picker.Teardown(true); return true; } if ((keyData & Keys.KeyCode) == Keys.Escape && (keyData & (Keys.Alt | Keys.Control)) == 0) { _picker.Teardown(false); return true; } if ((keyData & Keys.KeyCode) == Keys.Tab && (keyData & (Keys.Alt | Keys.Control)) == 0) { for (int i = 0; i < _picker._tabOrder.Length; i++) { if (_picker._tabOrder[i] == this) { i += (keyData & Keys.Shift) == 0 ? 1 : -1; i = i < 0 ? i + _picker._tabOrder.Length : i % _picker._tabOrder.Length; _picker._tabOrder[i].Focus(); break; } } return true; } return base.ProcessDialogKey(keyData); } private class SpringControlAccessibleObject : ControlAccessibleObject { public SpringControlAccessibleObject(SpringControl owner) : base(owner) { } public override string DefaultAction => ((SpringControl)Owner!).IsSolid ? SR.AccessibleActionUncheck : SR.AccessibleActionCheck; public override AccessibleStates State { get { AccessibleStates state = base.State; if (((SpringControl)Owner!).IsSolid) { state |= AccessibleStates.Checked; } return state; } } } } } }