using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; namespace DevComponents.DotNetBar.Layout { /// /// Represents layout item which hosts a Windows Forms Control. /// [Designer("DevComponents.DotNetBar.Layout.Design.LayoutControlItemDesigner, DevComponents.DotNetBar.Layout.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=7eb7c3a35b91de04")] public class LayoutControlItem : LayoutItemBase { #region Constructor protected override void OnDispose() { UnhookControlEventHandlers(_Control); base.OnDispose(); } #endregion #region Implementation protected override void OnUpdateLayout() { base.OnUpdateLayout(); if (_Control != null) { Rectangle bounds = Helpers.Deflate(this.Bounds, this.Padding); Rectangle r = bounds; if (this.TextVisible && !string.IsNullOrEmpty(this.Text)) { Rectangle actualTextBounds = this.ActualTextBounds; if (IsImageVisible) actualTextBounds = Rectangle.Union(actualTextBounds, this.ActualImageBounds); if (this.TextPosition == eLayoutPosition.Default || this.TextPosition == eLayoutPosition.Left) { r.X = actualTextBounds.Right + _TextControlSpacing; r.Width = bounds.Right - r.X; } else if (this.TextPosition == eLayoutPosition.Top) { r.Y = actualTextBounds.Bottom + _TextControlSpacing; r.Height = bounds.Bottom - r.Y; } else if (this.TextPosition == eLayoutPosition.Bottom) { r.Height = actualTextBounds.Y - bounds.Y - _TextControlSpacing; } else if (this.TextPosition == eLayoutPosition.Right) { r.Width = actualTextBounds.X - r.X - _TextControlSpacing; } } if (_Control.Margin.Horizontal > 0 || _Control.Margin.Vertical > 0) { r.X += _Control.Margin.Left; r.Width -= _Control.Margin.Horizontal; r.Y += _Control.Margin.Top; r.Height -= _Control.Margin.Vertical; } if (!_ControlSize.IsEmpty && _Control.Dock != DockStyle.Fill && (_ControlSize.Width > 0 && r.Width > _ControlSize.Width) || (_ControlSize.Height > 0 && r.Height > _ControlSize.Height)) { Size controlSize = new Size(_ControlSize.Width > 0 ? Math.Min(r.Width, _ControlSize.Width) : r.Width, _ControlSize.Height > 0 ? Math.Min(r.Height, _ControlSize.Height) : r.Height); if (_Control.Dock != DockStyle.None) { if (_Control.Dock == DockStyle.Left) r = new Rectangle(r.X, r.Y, controlSize.Width, r.Height); else if (_Control.Dock == DockStyle.Right) r = new Rectangle(r.Right - controlSize.Width, r.Y, controlSize.Width, r.Height); else if (_Control.Dock == DockStyle.Top) r = new Rectangle(r.X, r.Y, r.Width, controlSize.Height); else if (_Control.Dock == DockStyle.Bottom) r = new Rectangle(r.X, r.Bottom - controlSize.Height, r.Width, controlSize.Height); } else { if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom)) { // Center into the bounding box r.X += (r.Width - controlSize.Width) / 2; r.Y += (r.Height - controlSize.Height) / 2; r.Size = controlSize; } else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Top)) { r.Size = controlSize; } else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right)) { r.X += (r.Width - controlSize.Width) / 2; r.Size = controlSize; } else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom)) { r.Y += (r.Height - controlSize.Height) / 2; r.Size = controlSize; } else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Bottom)) { r.Y = r.Bottom - controlSize.Height; r.Size = controlSize; } else if (_Control.Anchor == (AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right)) { r.Y = r.Bottom - controlSize.Height; r.X += (r.Width - controlSize.Width) / 2; r.Size = controlSize; } else if (_Control.Anchor == (AnchorStyles.Right | AnchorStyles.Top)) { r.X = r.Right - controlSize.Width; r.Size = controlSize; } else if (_Control.Anchor == (AnchorStyles.Right | AnchorStyles.Bottom)) { r.X = r.Right - controlSize.Width; r.Y = r.Bottom - controlSize.Height; r.Size = controlSize; } else if (_Control.Anchor == (AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Top)) { r.X = r.Right - controlSize.Width; r.Y += (r.Height - controlSize.Height) / 2; r.Size = controlSize; } else r.Size = controlSize; } } _Control.Bounds = r; } } protected override void OnPaintBackground(PaintContext context) { base.OnPaintBackground(context); if (IsKeyboardFocusWithin && context.FocusStyle != null) { DrawingHelpers.PaintStyle(context.Graphics, context.FocusStyle, this.Bounds); } } [EditorBrowsable(EditorBrowsableState.Never)] public override void ScaleItem(SizeF factor) { base.ScaleItem(factor); bool widthChanged = factor.Width != 1f; bool heightChanged = factor.Height != 1f; if (!_ControlSize.IsEmpty && (widthChanged || heightChanged)) { Size newSize = new Size(); if (widthChanged) newSize.Width = (int)(_ControlSize.Width * factor.Width); else newSize.Width = _ControlSize.Width; if (heightChanged) newSize.Height = (int)(_ControlSize.Height * factor.Height); else newSize.Height = _ControlSize.Height; ControlSize = newSize; } } internal override void UpdateScrollBounds(int xScroll, int yScroll, bool moveControls) { base.UpdateScrollBounds(xScroll, yScroll, moveControls); if (moveControls && _Control != null) _Control.Location = new Point(_Control.Location.X + xScroll, _Control.Location.Y + yScroll); } protected override Size OnMeasureText(LayoutContext c) { if (_Control is TextBoxBase && this.TextPosition == eLayoutPosition.Default) { TextBoxBase textBox = (TextBoxBase)_Control; int textBaseLine = Helpers.GetTextBaseline(_Control, ContentAlignment.TopLeft); if (textBox is DevComponents.DotNetBar.Controls.TextBoxX) textBaseLine += 3; else if (textBox.BorderStyle == BorderStyle.FixedSingle || textBox.BorderStyle == BorderStyle.None) textBaseLine += 2; else if (textBox.BorderStyle == BorderStyle.Fixed3D) textBaseLine += 3; _ControlTextBaseline = textBaseLine; } else _ControlTextBaseline = 0; return base.OnMeasureText(c); } internal override int TextBaseline { get { if (_ControlTextBaseline > 0 && _ControlTextBaseline > base.TextBaseline) return _ControlTextBaseline; return base.TextBaseline; } set { base.TextBaseline = value; } } private int _ControlTextBaseline = 0; private Control _Control = null; /// /// Gets or sets the control managed by layout item. /// [DefaultValue(null), Category("Data"), Description("Indicates control managed by layout item.")] public Control Control { get { return _Control; } set { if (value != _Control) { Control oldValue = _Control; _Control = value; OnControlChanged(oldValue, value); } } } private void UnhookControlEventHandlers(Control control) { if (control == null) return; control.Enter -= ControlEnter; control.Leave -= ControlLeave; control.MouseHover -= ControlMouseHover; control.MouseDown -= ControlMouseDown; control.MouseMove -= ControlMouseMove; control.MouseLeave -= ControlMouseLeave; } /// /// Called when Control property has changed. /// /// Old property value /// New property value protected virtual void OnControlChanged(Control oldValue, Control newValue) { if (oldValue != null) { UnhookControlEventHandlers(oldValue); } OnPropertyChanged(new PropertyChangedEventArgs("Control")); if (_Control != null) { _Control.Enter += ControlEnter; _Control.Leave += ControlLeave; _Control.MouseHover += ControlMouseHover; _Control.MouseDown += ControlMouseDown; _Control.MouseMove += ControlMouseMove; _Control.MouseLeave += ControlMouseLeave; if (_Control.Visible != this.Visible) _Control.Visible = this.Visible; } InvalidateLayout(); } private Point _MouseTooltipLocation = Point.Empty; void ControlMouseLeave(object sender, EventArgs e) { _MouseTooltipLocation = Point.Empty; if (ToolTipVisible) HideToolTip(); } void ControlMouseMove(object sender, MouseEventArgs e) { if (!_MouseTooltipLocation.IsEmpty && ToolTipVisible && (Math.Abs(_MouseTooltipLocation.X - e.X) > 1 || Math.Abs(_MouseTooltipLocation.Y - e.Y) > 1)) HideToolTip(); } void ControlMouseDown(object sender, MouseEventArgs e) { if (ToolTipVisible) HideToolTip(); } void ControlMouseHover(object sender, EventArgs e) { if (_EnableControlTooltip) { ShowToolTip(); _MouseTooltipLocation = _Control.PointToClient(Control.MousePosition); } } private void ControlLeave(object sender, EventArgs e) { IsKeyboardFocusWithin = false; } private void ControlEnter(object sender, EventArgs e) { IsKeyboardFocusWithin = true; } private bool _EnableControlTooltip = true; /// /// Indicates whether Tooltip for the item is shown when mouse is over the control. /// [DefaultValue(true), Category("Behavior"), Description("Indicates whether Tooltip for the item is shown when mouse is over the control.")] public bool EnableControlTooltip { get { return _EnableControlTooltip; } set { if (value != _EnableControlTooltip) { bool oldValue = _EnableControlTooltip; _EnableControlTooltip = value; OnEnableControlTooltipChanged(oldValue, value); } } } /// /// Called when EnableControlTooltip property has changed. /// /// Old property value /// New property value protected virtual void OnEnableControlTooltipChanged(bool oldValue, bool newValue) { OnPropertyChanged(new PropertyChangedEventArgs("EnableControlTooltip")); } private int _TextControlSpacing = 3; /// /// Indicates spacing between text and the control. /// [DefaultValue(3), Category("Appearance"), Description("Indicates spacing between text and the control."), RefreshProperties(RefreshProperties.All)] public int TextControlSpacing { get { return _TextControlSpacing; } set { if (value != _TextControlSpacing) { int oldValue = _TextControlSpacing; _TextControlSpacing = value; OnTextControlSpacingChanged(oldValue, value); } } } /// /// Called when TextControlSpacing property has changed. /// /// Old property value /// New property value protected virtual void OnTextControlSpacingChanged(int oldValue, int newValue) { OnPropertyChanged(new PropertyChangedEventArgs("TextControlSpacing")); InvalidateLayout(); } /// /// Processes accelerator key for the item. /// /// internal override bool ProcessMnemonic(char charCode) { if (MnemonicsEnabled && _Control != null && _Control.CanSelect) { _Control.Select(); return true; } return false; } private Size _ControlSize = Size.Empty; /// /// Indicates suggested control size which is used only if calculated layout size for the control exceeds the size specified here. Either width or height may be set or both. /// ControlSize property can be used in conjuction with Dock and Anchor properties on the Control. When available space for the Control /// exceeds ControlSize the Dock and Anchor properties will indicate the control position inside of the control box. /// [Category("Appearance"), Description("Indicates suggested control size which is used only if calculated layout size for the control exceeds the size specified here. Either width or height may be set or both.")] public Size ControlSize { get { return _ControlSize; } set { if (value != _ControlSize) { Size oldValue = _ControlSize; _ControlSize = value; OnControlSizeChanged(oldValue, value); } } } /// /// Called when ControlSize property has changed. /// /// Old property value /// New property value protected virtual void OnControlSizeChanged(Size oldValue, Size newValue) { OnPropertyChanged(new PropertyChangedEventArgs("ControlSize")); InvalidateLayout(); } [EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeControlSize() { return !_ControlSize.IsEmpty; } [EditorBrowsable(EditorBrowsableState.Never)] public void ResetControlSize() { ControlSize = Size.Empty; } private bool _AutoSetTabIndex = true; /// /// Indicates whether Control TabIndex is automatically set based on the position of the item inside of the layout. /// [DefaultValue(true), Category("Behavior"), Description("Indicates whether Control TabIndex is automatically set based on the position of the item inside of the layout.")] public bool AutoSetTabIndex { get { return _AutoSetTabIndex; } set { if (value != _AutoSetTabIndex) { bool oldValue = _AutoSetTabIndex; _AutoSetTabIndex = value; OnAutoSetTabIndexChanged(oldValue, value); } } } /// /// Called when AutoSetTabIndex property has changed. /// /// Old property value /// New property value protected virtual void OnAutoSetTabIndexChanged(bool oldValue, bool newValue) { OnPropertyChanged(new PropertyChangedEventArgs("AutoSetTabIndex")); } protected override void OnAbsoluteIndexChanged(int oldValue, int newValue) { if (_Control != null && _AutoSetTabIndex) _Control.TabIndex = newValue; base.OnAbsoluteIndexChanged(oldValue, newValue); } private bool _FocusVisualStyleEnabled = true; /// /// Indicates whether LayoutControl.FocusStyle is used to paint background of item when control has input focus. /// [DefaultValue(true), Category("Behavior"), Description("Indicates whether LayoutControl.FocusStyle is used to paint background of item when control has input focus.")] public bool FocusVisualStyleEnabled { get { return _FocusVisualStyleEnabled; } set { if (_FocusVisualStyleEnabled == value) return; _FocusVisualStyleEnabled = value; if (this.IsKeyboardFocusWithin) this.Invalidate(); OnPropertyChanged(new PropertyChangedEventArgs("FocusVisualStyleEnabled")); } } protected override void OnVisibleChanged(bool oldValue, bool newValue) { if (_Control != null) _Control.Visible = newValue; base.OnVisibleChanged(oldValue, newValue); } #endregion } }